@xmanrui/dsh-im 4.2.1 → 4.4.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/README.en.md +4 -2
- package/README.md +4 -2
- package/lib/client.js +1267 -787
- package/lib/index.js +237 -235
- package/package.json +1 -1
- package/plugin-src/client/access-policy-settings.js +351 -0
- package/plugin-src/client/channel-card-meta.js +2 -1
- package/plugin-src/client/channels/dingtalk/api.js +5 -0
- package/plugin-src/client/channels/dingtalk/index.js +1 -0
- package/plugin-src/client/channels/feishu/api.js +5 -0
- package/plugin-src/client/channels/feishu/index.js +1 -0
- package/plugin-src/client/channels/qq/api.js +5 -0
- package/plugin-src/client/channels/qq/index.js +1 -0
- package/plugin-src/client/channels/shared/token-api.js +5 -0
- package/plugin-src/client/channels/shared/token-channel.js +1 -0
- package/plugin-src/client/channels/telegram/api.js +2 -17
- package/plugin-src/client/channels/telegram/index.js +0 -112
- package/plugin-src/client/channels/telegram/styles.js +0 -28
- package/plugin-src/client/channels/wecom/api.js +5 -0
- package/plugin-src/client/channels/wecom/index.js +1 -0
- package/plugin-src/client/channels/weixin/api.js +5 -0
- package/plugin-src/client/channels/weixin/index.js +1 -0
- package/plugin-src/client/channels/whatsapp/api.js +4 -10
- package/plugin-src/client/channels/whatsapp/index.js +1 -125
- package/plugin-src/client/channels/whatsapp/styles.js +0 -25
- package/plugin-src/client/context-enhancement.js +207 -102
- package/plugin-src/client/delivery-settings.js +61 -9
- package/plugin-src/client/i18n.js +71 -3
- package/plugin-src/client/index.js +1 -0
- package/plugin-src/client/styles.js +59 -8
- package/plugin-src/host/channels/dingtalk/production.mjs +12 -1
- package/plugin-src/host/channels/dingtalk/rpc.mjs +11 -0
- package/plugin-src/host/channels/feishu/production.mjs +39 -1
- package/plugin-src/host/channels/feishu/rpc.mjs +19 -2
- package/plugin-src/host/channels/qq/production.mjs +12 -1
- package/plugin-src/host/channels/qq/rpc.mjs +11 -0
- package/plugin-src/host/channels/shared/access-policy-production.mjs +137 -0
- package/plugin-src/host/channels/shared/access-policy-rpc.mjs +17 -0
- package/plugin-src/host/channels/shared/production.mjs +15 -1
- package/plugin-src/host/channels/shared/rpc.mjs +9 -0
- package/plugin-src/host/channels/slack/production.mjs +12 -1
- package/plugin-src/host/channels/slack/rpc.mjs +10 -0
- package/plugin-src/host/channels/telegram/rpc.mjs +2 -49
- package/plugin-src/host/channels/wecom/production.mjs +12 -1
- package/plugin-src/host/channels/wecom/rpc.mjs +11 -0
- package/plugin-src/host/channels/weixin/production.mjs +12 -1
- package/plugin-src/host/channels/weixin/rpc.mjs +11 -0
- package/plugin-src/host/channels/whatsapp/production.mjs +16 -2
- package/plugin-src/host/channels/whatsapp/rpc.mjs +10 -15
- package/scripts/verify-package.mjs +4 -3
- package/src/channels/dingtalk/dingtalk-bridge.mjs +61 -9
- package/src/channels/dingtalk/dingtalk-runtime.mjs +4 -0
- package/src/channels/discord/discord-runtime.mjs +29 -1
- package/src/channels/feishu/bridge.mjs +286 -120
- package/src/channels/feishu/feishu-runtime.mjs +4 -0
- package/src/channels/feishu/message-utils.mjs +5 -0
- package/src/channels/qq/qq-bridge.mjs +59 -17
- package/src/channels/qq/qq-runtime.mjs +25 -3
- package/src/channels/shared/access-policy.mjs +210 -0
- package/src/channels/shared/bot-workspace-store.mjs +176 -33
- package/src/channels/shared/command-permission.mjs +32 -0
- package/src/channels/shared/compact-command.mjs +5 -2
- package/src/channels/shared/context-enhancement.mjs +73 -20
- package/src/channels/shared/i18n-en/shared-c.mjs +2 -0
- package/src/channels/shared/inbound-access.mjs +43 -0
- package/src/channels/shared/text-harness-bridge.mjs +47 -4
- package/src/channels/shared/workspace-command.mjs +10 -1
- package/src/channels/slack/slack-runtime.mjs +4 -0
- package/src/channels/telegram/telegram-runtime.mjs +5 -13
- package/src/channels/wecom/wecom-bridge.mjs +51 -4
- package/src/channels/wecom/wecom-runtime.mjs +4 -0
- package/src/channels/weixin/weixin-bridge.mjs +59 -16
- package/src/channels/weixin/weixin-runtime.mjs +4 -0
- package/src/channels/whatsapp/whatsapp-runtime.mjs +42 -20
|
@@ -4,34 +4,6 @@ const CSS = String.raw`
|
|
|
4
4
|
.dtg-page { --ddt-accent: #229ed9; --ddt-accent-deep: #1687bd; --ddt-accent-wash: #eaf7fd; }
|
|
5
5
|
.dtg-avatar { color: #fff; background: #229ed9; }
|
|
6
6
|
.dtg-avatar svg { display: block; }
|
|
7
|
-
.dtg-access { min-width: 0; width: 100%; max-width: 100%; display: grid; gap: 10px; padding: 12px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 10px; background: var(--dsw-alias-bg-layer-2, #f7f8fa); }
|
|
8
|
-
.dtg-accessHeading { position: relative; min-width: 0; max-width: 100%; display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 8px 12px; }
|
|
9
|
-
.dtg-accessHeading > strong { min-width: 0; font-size: 13px; overflow-wrap: anywhere; }
|
|
10
|
-
.dtg-accessStatus { min-width: 0; max-width: 100%; flex: 0 1 auto; display: inline-flex; align-items: center; justify-content: flex-end; flex-wrap: wrap; gap: 6px; }
|
|
11
|
-
.dtg-accessBadge { min-width: 0; max-width: 100%; flex: 0 1 auto; padding: 3px 8px; border-radius: 999px; color: #1687bd; background: #eaf7fd; font-size: 11px; font-weight: 700; overflow-wrap: anywhere; text-align: center; }
|
|
12
|
-
.dtg-accessBadge[data-mode="private-allowlist"] { color: #a15c00; background: #fff3d6; }
|
|
13
|
-
.dtg-accessHelp { position: static; display: inline-flex; flex: none; }
|
|
14
|
-
.dtg-accessHelpButton { width: 20px; height: 20px; display: grid; place-items: center; padding: 0; border: 1px solid color-mix(in srgb, #229ed9 28%, var(--dsw-alias-border-l2, #dfe1e5)); border-radius: 50%; color: #1687bd; background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 12px; line-height: 1; font-weight: 750; cursor: help; transition: border-color .15s ease, color .15s ease, background .15s ease, box-shadow .15s ease; }
|
|
15
|
-
.dtg-accessHelpButton:hover { border-color: #229ed9; color: #1178a8; background: #eaf7fd; }
|
|
16
|
-
.dtg-accessHelpButton:focus-visible { outline: none; border-color: #229ed9; box-shadow: 0 0 0 3px color-mix(in srgb, #229ed9 18%, transparent); }
|
|
17
|
-
.dtg-accessTooltip { position: absolute; top: calc(100% + 8px); right: 0; z-index: 30; width: min(300px, 100%); max-width: 100%; display: grid; gap: 8px; padding: 10px 11px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 9px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 10px 28px rgb(31 35 41 / 16%); opacity: 0; visibility: hidden; transform: translateY(-3px); pointer-events: none; transition: opacity .15s ease, transform .15s ease, visibility .15s ease; }
|
|
18
|
-
.dtg-accessTooltipItem { display: grid; gap: 2px; }
|
|
19
|
-
.dtg-accessTooltipItem + .dtg-accessTooltipItem { padding-top: 8px; border-top: 1px solid var(--dsw-alias-border-l2, #eef0f3); }
|
|
20
|
-
.dtg-accessTooltipItem strong { color: var(--dsw-alias-label-primary, #1f2329); font-size: 12px; line-height: 17px; font-weight: 700; }
|
|
21
|
-
.dtg-accessTooltipItem > span { color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 16px; font-weight: 400; }
|
|
22
|
-
.dtg-accessHelp:hover .dtg-accessTooltip, .dtg-accessHelp:focus-within .dtg-accessTooltip { opacity: 1; visibility: visible; transform: translateY(0); }
|
|
23
|
-
.dtg-accessField { min-width: 0; max-width: 100%; display: grid; gap: 5px; color: var(--dsw-alias-label-primary, #1f2329); font-size: 12px; font-weight: 600; }
|
|
24
|
-
.dtg-accessField select, .dtg-accessField textarea { min-width: 0; width: 100%; max-width: 100%; box-sizing: border-box; border: 1px solid var(--dsw-alias-border-l1, #c9cdd4); border-radius: 7px; color: inherit; background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-weight: 400; }
|
|
25
|
-
.dtg-accessField select { height: 34px; padding: 0 9px; }
|
|
26
|
-
.dtg-accessField textarea { min-height: 68px; padding: 8px 9px; resize: vertical; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
27
|
-
.dtg-accessField textarea:disabled { color: var(--dsw-alias-label-tertiary, #8f959e); background: var(--dsw-alias-bg-module-platform, #f2f3f5); cursor: not-allowed; resize: none; opacity: 1; }
|
|
28
|
-
.dtg-accessField > span, .dtg-accessField small { overflow-wrap: anywhere; }
|
|
29
|
-
.dtg-accessField small { color: var(--dsw-alias-label-secondary, #646a73); font-weight: 400; }
|
|
30
|
-
.dtg-accessWarning, .dtg-accessError { margin: 0; font-size: 12px; line-height: 1.5; }
|
|
31
|
-
.dtg-accessWarning { color: #a15c00; }
|
|
32
|
-
.dtg-accessError { color: var(--dsw-alias-state-error-primary, #d83931); }
|
|
33
|
-
.dtg-accessActions { min-width: 0; max-width: 100%; display: flex; justify-content: flex-end; flex-wrap: wrap; }
|
|
34
|
-
.dtg-accessActions .ddt-button { max-width: 100%; white-space: normal; }
|
|
35
7
|
`;
|
|
36
8
|
|
|
37
9
|
export function installTelegramStyles() {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { normalizeAgentPresetCatalog, normalizeAgentPresetId, SET_AGENT_PRESET_ENDPOINT } from '../../agent-preset.js';
|
|
2
2
|
import { normalizeLastMessageError } from '../../last-message-error.js';
|
|
3
|
+
import { normalizeAccessPolicy } from '../../../../src/channels/shared/access-policy.mjs';
|
|
3
4
|
import { normalizeContextEnhancementConfig } from '../../../../src/channels/shared/context-enhancement.mjs';
|
|
4
5
|
|
|
5
6
|
export const WECOM_RPC_CHANNEL = '/wecom';
|
|
@@ -15,6 +16,7 @@ export const WECOM_ENDPOINTS = Object.freeze({
|
|
|
15
16
|
setWorkspace: 'bot.workspace.set',
|
|
16
17
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
17
18
|
setContextEnhancement: 'bot.context-enhancement.set',
|
|
19
|
+
setAccessPolicy: 'bot.access-policy.set',
|
|
18
20
|
});
|
|
19
21
|
|
|
20
22
|
const PROVISION_STATES = new Set(['starting', 'pending', 'refreshing', 'connecting', 'connected', 'failed', 'cancelled']);
|
|
@@ -99,6 +101,9 @@ function normalizeBot(value) {
|
|
|
99
101
|
workspace: text(value.workspace, '', 4_096),
|
|
100
102
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
101
103
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
104
|
+
...(Object.hasOwn(value, 'accessPolicy')
|
|
105
|
+
? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) }
|
|
106
|
+
: {}),
|
|
102
107
|
bot: {
|
|
103
108
|
name: text(value.bot?.name, '企业微信机器人', 100),
|
|
104
109
|
appIdMasked: text(value.bot?.appIdMasked, '应用标识已安全保存', 140),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { normalizeAgentPresetCatalog, normalizeAgentPresetId, SET_AGENT_PRESET_ENDPOINT } from '../../agent-preset.js';
|
|
2
2
|
import { normalizeLastMessageError } from '../../last-message-error.js';
|
|
3
|
+
import { normalizeAccessPolicy } from '../../../../src/channels/shared/access-policy.mjs';
|
|
3
4
|
import { normalizeContextEnhancementConfig } from '../../../../src/channels/shared/context-enhancement.mjs';
|
|
4
5
|
|
|
5
6
|
export const WEIXIN_RPC_CHANNEL = '/weixin';
|
|
@@ -14,6 +15,7 @@ export const WEIXIN_ENDPOINTS = Object.freeze({
|
|
|
14
15
|
setWorkspace: 'bot.workspace.set',
|
|
15
16
|
setAgentPreset: SET_AGENT_PRESET_ENDPOINT,
|
|
16
17
|
setContextEnhancement: 'bot.context-enhancement.set',
|
|
18
|
+
setAccessPolicy: 'bot.access-policy.set',
|
|
17
19
|
});
|
|
18
20
|
|
|
19
21
|
const ACCOUNT_STATES = new Set(['connected', 'connecting', 'offline', 'error']);
|
|
@@ -124,6 +126,9 @@ function normalizeBot(value) {
|
|
|
124
126
|
workspace: string(value.workspace).slice(0, 4_096),
|
|
125
127
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
126
128
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
129
|
+
...(Object.hasOwn(value, 'accessPolicy')
|
|
130
|
+
? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) }
|
|
131
|
+
: {}),
|
|
127
132
|
bot: {
|
|
128
133
|
name: string(value.bot.name, '微信机器人'),
|
|
129
134
|
accountIdMasked: string(value.bot.accountIdMasked, '已安全保存'),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { normalizeAgentPresetCatalog, normalizeAgentPresetId, SET_AGENT_PRESET_ENDPOINT } from '../../agent-preset.js';
|
|
2
2
|
import { normalizeLastMessageError } from '../../last-message-error.js';
|
|
3
|
+
import { normalizeAccessPolicy } from '../../../../src/channels/shared/access-policy.mjs';
|
|
3
4
|
import { normalizeContextEnhancementConfig } from '../../../../src/channels/shared/context-enhancement.mjs';
|
|
4
5
|
|
|
5
6
|
export const WHATSAPP_RPC_CHANNEL = '/whatsapp';
|
|
@@ -91,16 +92,9 @@ function normalizeBot(value) {
|
|
|
91
92
|
workspace: text(value.workspace, '', 4_096),
|
|
92
93
|
agentPreset: normalizeAgentPresetId(value.agentPreset),
|
|
93
94
|
contextEnhancement: normalizeContextEnhancementConfig(value.contextEnhancement),
|
|
94
|
-
accessPolicy
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
) ? value.accessPolicy.accessMode : 'self-only',
|
|
98
|
-
allowedNumbers: Array.isArray(value.accessPolicy?.allowedNumbers)
|
|
99
|
-
? [...new Set(value.accessPolicy.allowedNumbers.filter((entry) => (
|
|
100
|
-
typeof entry === 'string' && /^[1-9]\d{4,14}$/.test(entry)
|
|
101
|
-
)))]
|
|
102
|
-
: [],
|
|
103
|
-
},
|
|
95
|
+
...(Object.hasOwn(value, 'accessPolicy')
|
|
96
|
+
? { accessPolicy: normalizeAccessPolicy(value.accessPolicy) }
|
|
97
|
+
: {}),
|
|
104
98
|
bot: {
|
|
105
99
|
name: text(value.bot?.name, 'WhatsApp机器人', 100),
|
|
106
100
|
idMasked: text(value.bot?.idMasked, 'WhatsApp账号', 140),
|
|
@@ -31,119 +31,6 @@ import { installWhatsappStyles } from './styles.js';
|
|
|
31
31
|
|
|
32
32
|
const ACTIVE_STATES = new Set(['pending', 'connecting']);
|
|
33
33
|
|
|
34
|
-
function accessPolicyFor(account) {
|
|
35
|
-
const accessMode = ['self-only', 'private-allowlist', 'open'].includes(
|
|
36
|
-
account?.accessPolicy?.accessMode,
|
|
37
|
-
) ? account.accessPolicy.accessMode : 'self-only';
|
|
38
|
-
return {
|
|
39
|
-
accessMode,
|
|
40
|
-
allowedNumbers: Array.isArray(account?.accessPolicy?.allowedNumbers)
|
|
41
|
-
? account.accessPolicy.allowedNumbers : [],
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function allowedNumbersFromText(value) {
|
|
46
|
-
const entries = value.split(/\r?\n/).map((entry) => entry.trim()).filter(Boolean);
|
|
47
|
-
const normalized = entries.map((entry) => entry.replace(/^\+/, ''));
|
|
48
|
-
if (normalized.some((entry) => !/^[1-9]\d{4,14}$/.test(entry))) {
|
|
49
|
-
throw new TypeError('电话号码必须包含国家或地区代码,每行一个。');
|
|
50
|
-
}
|
|
51
|
-
return [...new Set(normalized)];
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export function WhatsappAccessSettings({ account, busy = false, onSave }) {
|
|
55
|
-
const policy = accessPolicyFor(account);
|
|
56
|
-
const sourceNumbers = policy.allowedNumbers.join('\n');
|
|
57
|
-
const helpId = React.useId();
|
|
58
|
-
const [accessMode, setAccessMode] = React.useState(policy.accessMode);
|
|
59
|
-
const [allowedNumbers, setAllowedNumbers] = React.useState(sourceNumbers);
|
|
60
|
-
const [error, setError] = React.useState(null);
|
|
61
|
-
|
|
62
|
-
React.useEffect(() => {
|
|
63
|
-
setAccessMode(policy.accessMode);
|
|
64
|
-
setAllowedNumbers(sourceNumbers);
|
|
65
|
-
setError(null);
|
|
66
|
-
}, [policy.accessMode, sourceNumbers]);
|
|
67
|
-
|
|
68
|
-
const save = async (event) => {
|
|
69
|
-
event.preventDefault();
|
|
70
|
-
setError(null);
|
|
71
|
-
try {
|
|
72
|
-
const normalized = allowedNumbersFromText(allowedNumbers);
|
|
73
|
-
if (typeof onSave !== 'function') throw new Error('WhatsApp 访问设置暂不可用。');
|
|
74
|
-
await onSave({ accessMode, allowedNumbers: normalized });
|
|
75
|
-
} catch (caught) {
|
|
76
|
-
setError(caught?.message ?? 'WhatsApp 访问设置保存失败。');
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
const allowlistEnabled = accessMode === 'private-allowlist';
|
|
81
|
-
const labels = {
|
|
82
|
-
'self-only': '仅自己模式',
|
|
83
|
-
'private-allowlist': '指定联系人模式',
|
|
84
|
-
open: '开放响应模式',
|
|
85
|
-
};
|
|
86
|
-
return h('form', { className: 'dwa-access', onSubmit: save },
|
|
87
|
-
h('div', { className: 'dwa-accessHeading' },
|
|
88
|
-
h('strong', null, '访问设置'),
|
|
89
|
-
h('span', { className: 'dwa-accessStatus' },
|
|
90
|
-
h('span', { className: 'dwa-accessBadge', 'data-mode': policy.accessMode },
|
|
91
|
-
['已生效:', labels[policy.accessMode]]),
|
|
92
|
-
h('span', { className: 'dwa-accessHelp' },
|
|
93
|
-
h('button', {
|
|
94
|
-
type: 'button',
|
|
95
|
-
className: 'dwa-accessHelpButton',
|
|
96
|
-
'aria-label': '查看 WhatsApp 访问模式说明',
|
|
97
|
-
'aria-describedby': helpId,
|
|
98
|
-
}, h('span', { 'aria-hidden': 'true' }, '?')),
|
|
99
|
-
h('span', { id: helpId, className: 'dwa-accessTooltip', role: 'tooltip' },
|
|
100
|
-
h('span', { className: 'dwa-accessTooltipItem' },
|
|
101
|
-
h('strong', null, '仅自己模式'),
|
|
102
|
-
h('span', null, '只响应已绑定 WhatsApp 账号的自聊消息。')),
|
|
103
|
-
h('span', { className: 'dwa-accessTooltipItem' },
|
|
104
|
-
h('strong', null, '指定联系人模式'),
|
|
105
|
-
h('span', null, '响应自聊和白名单联系人的私聊,忽略群聊。')),
|
|
106
|
-
h('span', { className: 'dwa-accessTooltipItem' },
|
|
107
|
-
h('strong', null, '开放响应模式'),
|
|
108
|
-
h('span', null, '响应所有私聊、已绑定账号自己发出的群聊消息,以及其他群成员的提及或回复。')))))),
|
|
109
|
-
h('label', { className: 'dwa-accessField' },
|
|
110
|
-
h('span', null, '模式'),
|
|
111
|
-
h('select', {
|
|
112
|
-
value: accessMode,
|
|
113
|
-
disabled: busy,
|
|
114
|
-
'aria-label': 'WhatsApp 访问模式',
|
|
115
|
-
onChange: (event) => { setAccessMode(event.target.value); setError(null); },
|
|
116
|
-
},
|
|
117
|
-
h('option', { value: 'self-only' }, '仅自己模式(默认)'),
|
|
118
|
-
h('option', { value: 'private-allowlist' }, '指定联系人模式'),
|
|
119
|
-
h('option', { value: 'open' }, '开放响应模式'))),
|
|
120
|
-
allowlistEnabled
|
|
121
|
-
? h('label', { className: 'dwa-accessField' },
|
|
122
|
-
h('span', null, '允许私聊的 WhatsApp 电话号码'),
|
|
123
|
-
h('textarea', {
|
|
124
|
-
value: allowedNumbers,
|
|
125
|
-
disabled: busy,
|
|
126
|
-
rows: 3,
|
|
127
|
-
placeholder: '每行一个含国家或地区代码的号码',
|
|
128
|
-
'aria-label': '允许私聊的 WhatsApp 电话号码',
|
|
129
|
-
onChange: (event) => { setAllowedNumbers(event.target.value); setError(null); },
|
|
130
|
-
}),
|
|
131
|
-
h('small', null, '可以包含开头的 +,保存时会自动移除。'))
|
|
132
|
-
: null,
|
|
133
|
-
allowlistEnabled && allowedNumbers.trim() === ''
|
|
134
|
-
? h('p', { className: 'dwa-accessWarning', role: 'status' },
|
|
135
|
-
'白名单为空;保存后将只接受自聊消息。')
|
|
136
|
-
: null,
|
|
137
|
-
error ? h('p', { className: 'dwa-accessError', role: 'alert' }, error) : null,
|
|
138
|
-
h('div', { className: 'dwa-accessActions' },
|
|
139
|
-
h('button', {
|
|
140
|
-
type: 'submit',
|
|
141
|
-
className: 'ddt-button',
|
|
142
|
-
'data-kind': 'secondary',
|
|
143
|
-
disabled: busy,
|
|
144
|
-
}, busy ? '正在保存…' : '保存访问设置')));
|
|
145
|
-
}
|
|
146
|
-
|
|
147
34
|
const Button = React.forwardRef(function Button(
|
|
148
35
|
{ children, kind = 'secondary', className = '', ...props },
|
|
149
36
|
ref,
|
|
@@ -300,7 +187,6 @@ export function WhatsappAccountCard({
|
|
|
300
187
|
onWorkspaceSave,
|
|
301
188
|
onAgentPresetSave,
|
|
302
189
|
onContextEnhancementSave,
|
|
303
|
-
onAccessPolicySave,
|
|
304
190
|
onRequestRemove,
|
|
305
191
|
onConfirmRemove,
|
|
306
192
|
onCancelRemove,
|
|
@@ -333,6 +219,7 @@ export function WhatsappAccountCard({
|
|
|
333
219
|
botId: account.botId,
|
|
334
220
|
botName: account.bot.name,
|
|
335
221
|
connected: account.connected,
|
|
222
|
+
accessPolicy: account.accessPolicy,
|
|
336
223
|
}))),
|
|
337
224
|
h(WorkspaceEditor, {
|
|
338
225
|
workspace: account.workspace,
|
|
@@ -349,11 +236,6 @@ export function WhatsappAccountCard({
|
|
|
349
236
|
disabled: Boolean(busy),
|
|
350
237
|
onSave: onContextEnhancementSave,
|
|
351
238
|
}),
|
|
352
|
-
h(WhatsappAccessSettings, {
|
|
353
|
-
account,
|
|
354
|
-
busy: Boolean(busy),
|
|
355
|
-
onSave: onAccessPolicySave,
|
|
356
|
-
}),
|
|
357
239
|
h('div', { className: 'ddt-accountFooter dim-cardFooter' },
|
|
358
240
|
h('div', { className: 'dim-cardFooterLayout' },
|
|
359
241
|
h('div', { className: 'ddt-actions dim-cardActions' },
|
|
@@ -617,12 +499,6 @@ export function WhatsappSettingsTab({ rpcCall }) {
|
|
|
617
499
|
WHATSAPP_ENDPOINTS.setContextEnhancement,
|
|
618
500
|
{ botId: account.botId, config },
|
|
619
501
|
),
|
|
620
|
-
onAccessPolicySave: (accessPolicy) => botAction(
|
|
621
|
-
account,
|
|
622
|
-
'access',
|
|
623
|
-
WHATSAPP_ENDPOINTS.setAccessPolicy,
|
|
624
|
-
{ botId: account.botId, ...accessPolicy },
|
|
625
|
-
),
|
|
626
502
|
onRequestRemove: () => setRemoveTarget(account.botId),
|
|
627
503
|
onCancelRemove: () => setRemoveTarget(null),
|
|
628
504
|
onConfirmRemove: async () => {
|
|
@@ -4,31 +4,6 @@ const CSS = String.raw`
|
|
|
4
4
|
.dwa-page { --ddt-accent: #25d366; --ddt-accent-deep: #128c7e; --ddt-accent-wash: #eafbf0; }
|
|
5
5
|
.dwa-avatar { color: #fff; background: #25d366; }
|
|
6
6
|
.dwa-avatar svg { display: block; }
|
|
7
|
-
.dwa-access { display: grid; gap: 10px; padding: 12px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 10px; background: var(--dsw-alias-bg-layer-2, #f7f8fa); }
|
|
8
|
-
.dwa-accessHeading { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
|
|
9
|
-
.dwa-accessHeading > strong { font-size: 13px; }
|
|
10
|
-
.dwa-accessStatus { min-width: 0; display: inline-flex; align-items: center; justify-content: flex-end; gap: 6px; }
|
|
11
|
-
.dwa-accessBadge { flex: none; padding: 3px 8px; border-radius: 999px; color: #08785f; background: #eafbf0; font-size: 11px; font-weight: 700; }
|
|
12
|
-
.dwa-accessBadge[data-mode="private-allowlist"] { color: #0f6f8f; background: #eaf7fd; }
|
|
13
|
-
.dwa-accessBadge[data-mode="open"] { color: #a15c00; background: #fff3d6; }
|
|
14
|
-
.dwa-accessHelp { position: relative; display: inline-flex; flex: none; }
|
|
15
|
-
.dwa-accessHelpButton { width: 20px; height: 20px; display: grid; place-items: center; padding: 0; border: 1px solid color-mix(in srgb, #25d366 34%, var(--dsw-alias-border-l2, #dfe1e5)); border-radius: 50%; color: #128c7e; background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-size: 12px; line-height: 1; font-weight: 750; cursor: help; }
|
|
16
|
-
.dwa-accessTooltip { position: absolute; top: calc(100% + 8px); right: 0; z-index: 30; width: 270px; max-width: min(290px, calc(100vw - 48px)); display: grid; gap: 8px; padding: 10px 11px; border: 1px solid var(--dsw-alias-border-l2, #dfe1e5); border-radius: 9px; color: var(--dsw-alias-label-primary, #1f2329); background: var(--dsw-alias-bg-layer-3, #fff); box-shadow: 0 10px 28px rgb(31 35 41 / 16%); opacity: 0; visibility: hidden; transform: translateY(-3px); pointer-events: none; transition: opacity .15s ease, transform .15s ease, visibility .15s ease; }
|
|
17
|
-
.dwa-accessTooltipItem { display: grid; gap: 2px; }
|
|
18
|
-
.dwa-accessTooltipItem + .dwa-accessTooltipItem { padding-top: 8px; border-top: 1px solid var(--dsw-alias-border-l2, #eef0f3); }
|
|
19
|
-
.dwa-accessTooltipItem strong { font-size: 12px; line-height: 17px; }
|
|
20
|
-
.dwa-accessTooltipItem > span { color: var(--dsw-alias-label-secondary, #646a73); font-size: 11px; line-height: 16px; }
|
|
21
|
-
.dwa-accessHelp:hover .dwa-accessTooltip, .dwa-accessHelp:focus-within .dwa-accessTooltip { opacity: 1; visibility: visible; transform: translateY(0); }
|
|
22
|
-
.dwa-accessField { display: grid; gap: 5px; color: var(--dsw-alias-label-primary, #1f2329); font-size: 12px; font-weight: 600; }
|
|
23
|
-
.dwa-accessField select, .dwa-accessField textarea { width: 100%; box-sizing: border-box; border: 1px solid var(--dsw-alias-border-l1, #c9cdd4); border-radius: 7px; color: inherit; background: var(--dsw-alias-bg-layer-1, #fff); font: inherit; font-weight: 400; }
|
|
24
|
-
.dwa-accessField select { height: 34px; padding: 0 9px; }
|
|
25
|
-
.dwa-accessField textarea { min-height: 68px; padding: 8px 9px; resize: vertical; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
|
|
26
|
-
.dwa-accessField textarea:disabled { color: var(--dsw-alias-label-tertiary, #8f959e); background: var(--dsw-alias-bg-module-platform, #f2f3f5); cursor: not-allowed; resize: none; opacity: 1; }
|
|
27
|
-
.dwa-accessField small { color: var(--dsw-alias-label-secondary, #646a73); font-weight: 400; }
|
|
28
|
-
.dwa-accessWarning, .dwa-accessError { margin: 0; font-size: 12px; line-height: 1.5; }
|
|
29
|
-
.dwa-accessWarning { color: #a15c00; }
|
|
30
|
-
.dwa-accessError { color: var(--dsw-alias-state-error-primary, #d83931); }
|
|
31
|
-
.dwa-accessActions { display: flex; justify-content: flex-end; }
|
|
32
7
|
`;
|
|
33
8
|
|
|
34
9
|
export function installWhatsappStyles() {
|