@hkyhy/marsun-components-core 0.1.101 → 0.1.113
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/dist/components/Editor/VariablePicker.js +13 -13
- package/dist/components/Editor/VariablePicker.js.map +1 -1
- package/dist/components/Filter/createKneFilterField.js +42 -39
- package/dist/components/Filter/createKneFilterField.js.map +1 -1
- package/dist/components/Form/SuperSelect.js +48 -45
- package/dist/components/Form/SuperSelect.js.map +1 -1
- package/dist/components/FormInfo/RichTextField/index.js +46 -69
- package/dist/components/FormInfo/RichTextField/index.js.map +1 -1
- package/dist/components/FormInfo/VariableMentionInput/index.d.ts +1 -0
- package/dist/components/FormInfo/VariableMentionInput/index.js +53 -47
- package/dist/components/FormInfo/VariableMentionInput/index.js.map +1 -1
- package/dist/components/FormInfo/VariableMentionInput/style.module.scss.js +6 -5
- package/dist/components/FormInfo/VariableMentionInput/style.module.scss.js.map +1 -1
- package/dist/components/ReactFilter/fields/index.js +33 -26
- package/dist/components/ReactFilter/fields/index.js.map +1 -1
- package/dist/components/ReactFilter/renderSelectListItemContent.d.ts +8 -0
- package/dist/components/ReactFilter/renderSelectListItemContent.js +12 -0
- package/dist/components/ReactFilter/renderSelectListItemContent.js.map +1 -0
- package/dist/components/Tools/Inbox/InboxBell/InboxBell.d.ts +3 -0
- package/dist/components/Tools/Inbox/InboxBell/InboxBell.js +59 -49
- package/dist/components/Tools/Inbox/InboxBell/InboxBell.js.map +1 -1
- package/dist/components/Tools/Inbox/InboxBell/style.module.scss.js +20 -18
- package/dist/components/Tools/Inbox/InboxBell/style.module.scss.js.map +1 -1
- package/dist/components/Tools/Inbox/index.d.ts +1 -0
- package/dist/components/Tools/Inbox/sanitizeInboxHtml.d.ts +5 -0
- package/dist/components/Tools/Inbox/sanitizeInboxHtml.js +14 -0
- package/dist/components/Tools/Inbox/sanitizeInboxHtml.js.map +1 -0
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/MessageTemplateAdmin.d.ts +1 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/MessageTemplateAdmin.js +158 -137
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/MessageTemplateAdmin.js.map +1 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/Modal/TemplateFormModal.js +217 -124
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/Modal/TemplateFormModal.js.map +1 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/PushRulesPanel/index.d.ts +8 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/PushRulesPanel/index.js +312 -170
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/PushRulesPanel/index.js.map +1 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/VariablesPanel/index.js +87 -76
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/VariablesPanel/index.js.map +1 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/audienceSlots.d.ts +14 -0
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/audienceSlots.js +31 -0
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/audienceSlots.js.map +1 -0
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/index.d.ts +3 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/style.module.scss.js +18 -6
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/style.module.scss.js.map +1 -1
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/types.d.ts +27 -0
- package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/types.js.map +1 -1
- package/dist/components/Tools/MessageCenter/MsgCenterAppSwitcher/MsgCenterAppSwitcher.d.ts +22 -0
- package/dist/components/Tools/MessageCenter/MsgCenterAppSwitcher/MsgCenterAppSwitcher.js +64 -0
- package/dist/components/Tools/MessageCenter/MsgCenterAppSwitcher/MsgCenterAppSwitcher.js.map +1 -0
- package/dist/components/Tools/MessageCenter/MsgCenterAppSwitcher/index.d.ts +2 -0
- package/dist/components/Tools/MessageCenter/index.d.ts +8 -1
- package/dist/components/Tools/MessageCenter/msgCenterAppSwitch.d.ts +39 -0
- package/dist/components/Tools/MessageCenter/msgCenterAppSwitch.js +94 -0
- package/dist/components/Tools/MessageCenter/msgCenterAppSwitch.js.map +1 -0
- package/dist/components/Tools/MessageCenter/useMsgCenterAppKey.d.ts +2 -0
- package/dist/components/Tools/MessageCenter/useMsgCenterAppKey.js +18 -0
- package/dist/components/Tools/MessageCenter/useMsgCenterAppKey.js.map +1 -0
- package/dist/components/Tools/MessageCenter/utils/audienceUserSelectOptions.d.ts +16 -0
- package/dist/components/Tools/MessageCenter/utils/audienceUserSelectOptions.js +33 -0
- package/dist/components/Tools/MessageCenter/utils/audienceUserSelectOptions.js.map +1 -0
- package/dist/components/Tools/MessageCenter/utils/templateCode.js +11 -17
- package/dist/components/Tools/MessageCenter/utils/templateCode.js.map +1 -1
- package/dist/components/Tools/index.d.ts +3 -2
- package/dist/index.js +641 -626
- package/dist/index.js.map +1 -1
- package/dist/marsun-components-core.css +1 -1
- package/dist/node_modules/dompurify/dist/purify.es.js +908 -0
- package/dist/node_modules/dompurify/dist/purify.es.js.map +1 -0
- package/dist/node_modules/isomorphic-dompurify/dist/browser.js +17 -0
- package/dist/node_modules/isomorphic-dompurify/dist/browser.js.map +1 -0
- package/dist/styles/global.css +1 -1
- package/package.json +9 -1
|
@@ -1,190 +1,283 @@
|
|
|
1
|
-
import { jsx as
|
|
2
|
-
import { RichTextField as
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
1
|
+
import { jsx as s, jsxs as y } from "react/jsx-runtime";
|
|
2
|
+
import { RichTextField as Q } from "../../../../FormInfo/RichTextField/index.js";
|
|
3
|
+
import { sanitizeInboxHtml as V } from "../../../Inbox/sanitizeInboxHtml.js";
|
|
4
|
+
import { normalizeTemplatePlaceholders as v, applyTemplateVars as D } from "../../utils/templateCode.js";
|
|
5
|
+
import { Typography as k, message as b, Modal as q, Collapse as G } from "antd";
|
|
6
|
+
import { useState as H, useEffect as U, useMemo as I, useCallback as i } from "react";
|
|
7
|
+
import { AUDIENCE_SLOT_OPTIONS as J, normalizeAudienceSlots as X, hasAudienceSelection as Y, ORG_TENANT_SLOT as Z } from "../audienceSlots.js";
|
|
8
|
+
import t from "../style.module.scss.js";
|
|
9
|
+
import { Input as A, Select as C } from "../../../../FormInfo/fields.js";
|
|
10
|
+
import W from "../../../../FormInfo/FormModal.js";
|
|
11
|
+
import ee from "../../../../FormInfo/FormInfo.js";
|
|
12
|
+
import oe from "../../../../FormInfo/FormItem.js";
|
|
13
|
+
const K = {
|
|
14
|
+
getPopupContainer: () => document.body,
|
|
15
|
+
styles: { popup: { root: { zIndex: 2e3 } } }
|
|
16
|
+
}, ye = ({
|
|
17
|
+
open: w,
|
|
18
|
+
isCreate: n,
|
|
14
19
|
initial: e,
|
|
15
|
-
catalog:
|
|
16
|
-
roleOptions:
|
|
17
|
-
variables:
|
|
20
|
+
catalog: p,
|
|
21
|
+
roleOptions: S,
|
|
22
|
+
variables: T,
|
|
18
23
|
catalogError: u,
|
|
19
|
-
previewVars:
|
|
20
|
-
canWrite:
|
|
21
|
-
onCancel:
|
|
22
|
-
onSubmit:
|
|
23
|
-
renderAudienceField:
|
|
24
|
+
previewVars: F,
|
|
25
|
+
canWrite: r,
|
|
26
|
+
onCancel: R,
|
|
27
|
+
onSubmit: M,
|
|
28
|
+
renderAudienceField: a
|
|
24
29
|
}) => {
|
|
25
|
-
const [
|
|
26
|
-
|
|
27
|
-
if (!
|
|
28
|
-
|
|
30
|
+
const [x, E] = H([]), [N, h] = H(!1);
|
|
31
|
+
U(() => {
|
|
32
|
+
if (!w || !e) {
|
|
33
|
+
h(!1);
|
|
29
34
|
return;
|
|
30
35
|
}
|
|
31
|
-
|
|
32
|
-
const o = window.requestAnimationFrame(() =>
|
|
36
|
+
E(e.audienceRoles || e.roles || []);
|
|
37
|
+
const o = window.requestAnimationFrame(() => h(!0));
|
|
33
38
|
return () => window.cancelAnimationFrame(o);
|
|
34
|
-
}, [
|
|
35
|
-
const
|
|
39
|
+
}, [w, e]);
|
|
40
|
+
const _ = (e == null ? void 0 : e.id) || (e == null ? void 0 : e.code) || (n ? "create" : "edit"), P = I(() => e ? {
|
|
36
41
|
code: e.code,
|
|
37
42
|
eventKey: e.eventKey,
|
|
38
43
|
scenario: e.scenario || e.label || "",
|
|
39
|
-
titleTemplate:
|
|
44
|
+
titleTemplate: v(
|
|
40
45
|
e.titleTemplate || e.titlePreview || ""
|
|
41
46
|
),
|
|
42
|
-
bodyTemplate:
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
}, []),
|
|
46
|
-
|
|
47
|
+
bodyTemplate: v(e.bodyTemplate || ""),
|
|
48
|
+
audienceRoles: e.audienceRoles || e.roles || [],
|
|
49
|
+
audienceSlots: e.audienceSlots || []
|
|
50
|
+
} : {}, [e]), z = u ? `目录加载失败,无法插入变量(${u})` : T.length === 0 ? "暂无 catalog 变量" : "", B = i((o) => {
|
|
51
|
+
h(!!o);
|
|
52
|
+
}, []), $ = I(() => {
|
|
53
|
+
if (!N)
|
|
47
54
|
return [
|
|
48
|
-
/* @__PURE__ */
|
|
55
|
+
/* @__PURE__ */ s(k.Text, { type: "secondary", children: "加载编辑器…" }, "loading")
|
|
49
56
|
];
|
|
50
57
|
const o = [];
|
|
51
|
-
return
|
|
52
|
-
/* @__PURE__ */
|
|
53
|
-
|
|
58
|
+
return n || o.push(/* @__PURE__ */ s(A, { name: "code", label: "编号", disabled: !0 }, "code")), o.push(
|
|
59
|
+
/* @__PURE__ */ s(
|
|
60
|
+
C,
|
|
54
61
|
{
|
|
55
62
|
name: "eventKey",
|
|
56
|
-
label: "
|
|
63
|
+
label: "适用场景",
|
|
57
64
|
rule: "REQ",
|
|
58
|
-
disabled: !
|
|
65
|
+
disabled: !r,
|
|
59
66
|
optionLabelProp: "label",
|
|
60
|
-
options:
|
|
61
|
-
value:
|
|
62
|
-
label:
|
|
63
|
-
}))
|
|
67
|
+
options: p.map((l) => ({
|
|
68
|
+
value: l.eventKey,
|
|
69
|
+
label: l.label || l.eventKey
|
|
70
|
+
})),
|
|
71
|
+
placeholder: p.length ? "选择场景" : "暂无事件目录",
|
|
72
|
+
...K
|
|
64
73
|
},
|
|
65
74
|
"eventKey"
|
|
66
75
|
),
|
|
67
|
-
/* @__PURE__ */
|
|
68
|
-
|
|
69
|
-
K,
|
|
76
|
+
/* @__PURE__ */ s(
|
|
77
|
+
A,
|
|
70
78
|
{
|
|
71
79
|
name: "titleTemplate",
|
|
72
80
|
label: "标题模板",
|
|
73
|
-
|
|
81
|
+
rule: "REQ",
|
|
82
|
+
disabled: !r,
|
|
74
83
|
enableVariableMention: !0,
|
|
75
|
-
variables:
|
|
84
|
+
variables: T,
|
|
76
85
|
catalogError: u,
|
|
77
86
|
placeholder: "点「插入变量」选择 catalog 变量",
|
|
78
|
-
labelTips:
|
|
87
|
+
labelTips: n ? "新建默认停用。标题:点「插入变量」插入明文 {{key}}(可手改)。正文:原子色块,不可改字,整颗删除。" : "标题可手改 {{key}};正文为原子色块(不可改字、Backspace 整颗删)。"
|
|
79
88
|
},
|
|
80
89
|
"titleTemplate"
|
|
81
90
|
),
|
|
82
|
-
/* @__PURE__ */
|
|
83
|
-
|
|
91
|
+
/* @__PURE__ */ s(
|
|
92
|
+
Q,
|
|
84
93
|
{
|
|
85
94
|
name: "bodyTemplate",
|
|
86
95
|
label: "正文模板",
|
|
87
|
-
disabled: !
|
|
96
|
+
disabled: !r,
|
|
88
97
|
enableVariableMention: !0,
|
|
89
|
-
variables:
|
|
98
|
+
variables: T,
|
|
90
99
|
catalogError: u,
|
|
91
|
-
editorKey:
|
|
100
|
+
editorKey: _,
|
|
92
101
|
placeholder: "编辑正文,点「插入变量」",
|
|
93
102
|
minHeight: 160
|
|
94
103
|
},
|
|
95
104
|
"bodyTemplate"
|
|
96
105
|
)
|
|
106
|
+
), a || o.push(
|
|
107
|
+
/* @__PURE__ */ s(
|
|
108
|
+
C,
|
|
109
|
+
{
|
|
110
|
+
name: "audienceRoles",
|
|
111
|
+
label: "受众角色",
|
|
112
|
+
mode: "multiple",
|
|
113
|
+
allowClear: !0,
|
|
114
|
+
disabled: !r,
|
|
115
|
+
options: S.map((l) => ({
|
|
116
|
+
value: l.code,
|
|
117
|
+
label: l.name || l.code
|
|
118
|
+
})),
|
|
119
|
+
optionFilterProp: "label",
|
|
120
|
+
maxTagCount: "responsive",
|
|
121
|
+
placeholder: S.length ? "下拉选择角色(可多选)" : "暂无角色数据",
|
|
122
|
+
notFoundContent: "暂无角色",
|
|
123
|
+
labelTips: "可与「通知范围」并存;至少选角色或槽位之一。emit 与显式 userIds 并集送达。",
|
|
124
|
+
...K
|
|
125
|
+
},
|
|
126
|
+
"audienceRoles"
|
|
127
|
+
),
|
|
128
|
+
/* @__PURE__ */ s(
|
|
129
|
+
C,
|
|
130
|
+
{
|
|
131
|
+
name: "audienceSlots",
|
|
132
|
+
label: "通知范围",
|
|
133
|
+
mode: "multiple",
|
|
134
|
+
allowClear: !0,
|
|
135
|
+
disabled: !r,
|
|
136
|
+
options: J.map((l) => ({
|
|
137
|
+
value: l.value,
|
|
138
|
+
label: l.label
|
|
139
|
+
})),
|
|
140
|
+
optionFilterProp: "label",
|
|
141
|
+
maxTagCount: "responsive",
|
|
142
|
+
placeholder: "可选:本人/领导/部门/分厂/租户或任务当事人",
|
|
143
|
+
notFoundContent: "暂无槽位",
|
|
144
|
+
labelTips: "依赖业务 emit.audienceContext;无上下文的槽不会发出。选「本租户」保存前会确认。",
|
|
145
|
+
...K
|
|
146
|
+
},
|
|
147
|
+
"audienceSlots"
|
|
148
|
+
)
|
|
97
149
|
), o;
|
|
98
|
-
}, [
|
|
150
|
+
}, [
|
|
151
|
+
N,
|
|
152
|
+
n,
|
|
153
|
+
r,
|
|
154
|
+
p,
|
|
155
|
+
T,
|
|
156
|
+
_,
|
|
157
|
+
u,
|
|
158
|
+
a,
|
|
159
|
+
S
|
|
160
|
+
]), j = I(
|
|
99
161
|
() => ({
|
|
100
|
-
data:
|
|
162
|
+
data: P,
|
|
101
163
|
onSubmit: async (o) => {
|
|
164
|
+
if (!r)
|
|
165
|
+
return b.warning("当前为只读(业务未授予写权限)"), !1;
|
|
166
|
+
const l = String(o.eventKey || "").trim();
|
|
102
167
|
if (!l)
|
|
103
|
-
return
|
|
104
|
-
const
|
|
105
|
-
if (!
|
|
106
|
-
return
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
168
|
+
return b.warning("请选择适用场景"), !1;
|
|
169
|
+
const g = v(String(o.titleTemplate || ""));
|
|
170
|
+
if (!g.trim())
|
|
171
|
+
return b.warning("请填写标题模板"), !1;
|
|
172
|
+
const f = a ? x : Array.isArray(o.audienceRoles) ? o.audienceRoles : [], m = X(o.audienceSlots || []);
|
|
173
|
+
if (!Y({
|
|
174
|
+
roles: f,
|
|
175
|
+
slots: m,
|
|
176
|
+
userIds: null
|
|
177
|
+
}))
|
|
178
|
+
return b.warning("请选择受众角色或通知范围(至少一个)"), !1;
|
|
179
|
+
if (m.includes(Z) && !await new Promise((O) => {
|
|
180
|
+
q.confirm({
|
|
181
|
+
title: "确认通知本租户全员?",
|
|
182
|
+
content: "已选「本租户(全公司)」:将向当前租户内用户展开(≠跨租户)。确认保存?",
|
|
183
|
+
okText: "确认保存",
|
|
184
|
+
cancelText: "取消",
|
|
185
|
+
onOk: () => O(!0),
|
|
186
|
+
onCancel: () => O(!1)
|
|
187
|
+
});
|
|
188
|
+
}))
|
|
189
|
+
return !1;
|
|
190
|
+
const d = p.find((c) => c.eventKey === l), L = String((d == null ? void 0 : d.label) || o.scenario || l).trim();
|
|
110
191
|
try {
|
|
111
|
-
await
|
|
192
|
+
await M({
|
|
112
193
|
...e || {},
|
|
113
194
|
code: o.code || (e == null ? void 0 : e.code),
|
|
114
|
-
eventKey:
|
|
115
|
-
scenario:
|
|
116
|
-
label:
|
|
117
|
-
messageType: (
|
|
118
|
-
titleTemplate:
|
|
119
|
-
bodyTemplate:
|
|
120
|
-
audienceRoles:
|
|
121
|
-
roles:
|
|
122
|
-
|
|
195
|
+
eventKey: l,
|
|
196
|
+
scenario: L,
|
|
197
|
+
label: L,
|
|
198
|
+
messageType: (d == null ? void 0 : d.messageType) || (e == null ? void 0 : e.messageType) || "alert",
|
|
199
|
+
titleTemplate: g,
|
|
200
|
+
bodyTemplate: v(String(o.bodyTemplate || "")),
|
|
201
|
+
audienceRoles: f,
|
|
202
|
+
roles: f,
|
|
203
|
+
audienceSlots: m,
|
|
204
|
+
enabled: n ? !1 : (e == null ? void 0 : e.enabled) !== !1,
|
|
123
205
|
channel: (e == null ? void 0 : e.channel) || "in_app"
|
|
124
|
-
}),
|
|
125
|
-
} catch (
|
|
126
|
-
return
|
|
206
|
+
}), R();
|
|
207
|
+
} catch (c) {
|
|
208
|
+
return b.error(c instanceof Error ? c.message : String(c)), !1;
|
|
127
209
|
}
|
|
128
210
|
}
|
|
129
211
|
}),
|
|
130
|
-
[
|
|
212
|
+
[
|
|
213
|
+
P,
|
|
214
|
+
r,
|
|
215
|
+
p,
|
|
216
|
+
M,
|
|
217
|
+
e,
|
|
218
|
+
x,
|
|
219
|
+
n,
|
|
220
|
+
R,
|
|
221
|
+
a
|
|
222
|
+
]
|
|
131
223
|
);
|
|
132
|
-
return /* @__PURE__ */
|
|
133
|
-
|
|
224
|
+
return /* @__PURE__ */ y(
|
|
225
|
+
W,
|
|
134
226
|
{
|
|
135
|
-
title:
|
|
136
|
-
open:
|
|
137
|
-
onCancel:
|
|
227
|
+
title: n ? "新建模板" : "编辑模板",
|
|
228
|
+
open: w,
|
|
229
|
+
onCancel: R,
|
|
138
230
|
width: 720,
|
|
231
|
+
size: "small",
|
|
232
|
+
className: "msg-center-form-modal",
|
|
139
233
|
okText: "保存",
|
|
140
234
|
autoClose: !1,
|
|
141
235
|
focusable: { trap: !1 },
|
|
142
|
-
afterOpenChange:
|
|
143
|
-
formProps:
|
|
236
|
+
afterOpenChange: B,
|
|
237
|
+
formProps: j,
|
|
144
238
|
children: [
|
|
145
|
-
/* @__PURE__ */
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
/* @__PURE__ */
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
239
|
+
/* @__PURE__ */ s(ee, { column: 1, list: $ }),
|
|
240
|
+
a ? /* @__PURE__ */ y("div", { className: t.audienceBlock, children: [
|
|
241
|
+
/* @__PURE__ */ y(k.Text, { className: t.audienceLabel, children: [
|
|
242
|
+
/* @__PURE__ */ s("span", { style: { color: "#ff4d4f", marginRight: 4 }, children: "*" }),
|
|
243
|
+
"受众角色"
|
|
244
|
+
] }),
|
|
245
|
+
a({ roles: x, onChange: E })
|
|
246
|
+
] }) : null,
|
|
247
|
+
N ? /* @__PURE__ */ s(oe, { children: (o) => {
|
|
248
|
+
const l = (typeof o.getFormData == "function" ? o.getFormData() : void 0) ?? o.formData ?? P, g = D(String(l.titleTemplate || ""), F), f = D(String(l.bodyTemplate || ""), F), m = V(f);
|
|
249
|
+
return /* @__PURE__ */ y("div", { className: t.previewCollapse, children: [
|
|
250
|
+
z ? /* @__PURE__ */ s(k.Text, { type: "secondary", children: z }) : null,
|
|
251
|
+
/* @__PURE__ */ s(
|
|
252
|
+
G,
|
|
253
|
+
{
|
|
254
|
+
ghost: !0,
|
|
255
|
+
size: "small",
|
|
256
|
+
items: [
|
|
257
|
+
{
|
|
258
|
+
key: "preview",
|
|
259
|
+
label: "效果预览",
|
|
260
|
+
children: /* @__PURE__ */ y("div", { className: t.previewCard, children: [
|
|
261
|
+
/* @__PURE__ */ s("div", { className: t.previewTitle, children: g.trim() || /* @__PURE__ */ s("span", { className: t.previewEmpty, children: "(无标题)" }) }),
|
|
262
|
+
m ? /* @__PURE__ */ s(
|
|
263
|
+
"div",
|
|
264
|
+
{
|
|
265
|
+
className: t.previewBody,
|
|
266
|
+
dangerouslySetInnerHTML: { __html: m }
|
|
267
|
+
}
|
|
268
|
+
) : /* @__PURE__ */ s("div", { className: `${t.previewBody} ${t.previewEmpty}`, children: "(无正文)" })
|
|
269
|
+
] })
|
|
270
|
+
}
|
|
271
|
+
]
|
|
272
|
+
}
|
|
273
|
+
)
|
|
161
274
|
] });
|
|
162
|
-
} }) : null
|
|
163
|
-
/* @__PURE__ */ p("div", { style: { marginTop: 12 }, children: [
|
|
164
|
-
/* @__PURE__ */ r(c.Text, { children: "受众角色" }),
|
|
165
|
-
M ? M({ roles: m, onChange: w }) : /* @__PURE__ */ r(
|
|
166
|
-
q,
|
|
167
|
-
{
|
|
168
|
-
mode: "multiple",
|
|
169
|
-
style: { width: "100%", marginTop: 8 },
|
|
170
|
-
value: m,
|
|
171
|
-
disabled: !l,
|
|
172
|
-
placeholder: P.length ? "选择角色" : "暂无角色数据",
|
|
173
|
-
options: P.map((o) => ({
|
|
174
|
-
value: o.code,
|
|
175
|
-
label: o.name || o.code
|
|
176
|
-
})),
|
|
177
|
-
optionFilterProp: "label",
|
|
178
|
-
onChange: (o) => w(o || []),
|
|
179
|
-
notFoundContent: "暂无角色"
|
|
180
|
-
}
|
|
181
|
-
)
|
|
182
|
-
] })
|
|
275
|
+
} }) : null
|
|
183
276
|
]
|
|
184
277
|
}
|
|
185
278
|
);
|
|
186
279
|
};
|
|
187
280
|
export {
|
|
188
|
-
|
|
281
|
+
ye as TemplateFormModal
|
|
189
282
|
};
|
|
190
283
|
//# sourceMappingURL=TemplateFormModal.js.map
|
package/dist/components/Tools/MessageCenter/MessageTemplateAdmin/Modal/TemplateFormModal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TemplateFormModal.js","sources":["../../../../../../src/components/Tools/MessageCenter/MessageTemplateAdmin/Modal/TemplateFormModal.tsx"],"sourcesContent":["import { FormInfo, FormItem, FormModal, Input, Select } from '@/components/FormInfo';\nimport { RichTextField } from '@/components/FormInfo/RichTextField';\nimport {\n applyTemplateVars,\n normalizeTemplatePlaceholders,\n stripHtmlToText,\n} from '../../utils/templateCode';\nimport { Select as AntSelect, Typography, message } from 'antd';\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport type {\n MessageAudienceRoleOption,\n MessageEventCatalogItem,\n MessageTemplateAdminItem,\n MessageTemplateVariable,\n} from '../types';\nimport styles from '../style.module.scss';\n\nexport type TemplateFormModalProps = {\n open: boolean;\n isCreate: boolean;\n initial: MessageTemplateAdminItem | null;\n catalog: MessageEventCatalogItem[];\n roleOptions: MessageAudienceRoleOption[];\n variables: MessageTemplateVariable[];\n /** catalog 请求失败时的短文案(与「变量为空」区分) */\n catalogError?: string;\n previewVars: Record<string, string>;\n canWrite: boolean;\n onCancel: () => void;\n onSubmit: (item: MessageTemplateAdminItem) => Promise<void>;\n renderAudienceField?: (ctx: {\n roles: string[];\n onChange: (roles: string[]) => void;\n }) => React.ReactNode;\n};\n\ntype FormShape = {\n code?: string;\n eventKey?: string;\n scenario?: string;\n titleTemplate?: string;\n bodyTemplate?: string;\n};\n\ntype FormApiLike = {\n formData?: FormShape;\n getFormData?: () => FormShape;\n};\n\n/**\n * 模板新建/编辑:FormModal + FormInfo;正文 RichTextField。\n * CKEditor 在 open 后微任务挂载,避免与 Modal focus/动画互抢;禁 mention uplift 死循环。\n */\nexport const TemplateFormModal: React.FC<TemplateFormModalProps> = ({\n open,\n isCreate,\n initial,\n catalog,\n roleOptions,\n variables,\n catalogError,\n previewVars,\n canWrite,\n onCancel,\n onSubmit,\n renderAudienceField,\n}) => {\n const [roles, setRoles] = useState<string[]>([]);\n const [editorReady, setEditorReady] = useState(false);\n\n useEffect(() => {\n if (!open || !initial) {\n setEditorReady(false);\n return;\n }\n setRoles(initial.audienceRoles || initial.roles || []);\n // 打开后再挂编辑器(afterOpenChange 兜底 + rAF)\n const id = window.requestAnimationFrame(() => setEditorReady(true));\n return () => window.cancelAnimationFrame(id);\n }, [open, initial]);\n\n const editorKey = initial?.id || initial?.code || (isCreate ? 'create' : 'edit');\n\n const formData = useMemo<FormShape>(() => {\n if (!initial) return {};\n return {\n code: initial.code,\n eventKey: initial.eventKey,\n scenario: initial.scenario || initial.label || '',\n titleTemplate: normalizeTemplatePlaceholders(\n initial.titleTemplate || initial.titlePreview || '',\n ),\n bodyTemplate: normalizeTemplatePlaceholders(initial.bodyTemplate || ''),\n };\n }, [initial]);\n\n const varsEmptyHint = catalogError\n ? `目录加载失败,无法插入变量(${catalogError})`\n : variables.length === 0\n ? '暂无 catalog 变量'\n : '';\n\n const handleAfterOpenChange = useCallback((nextOpen: boolean) => {\n if (nextOpen) setEditorReady(true);\n else setEditorReady(false);\n }, []);\n\n const fieldList = useMemo(() => {\n if (!editorReady) {\n return [\n <Typography.Text key=\"loading\" type=\"secondary\">\n 加载编辑器…\n </Typography.Text>,\n ];\n }\n const fields: React.ReactNode[] = [];\n if (!isCreate) {\n fields.push(<Input key=\"code\" name=\"code\" label=\"编号\" disabled />);\n }\n fields.push(\n <Select\n key=\"eventKey\"\n name=\"eventKey\"\n label=\"事件\"\n rule=\"REQ\"\n disabled={!canWrite}\n optionLabelProp=\"label\"\n options={catalog.map((c) => ({\n value: c.eventKey,\n label: c.label,\n }))}\n />,\n <Input key=\"scenario\" name=\"scenario\" label=\"适用场景\" rule=\"REQ\" disabled={!canWrite} />,\n <Input\n key=\"titleTemplate\"\n name=\"titleTemplate\"\n label=\"标题模板\"\n disabled={!canWrite}\n enableVariableMention\n variables={variables}\n catalogError={catalogError}\n placeholder=\"点「插入变量」选择 catalog 变量\"\n labelTips={\n isCreate\n ? '新建默认停用。标题:点「插入变量」插入明文 {{key}}(可手改)。正文:原子色块,不可改字,整颗删除。'\n : '标题可手改 {{key}};正文为原子色块(不可改字、Backspace 整颗删)。'\n }\n />,\n <RichTextField\n key=\"bodyTemplate\"\n name=\"bodyTemplate\"\n label=\"正文模板\"\n disabled={!canWrite}\n enableVariableMention\n variables={variables}\n catalogError={catalogError}\n editorKey={editorKey}\n placeholder=\"编辑正文,点「插入变量」\"\n minHeight={160}\n />,\n );\n return fields;\n }, [editorReady, isCreate, canWrite, catalog, variables, editorKey]);\n\n const formProps = useMemo(\n () => ({\n data: formData,\n onSubmit: async (data: FormShape) => {\n if (!canWrite) {\n message.warning('当前为只读(业务未授予写权限)');\n return false;\n }\n const scenario = String(data.scenario || '').trim();\n const eventKey = String(data.eventKey || '').trim();\n if (!scenario) {\n message.warning('请填写适用场景');\n return false;\n }\n if (!eventKey) {\n message.warning('请选择事件');\n return false;\n }\n const hit = catalog.find((c) => c.eventKey === eventKey);\n try {\n await onSubmit({\n ...(initial || {}),\n code: data.code || initial?.code,\n eventKey,\n scenario,\n label: scenario,\n messageType: hit?.messageType || initial?.messageType || 'alert',\n titleTemplate: normalizeTemplatePlaceholders(String(data.titleTemplate || '')),\n bodyTemplate: normalizeTemplatePlaceholders(String(data.bodyTemplate || '')),\n audienceRoles: roles,\n roles,\n enabled: isCreate ? false : initial?.enabled !== false,\n channel: initial?.channel || 'in_app',\n });\n onCancel();\n } catch (e) {\n message.error(e instanceof Error ? e.message : String(e));\n return false;\n }\n },\n }),\n [formData, canWrite, catalog, onSubmit, initial, roles, isCreate, onCancel],\n );\n\n return (\n <FormModal\n title={isCreate ? '新建模板' : '编辑模板'}\n open={open}\n onCancel={onCancel}\n width={720}\n okText=\"保存\"\n autoClose={false}\n focusable={{ trap: false }}\n afterOpenChange={handleAfterOpenChange}\n formProps={formProps}\n >\n <FormInfo column={1} list={fieldList} />\n {editorReady ? (\n <FormItem>\n {(api: FormApiLike) => {\n const data =\n (typeof api.getFormData === 'function' ? api.getFormData() : undefined) ??\n api.formData ??\n formData;\n const titlePreview = applyTemplateVars(String(data.titleTemplate || ''), previewVars);\n const bodyPreview = applyTemplateVars(\n stripHtmlToText(String(data.bodyTemplate || '')),\n previewVars,\n );\n return (\n <>\n {varsEmptyHint ? (\n <Typography.Text type=\"secondary\">{varsEmptyHint}</Typography.Text>\n ) : null}\n <Typography.Paragraph type=\"secondary\" className={styles.preview}>\n 标题预览:{titlePreview || '—'}\n </Typography.Paragraph>\n <Typography.Paragraph type=\"secondary\" className={styles.preview}>\n 正文预览:{bodyPreview || '—'}\n </Typography.Paragraph>\n </>\n );\n }}\n </FormItem>\n ) : null}\n <div style={{ marginTop: 12 }}>\n <Typography.Text>受众角色</Typography.Text>\n {renderAudienceField ? (\n renderAudienceField({ roles, onChange: setRoles })\n ) : (\n <AntSelect\n mode=\"multiple\"\n style={{ width: '100%', marginTop: 8 }}\n value={roles}\n disabled={!canWrite}\n placeholder={roleOptions.length ? '选择角色' : '暂无角色数据'}\n options={roleOptions.map((r) => ({\n value: r.code,\n label: r.name || r.code,\n }))}\n optionFilterProp=\"label\"\n onChange={(v) => setRoles(v || [])}\n notFoundContent=\"暂无角色\"\n />\n )}\n </div>\n </FormModal>\n );\n};\n\nexport default TemplateFormModal;\n"],"names":["TemplateFormModal","open","isCreate","initial","catalog","roleOptions","variables","catalogError","previewVars","canWrite","onCancel","onSubmit","renderAudienceField","roles","setRoles","useState","editorReady","setEditorReady","useEffect","id","editorKey","formData","useMemo","normalizeTemplatePlaceholders","varsEmptyHint","handleAfterOpenChange","useCallback","nextOpen","fieldList","Typography","fields","jsx","Input","Select","c","RichTextField","formProps","data","message","scenario","eventKey","hit","e","jsxs","FormModal","FormInfo","FormItem","api","titlePreview","applyTemplateVars","bodyPreview","stripHtmlToText","Fragment","styles","AntSelect","r","v"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TemplateFormModal.js","sources":["../../../../../../src/components/Tools/MessageCenter/MessageTemplateAdmin/Modal/TemplateFormModal.tsx"],"sourcesContent":["import { FormInfo, FormItem, FormModal, Input, Select } from '@/components/FormInfo';\nimport { RichTextField } from '@/components/FormInfo/RichTextField';\nimport { sanitizeInboxHtml } from '@/components/Tools/Inbox/sanitizeInboxHtml';\nimport { applyTemplateVars, normalizeTemplatePlaceholders } from '../../utils/templateCode';\nimport { Collapse, Modal, Typography, message } from 'antd';\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport type {\n MessageAudienceRoleOption,\n MessageEventCatalogItem,\n MessageTemplateAdminItem,\n MessageTemplateVariable,\n} from '../types';\nimport {\n AUDIENCE_SLOT_OPTIONS,\n ORG_TENANT_SLOT,\n hasAudienceSelection,\n normalizeAudienceSlots,\n} from '../audienceSlots';\nimport styles from '../style.module.scss';\n\n/** ReactModal 内 Select 弹出层须高于 Modal(≈1100) */\nconst selectInModalPopupProps = {\n getPopupContainer: () => document.body,\n styles: { popup: { root: { zIndex: 2000 } } },\n} as const;\n\nexport type TemplateFormModalProps = {\n open: boolean;\n isCreate: boolean;\n initial: MessageTemplateAdminItem | null;\n catalog: MessageEventCatalogItem[];\n roleOptions: MessageAudienceRoleOption[];\n variables: MessageTemplateVariable[];\n /** catalog 请求失败时的短文案(与「变量为空」区分) */\n catalogError?: string;\n previewVars: Record<string, string>;\n canWrite: boolean;\n onCancel: () => void;\n onSubmit: (item: MessageTemplateAdminItem) => Promise<void>;\n renderAudienceField?: (ctx: {\n roles: string[];\n onChange: (roles: string[]) => void;\n }) => React.ReactNode;\n};\n\ntype FormShape = {\n code?: string;\n eventKey?: string;\n scenario?: string;\n titleTemplate?: string;\n bodyTemplate?: string;\n audienceRoles?: string[];\n audienceSlots?: string[];\n};\n\ntype FormApiLike = {\n formData?: FormShape;\n getFormData?: () => FormShape;\n};\n\n/**\n * 模板新建/编辑:FormModal + FormInfo;正文 RichTextField。\n * CKEditor 在 open 后微任务挂载,避免与 Modal focus/动画互抢;禁 mention uplift 死循环。\n */\nexport const TemplateFormModal: React.FC<TemplateFormModalProps> = ({\n open,\n isCreate,\n initial,\n catalog,\n roleOptions,\n variables,\n catalogError,\n previewVars,\n canWrite,\n onCancel,\n onSubmit,\n renderAudienceField,\n}) => {\n /** 仅业务 DI 自定义受众插槽时使用;默认走 FormInfo Select */\n const [roles, setRoles] = useState<string[]>([]);\n const [editorReady, setEditorReady] = useState(false);\n\n useEffect(() => {\n if (!open || !initial) {\n setEditorReady(false);\n return;\n }\n setRoles(initial.audienceRoles || initial.roles || []);\n const id = window.requestAnimationFrame(() => setEditorReady(true));\n return () => window.cancelAnimationFrame(id);\n }, [open, initial]);\n\n const editorKey = initial?.id || initial?.code || (isCreate ? 'create' : 'edit');\n\n const formData = useMemo<FormShape>(() => {\n if (!initial) return {};\n return {\n code: initial.code,\n eventKey: initial.eventKey,\n scenario: initial.scenario || initial.label || '',\n titleTemplate: normalizeTemplatePlaceholders(\n initial.titleTemplate || initial.titlePreview || '',\n ),\n bodyTemplate: normalizeTemplatePlaceholders(initial.bodyTemplate || ''),\n audienceRoles: initial.audienceRoles || initial.roles || [],\n audienceSlots: initial.audienceSlots || [],\n };\n }, [initial]);\n\n const varsEmptyHint = catalogError\n ? `目录加载失败,无法插入变量(${catalogError})`\n : variables.length === 0\n ? '暂无 catalog 变量'\n : '';\n\n const handleAfterOpenChange = useCallback((nextOpen: boolean) => {\n if (nextOpen) setEditorReady(true);\n else setEditorReady(false);\n }, []);\n\n const fieldList = useMemo(() => {\n if (!editorReady) {\n return [\n <Typography.Text key=\"loading\" type=\"secondary\">\n 加载编辑器…\n </Typography.Text>,\n ];\n }\n const fields: React.ReactNode[] = [];\n if (!isCreate) {\n fields.push(<Input key=\"code\" name=\"code\" label=\"编号\" disabled />);\n }\n fields.push(\n <Select\n key=\"eventKey\"\n name=\"eventKey\"\n label=\"适用场景\"\n rule=\"REQ\"\n disabled={!canWrite}\n optionLabelProp=\"label\"\n options={catalog.map((c) => ({\n value: c.eventKey,\n label: c.label || c.eventKey,\n }))}\n placeholder={catalog.length ? '选择场景' : '暂无事件目录'}\n {...selectInModalPopupProps}\n />,\n <Input\n key=\"titleTemplate\"\n name=\"titleTemplate\"\n label=\"标题模板\"\n rule=\"REQ\"\n disabled={!canWrite}\n enableVariableMention\n variables={variables}\n catalogError={catalogError}\n placeholder=\"点「插入变量」选择 catalog 变量\"\n labelTips={\n isCreate\n ? '新建默认停用。标题:点「插入变量」插入明文 {{key}}(可手改)。正文:原子色块,不可改字,整颗删除。'\n : '标题可手改 {{key}};正文为原子色块(不可改字、Backspace 整颗删)。'\n }\n />,\n <RichTextField\n key=\"bodyTemplate\"\n name=\"bodyTemplate\"\n label=\"正文模板\"\n disabled={!canWrite}\n enableVariableMention\n variables={variables}\n catalogError={catalogError}\n editorKey={editorKey}\n placeholder=\"编辑正文,点「插入变量」\"\n minHeight={160}\n />,\n );\n if (!renderAudienceField) {\n fields.push(\n <Select\n key=\"audienceRoles\"\n name=\"audienceRoles\"\n label=\"受众角色\"\n mode=\"multiple\"\n allowClear\n disabled={!canWrite}\n options={roleOptions.map((r) => ({\n value: r.code,\n label: r.name || r.code,\n }))}\n optionFilterProp=\"label\"\n maxTagCount=\"responsive\"\n placeholder={roleOptions.length ? '下拉选择角色(可多选)' : '暂无角色数据'}\n notFoundContent=\"暂无角色\"\n labelTips=\"可与「通知范围」并存;至少选角色或槽位之一。emit 与显式 userIds 并集送达。\"\n {...selectInModalPopupProps}\n />,\n <Select\n key=\"audienceSlots\"\n name=\"audienceSlots\"\n label=\"通知范围\"\n mode=\"multiple\"\n allowClear\n disabled={!canWrite}\n options={AUDIENCE_SLOT_OPTIONS.map((o) => ({\n value: o.value,\n label: o.label,\n }))}\n optionFilterProp=\"label\"\n maxTagCount=\"responsive\"\n placeholder=\"可选:本人/领导/部门/分厂/租户或任务当事人\"\n notFoundContent=\"暂无槽位\"\n labelTips=\"依赖业务 emit.audienceContext;无上下文的槽不会发出。选「本租户」保存前会确认。\"\n {...selectInModalPopupProps}\n />,\n );\n }\n return fields;\n }, [\n editorReady,\n isCreate,\n canWrite,\n catalog,\n variables,\n editorKey,\n catalogError,\n renderAudienceField,\n roleOptions,\n ]);\n\n const formProps = useMemo(\n () => ({\n data: formData,\n onSubmit: async (data: FormShape) => {\n if (!canWrite) {\n message.warning('当前为只读(业务未授予写权限)');\n return false;\n }\n const eventKey = String(data.eventKey || '').trim();\n if (!eventKey) {\n message.warning('请选择适用场景');\n return false;\n }\n const titleTemplate = normalizeTemplatePlaceholders(String(data.titleTemplate || ''));\n if (!titleTemplate.trim()) {\n message.warning('请填写标题模板');\n return false;\n }\n const audienceRoles = renderAudienceField\n ? roles\n : Array.isArray(data.audienceRoles)\n ? data.audienceRoles\n : [];\n const audienceSlots = normalizeAudienceSlots(data.audienceSlots || []);\n if (\n !hasAudienceSelection({\n roles: audienceRoles,\n slots: audienceSlots,\n userIds: null,\n })\n ) {\n message.warning('请选择受众角色或通知范围(至少一个)');\n return false;\n }\n if (audienceSlots.includes(ORG_TENANT_SLOT)) {\n const ok = await new Promise<boolean>((resolve) => {\n Modal.confirm({\n title: '确认通知本租户全员?',\n content: '已选「本租户(全公司)」:将向当前租户内用户展开(≠跨租户)。确认保存?',\n okText: '确认保存',\n cancelText: '取消',\n onOk: () => resolve(true),\n onCancel: () => resolve(false),\n });\n });\n if (!ok) return false;\n }\n const hit = catalog.find((c) => c.eventKey === eventKey);\n const scenario = String(hit?.label || data.scenario || eventKey).trim();\n try {\n await onSubmit({\n ...(initial || {}),\n code: data.code || initial?.code,\n eventKey,\n scenario,\n label: scenario,\n messageType: hit?.messageType || initial?.messageType || 'alert',\n titleTemplate,\n bodyTemplate: normalizeTemplatePlaceholders(String(data.bodyTemplate || '')),\n audienceRoles,\n roles: audienceRoles,\n audienceSlots,\n enabled: isCreate ? false : initial?.enabled !== false,\n channel: initial?.channel || 'in_app',\n });\n onCancel();\n } catch (e) {\n message.error(e instanceof Error ? e.message : String(e));\n return false;\n }\n },\n }),\n [\n formData,\n canWrite,\n catalog,\n onSubmit,\n initial,\n roles,\n isCreate,\n onCancel,\n renderAudienceField,\n ],\n );\n\n return (\n <FormModal\n title={isCreate ? '新建模板' : '编辑模板'}\n open={open}\n onCancel={onCancel}\n width={720}\n size=\"small\"\n className=\"msg-center-form-modal\"\n okText=\"保存\"\n autoClose={false}\n focusable={{ trap: false }}\n afterOpenChange={handleAfterOpenChange}\n formProps={formProps}\n >\n <FormInfo column={1} list={fieldList} />\n {renderAudienceField ? (\n <div className={styles.audienceBlock}>\n <Typography.Text className={styles.audienceLabel}>\n <span style={{ color: '#ff4d4f', marginRight: 4 }}>*</span>\n 受众角色\n </Typography.Text>\n {renderAudienceField({ roles, onChange: setRoles })}\n </div>\n ) : null}\n {editorReady ? (\n <FormItem>\n {(api: FormApiLike) => {\n const data =\n (typeof api.getFormData === 'function' ? api.getFormData() : undefined) ??\n api.formData ??\n formData;\n const titlePreview = applyTemplateVars(String(data.titleTemplate || ''), previewVars);\n const bodyRaw = applyTemplateVars(String(data.bodyTemplate || ''), previewVars);\n const bodyHtml = sanitizeInboxHtml(bodyRaw);\n return (\n <div className={styles.previewCollapse}>\n {varsEmptyHint ? (\n <Typography.Text type=\"secondary\">{varsEmptyHint}</Typography.Text>\n ) : null}\n <Collapse\n ghost\n size=\"small\"\n items={[\n {\n key: 'preview',\n label: '效果预览',\n children: (\n <div className={styles.previewCard}>\n <div className={styles.previewTitle}>\n {titlePreview.trim() || (\n <span className={styles.previewEmpty}>(无标题)</span>\n )}\n </div>\n {bodyHtml ? (\n <div\n className={styles.previewBody}\n dangerouslySetInnerHTML={{ __html: bodyHtml }}\n />\n ) : (\n <div className={`${styles.previewBody} ${styles.previewEmpty}`}>\n (无正文)\n </div>\n )}\n </div>\n ),\n },\n ]}\n />\n </div>\n );\n }}\n </FormItem>\n ) : null}\n </FormModal>\n );\n};\n\nexport default TemplateFormModal;\n"],"names":["selectInModalPopupProps","TemplateFormModal","open","isCreate","initial","catalog","roleOptions","variables","catalogError","previewVars","canWrite","onCancel","onSubmit","renderAudienceField","roles","setRoles","useState","editorReady","setEditorReady","useEffect","id","editorKey","formData","useMemo","normalizeTemplatePlaceholders","varsEmptyHint","handleAfterOpenChange","useCallback","nextOpen","fieldList","Typography","fields","jsx","Input","Select","c","RichTextField","r","AUDIENCE_SLOT_OPTIONS","o","formProps","data","message","eventKey","titleTemplate","audienceRoles","audienceSlots","normalizeAudienceSlots","hasAudienceSelection","ORG_TENANT_SLOT","resolve","Modal","hit","scenario","e","jsxs","FormModal","FormInfo","styles","FormItem","api","titlePreview","applyTemplateVars","bodyRaw","bodyHtml","sanitizeInboxHtml","Collapse"],"mappings":"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"}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
import { MessageAudienceRoleOption, MessageCrudFlags, MessageEventCatalogItem, MessageTemplateAdminItem, PushRuleAdminItem } from '../types';
|
|
2
|
+
import { MessageAudienceRoleOption, MessageAudienceUserOption, MessageCrudFlags, MessageEventCatalogItem, MessageTemplateAdminItem, PushRuleAdminItem } from '../types';
|
|
3
3
|
export type PushRulesPanelProps = {
|
|
4
4
|
crud: MessageCrudFlags;
|
|
5
5
|
catalog: MessageEventCatalogItem[];
|
|
6
6
|
templates: MessageTemplateAdminItem[];
|
|
7
7
|
roleOptions: MessageAudienceRoleOption[];
|
|
8
|
+
userOptions?: MessageAudienceUserOption[];
|
|
9
|
+
/** 角色 options 加载失败短文案(勿静默空列表) */
|
|
10
|
+
audienceRolesError?: string;
|
|
11
|
+
/** 例外抄送(静态 userIds)options 加载失败短文案 */
|
|
12
|
+
audienceUsersError?: string;
|
|
8
13
|
fetchPushRules: () => Promise<PushRuleAdminItem[]>;
|
|
9
14
|
savePushRule: (item: PushRuleAdminItem) => Promise<void>;
|
|
10
15
|
setPushRuleEnabled?: (item: PushRuleAdminItem, enabled: boolean) => Promise<void>;
|
|
@@ -13,6 +18,8 @@ export type PushRulesPanelProps = {
|
|
|
13
18
|
};
|
|
14
19
|
/**
|
|
15
20
|
* 推送规则 CRUD:必含 eventKey + templateCode;channels 默认 in_app。
|
|
21
|
+
* 受众:角色多选 + 通知范围(audienceSlots)+ 例外抄送;roles∪slots∪userIds 至少一个。
|
|
22
|
+
* 任务当事人/组织槽依赖 emit.audienceContext;禁 Tree 盖壳。
|
|
16
23
|
*/
|
|
17
24
|
export declare const PushRulesPanel: React.FC<PushRulesPanelProps>;
|
|
18
25
|
export default PushRulesPanel;
|