@sparkelf/dsh-task-bus 0.1.2 → 0.1.3
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/lib/client.js +40 -790
- package/lib/client.js.map +1 -1
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -22,483 +22,6 @@ window.__ModuleLoader__.load({
|
|
|
22
22
|
danger: "var(--dsw-alias-state-danger, #b91c1c)"
|
|
23
23
|
};
|
|
24
24
|
//#endregion
|
|
25
|
-
//#region src/client/connector-state.ts
|
|
26
|
-
/**
|
|
27
|
-
* Client state adapter for the Task Center's one connector.
|
|
28
|
-
*
|
|
29
|
-
* The Host owns the authoritative enabled/capability state and the tool
|
|
30
|
-
* disclosure that follows it. This module only reads that state, sends the two
|
|
31
|
-
* writes the panel offers, and projects the task rows a capability filter
|
|
32
|
-
* selects. It never decides permissions: a capability absent from the Host's
|
|
33
|
-
* answer is one this account may not use, so it is never rendered.
|
|
34
|
-
*
|
|
35
|
-
* @module @sparkelf/dsh-task-bus/client/connector-state
|
|
36
|
-
*/
|
|
37
|
-
/** Route the Host serves the connector state from. */
|
|
38
|
-
const CONNECTOR_ROUTE = "/dsh-task-bus/api/connector";
|
|
39
|
-
/** Connector id carried by DataOps approval tasks. */
|
|
40
|
-
const CONNECTOR_ID = "wanxiang-ai";
|
|
41
|
-
/** Display name shared by the card and its empty state. */
|
|
42
|
-
const CONNECTOR_NAME = "万相AI中台连接器";
|
|
43
|
-
/** Copy for the capability ids the Host currently ships. */
|
|
44
|
-
const CAPABILITY_COPY = {
|
|
45
|
-
"approval.push": {
|
|
46
|
-
label: "接收审批任务",
|
|
47
|
-
description: "从万相AI中台接收待办理的审批任务"
|
|
48
|
-
},
|
|
49
|
-
"approval.writeback": {
|
|
50
|
-
label: "回写审批结果",
|
|
51
|
-
description: "把办理结果回写到万相AI中台"
|
|
52
|
-
},
|
|
53
|
-
"task.push": {
|
|
54
|
-
label: "接收通用任务",
|
|
55
|
-
description: "接收万相AI中台下发的通用任务"
|
|
56
|
-
},
|
|
57
|
-
"task.writeback": {
|
|
58
|
-
label: "回写任务状态",
|
|
59
|
-
description: "把任务处理状态回写到万相AI中台"
|
|
60
|
-
},
|
|
61
|
-
"ai.accept": {
|
|
62
|
-
label: "AI 受理",
|
|
63
|
-
description: "由助手创建受理会话处理任务"
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
/** Humanize an id the client has no display copy for. */
|
|
67
|
-
function humanizeCapability(id) {
|
|
68
|
-
return id.replace(/[._-]+/gu, " ").trim();
|
|
69
|
-
}
|
|
70
|
-
/** Parse one unknown wire value into connector state. */
|
|
71
|
-
function parseConnectorState(value) {
|
|
72
|
-
if (typeof value !== "object" || value === null) return {
|
|
73
|
-
enabled: false,
|
|
74
|
-
capabilities: {}
|
|
75
|
-
};
|
|
76
|
-
const row = value;
|
|
77
|
-
const capabilities = {};
|
|
78
|
-
const reasons = {};
|
|
79
|
-
const raw = typeof row.capabilities === "object" && row.capabilities !== null ? row.capabilities : {};
|
|
80
|
-
for (const [id, entry] of Object.entries(raw)) {
|
|
81
|
-
if (typeof entry === "boolean") {
|
|
82
|
-
capabilities[id] = entry;
|
|
83
|
-
continue;
|
|
84
|
-
}
|
|
85
|
-
if (typeof entry !== "object" || entry === null) continue;
|
|
86
|
-
const detail = entry;
|
|
87
|
-
if (detail.permitted === false) continue;
|
|
88
|
-
capabilities[id] = detail.enabled === true;
|
|
89
|
-
if (typeof detail.reason === "string" && detail.reason !== "") reasons[id] = detail.reason;
|
|
90
|
-
}
|
|
91
|
-
const rawReasons = typeof row.reasons === "object" && row.reasons !== null ? row.reasons : {};
|
|
92
|
-
for (const [id, reason] of Object.entries(rawReasons)) if (typeof reason === "string" && reason !== "") reasons[id] = reason;
|
|
93
|
-
return {
|
|
94
|
-
enabled: row.enabled === true,
|
|
95
|
-
capabilities,
|
|
96
|
-
...Object.keys(reasons).length === 0 ? {} : { reasons }
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Read the Host's connector state.
|
|
101
|
-
* @param route - connector route; overridable for tests.
|
|
102
|
-
* @returns the parsed state.
|
|
103
|
-
* @throws when the Host rejects the request.
|
|
104
|
-
*/
|
|
105
|
-
async function fetchConnectorState(route = CONNECTOR_ROUTE) {
|
|
106
|
-
const response = await fetch(route, { headers: { accept: "application/json" } });
|
|
107
|
-
if (!response.ok) throw new Error("连接器状态读取失败(" + String(response.status) + ")");
|
|
108
|
-
return parseConnectorState(await response.json());
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Write connector state through the Host.
|
|
112
|
-
* @param patch - the enabled flag and optional capability changes to merge.
|
|
113
|
-
* @param route - connector route; overridable for tests.
|
|
114
|
-
* @returns the state the Host persisted.
|
|
115
|
-
* @throws when the Host rejects the request.
|
|
116
|
-
*/
|
|
117
|
-
async function saveConnectorState(patch, route = CONNECTOR_ROUTE) {
|
|
118
|
-
const response = await fetch(route, {
|
|
119
|
-
method: "POST",
|
|
120
|
-
headers: {
|
|
121
|
-
accept: "application/json",
|
|
122
|
-
"content-type": "application/json"
|
|
123
|
-
},
|
|
124
|
-
body: JSON.stringify(patch)
|
|
125
|
-
});
|
|
126
|
-
if (!response.ok) throw new Error("连接器状态保存失败(" + String(response.status) + ")");
|
|
127
|
-
return parseConnectorState(await response.json());
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Project the capability rows the card renders.
|
|
131
|
-
* @param state - Host state.
|
|
132
|
-
* @returns one row per capability the account may use, in the Host's order.
|
|
133
|
-
*/
|
|
134
|
-
function visibleCapabilities(state) {
|
|
135
|
-
if (state === null) return [];
|
|
136
|
-
return Object.entries(state.capabilities).map(([id, enabled]) => {
|
|
137
|
-
const copy = CAPABILITY_COPY[id];
|
|
138
|
-
return {
|
|
139
|
-
id,
|
|
140
|
-
label: copy?.label ?? humanizeCapability(id),
|
|
141
|
-
...copy === void 0 ? {} : { description: copy.description },
|
|
142
|
-
enabled,
|
|
143
|
-
...state.reasons?.[id] === void 0 ? {} : { unavailableReason: state.reasons[id] }
|
|
144
|
-
};
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* The connector that produced a task row. MVP DataOps approval rows predate
|
|
149
|
-
* explicit ids, so their source type still identifies the built-in connector.
|
|
150
|
-
* @param task - one task row.
|
|
151
|
-
* @returns the connector id, or undefined for a generic Task Bus row.
|
|
152
|
-
*/
|
|
153
|
-
function taskConnectorId(task) {
|
|
154
|
-
if (task.connectorId !== void 0 && task.connectorId !== "") return task.connectorId;
|
|
155
|
-
return task.sourceType === "dataops_approval" ? CONNECTOR_ID : void 0;
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* The capability that produced a task row; an id-less DataOps approval row
|
|
159
|
-
* belongs to `approval.push`.
|
|
160
|
-
* @param task - one task row.
|
|
161
|
-
* @returns the capability id, or undefined for a generic Task Bus row.
|
|
162
|
-
*/
|
|
163
|
-
function taskCapabilityId(task) {
|
|
164
|
-
if (task.capabilityId !== void 0 && task.capabilityId !== "") return task.capabilityId;
|
|
165
|
-
return task.sourceType === "dataops_approval" ? "approval.push" : void 0;
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Filter rows for the connector tab.
|
|
169
|
-
* @param tasks - every loaded row.
|
|
170
|
-
* @param capabilityId - `all`, or the capability whose rows should remain.
|
|
171
|
-
* @returns rows produced by the built-in connector, narrowed to the capability.
|
|
172
|
-
*/
|
|
173
|
-
function filterConnectorTasks(tasks, capabilityId) {
|
|
174
|
-
return tasks.filter((task) => taskConnectorId(task) === "wanxiang-ai" && (capabilityId === "all" || taskCapabilityId(task) === capabilityId));
|
|
175
|
-
}
|
|
176
|
-
//#endregion
|
|
177
|
-
//#region src/client/ConnectorCard.tsx
|
|
178
|
-
/** Status label and tone for the card header. */
|
|
179
|
-
function statusOf(state, loading, error) {
|
|
180
|
-
if (loading && state === null) return {
|
|
181
|
-
label: "同步中",
|
|
182
|
-
tone: "neutral"
|
|
183
|
-
};
|
|
184
|
-
if (error !== null) return {
|
|
185
|
-
label: "连接异常",
|
|
186
|
-
tone: "danger"
|
|
187
|
-
};
|
|
188
|
-
if (state?.enabled !== true) return {
|
|
189
|
-
label: "未启用",
|
|
190
|
-
tone: "neutral"
|
|
191
|
-
};
|
|
192
|
-
return {
|
|
193
|
-
label: "已连接",
|
|
194
|
-
tone: "success"
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
|
-
/** Draw the connector glyph the card header carries. */
|
|
198
|
-
function ConnectorGlyph() {
|
|
199
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
200
|
-
width: "18",
|
|
201
|
-
height: "18",
|
|
202
|
-
viewBox: "0 0 24 24",
|
|
203
|
-
fill: "none",
|
|
204
|
-
stroke: "currentColor",
|
|
205
|
-
strokeWidth: "1.8",
|
|
206
|
-
strokeLinecap: "round",
|
|
207
|
-
strokeLinejoin: "round",
|
|
208
|
-
"aria-hidden": "true",
|
|
209
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M10 13a5 5 0 0 0 7.54.54l2-2a5 5 0 0 0-7.07-7.07l-1.15 1.15" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-2 2a5 5 0 0 0 7.07 7.07l1.15-1.15" })]
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Render the connector card.
|
|
214
|
-
* @param props - server state, write handlers, and the current task count.
|
|
215
|
-
* @returns the card.
|
|
216
|
-
*/
|
|
217
|
-
function ConnectorCard({ state, loading, error, busy, taskCount, onSetEnabled, onToggleCapability, onReload }) {
|
|
218
|
-
const status = statusOf(state, loading, error);
|
|
219
|
-
const enabled = state?.enabled === true;
|
|
220
|
-
const capabilities = visibleCapabilities(state);
|
|
221
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("article", {
|
|
222
|
-
"data-connector-card": CONNECTOR_NAME,
|
|
223
|
-
"data-connector-enabled": enabled,
|
|
224
|
-
style: {
|
|
225
|
-
width: "100%",
|
|
226
|
-
minWidth: 0,
|
|
227
|
-
border: "1px solid " + colors.line,
|
|
228
|
-
borderRadius: 12,
|
|
229
|
-
background: colors.panelAlt,
|
|
230
|
-
padding: 14,
|
|
231
|
-
display: "flex",
|
|
232
|
-
flexDirection: "column",
|
|
233
|
-
gap: 10
|
|
234
|
-
},
|
|
235
|
-
children: [
|
|
236
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
237
|
-
style: {
|
|
238
|
-
display: "flex",
|
|
239
|
-
alignItems: "center",
|
|
240
|
-
gap: 9
|
|
241
|
-
},
|
|
242
|
-
children: [
|
|
243
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
244
|
-
"aria-hidden": "true",
|
|
245
|
-
style: {
|
|
246
|
-
width: 32,
|
|
247
|
-
height: 32,
|
|
248
|
-
flex: "none",
|
|
249
|
-
borderRadius: 9,
|
|
250
|
-
background: "#2563eb",
|
|
251
|
-
color: "#fff",
|
|
252
|
-
display: "inline-flex",
|
|
253
|
-
alignItems: "center",
|
|
254
|
-
justifyContent: "center"
|
|
255
|
-
},
|
|
256
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConnectorGlyph, {})
|
|
257
|
-
}),
|
|
258
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
259
|
-
style: {
|
|
260
|
-
flex: 1,
|
|
261
|
-
minWidth: 0
|
|
262
|
-
},
|
|
263
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
264
|
-
style: {
|
|
265
|
-
fontSize: 13,
|
|
266
|
-
fontWeight: 700,
|
|
267
|
-
color: colors.text
|
|
268
|
-
},
|
|
269
|
-
children: CONNECTOR_NAME
|
|
270
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
271
|
-
style: {
|
|
272
|
-
marginTop: 2,
|
|
273
|
-
fontSize: 10,
|
|
274
|
-
color: colors.muted
|
|
275
|
-
},
|
|
276
|
-
children: "DataOps"
|
|
277
|
-
})]
|
|
278
|
-
}),
|
|
279
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, {
|
|
280
|
-
tone: status.tone,
|
|
281
|
-
children: status.label
|
|
282
|
-
})
|
|
283
|
-
]
|
|
284
|
-
}),
|
|
285
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
286
|
-
style: {
|
|
287
|
-
fontSize: 11,
|
|
288
|
-
lineHeight: 1.55,
|
|
289
|
-
color: colors.muted
|
|
290
|
-
},
|
|
291
|
-
children: "接收万相AI中台的审批任务"
|
|
292
|
-
}),
|
|
293
|
-
loading && state === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
294
|
-
style: {
|
|
295
|
-
fontSize: 11,
|
|
296
|
-
color: colors.muted
|
|
297
|
-
},
|
|
298
|
-
children: "正在读取连接器状态…"
|
|
299
|
-
}) : null,
|
|
300
|
-
error === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
301
|
-
role: "alert",
|
|
302
|
-
style: {
|
|
303
|
-
display: "flex",
|
|
304
|
-
alignItems: "center",
|
|
305
|
-
gap: 8,
|
|
306
|
-
fontSize: 11,
|
|
307
|
-
color: colors.danger
|
|
308
|
-
},
|
|
309
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
310
|
-
style: {
|
|
311
|
-
flex: 1,
|
|
312
|
-
minWidth: 0
|
|
313
|
-
},
|
|
314
|
-
children: error
|
|
315
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
316
|
-
size: "sm",
|
|
317
|
-
variant: "ghost",
|
|
318
|
-
disabled: loading,
|
|
319
|
-
onClick: onReload,
|
|
320
|
-
children: "重试"
|
|
321
|
-
})]
|
|
322
|
-
}),
|
|
323
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
324
|
-
style: {
|
|
325
|
-
display: "flex",
|
|
326
|
-
alignItems: "center",
|
|
327
|
-
justifyContent: "space-between",
|
|
328
|
-
gap: 10,
|
|
329
|
-
minHeight: 28
|
|
330
|
-
},
|
|
331
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
332
|
-
style: {
|
|
333
|
-
fontSize: 12,
|
|
334
|
-
color: colors.muted
|
|
335
|
-
},
|
|
336
|
-
children: enabled ? "已启用,任务中心只读取该连接器的任务" : "未启用,任务中心不读取外部任务"
|
|
337
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
338
|
-
checked: enabled,
|
|
339
|
-
disabled: busy || loading,
|
|
340
|
-
label: (enabled ? "停用 " : "启用 ") + CONNECTOR_NAME,
|
|
341
|
-
onChange: (next) => {
|
|
342
|
-
onSetEnabled(next);
|
|
343
|
-
}
|
|
344
|
-
})]
|
|
345
|
-
}),
|
|
346
|
-
enabled ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
347
|
-
"data-connector-capabilities": true,
|
|
348
|
-
style: {
|
|
349
|
-
borderTop: "1px solid " + colors.line,
|
|
350
|
-
paddingTop: 8,
|
|
351
|
-
display: "grid",
|
|
352
|
-
gap: 2
|
|
353
|
-
},
|
|
354
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
355
|
-
style: {
|
|
356
|
-
fontSize: 10,
|
|
357
|
-
color: colors.muted
|
|
358
|
-
},
|
|
359
|
-
children: "能力"
|
|
360
|
-
}), capabilities.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
361
|
-
style: {
|
|
362
|
-
fontSize: 11,
|
|
363
|
-
color: colors.muted,
|
|
364
|
-
padding: "6px 0"
|
|
365
|
-
},
|
|
366
|
-
children: "当前账号没有可用的连接器能力,请联系管理员开通"
|
|
367
|
-
}) : capabilities.map((capability) => {
|
|
368
|
-
const unavailable = capability.unavailableReason !== void 0;
|
|
369
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
370
|
-
"data-capability-id": capability.id,
|
|
371
|
-
"data-capability-enabled": capability.enabled,
|
|
372
|
-
style: {
|
|
373
|
-
display: "flex",
|
|
374
|
-
alignItems: "center",
|
|
375
|
-
gap: 10,
|
|
376
|
-
minHeight: 40,
|
|
377
|
-
padding: "4px 0",
|
|
378
|
-
borderTop: "1px solid " + colors.line
|
|
379
|
-
},
|
|
380
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
381
|
-
style: {
|
|
382
|
-
flex: 1,
|
|
383
|
-
minWidth: 0
|
|
384
|
-
},
|
|
385
|
-
children: [
|
|
386
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
387
|
-
style: {
|
|
388
|
-
fontSize: 12,
|
|
389
|
-
color: colors.text
|
|
390
|
-
},
|
|
391
|
-
children: capability.label
|
|
392
|
-
}),
|
|
393
|
-
capability.description === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
394
|
-
style: {
|
|
395
|
-
marginTop: 1,
|
|
396
|
-
fontSize: 10,
|
|
397
|
-
color: colors.muted
|
|
398
|
-
},
|
|
399
|
-
children: capability.description
|
|
400
|
-
}),
|
|
401
|
-
capability.unavailableReason === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
402
|
-
style: {
|
|
403
|
-
marginTop: 2,
|
|
404
|
-
fontSize: 10,
|
|
405
|
-
color: colors.warning
|
|
406
|
-
},
|
|
407
|
-
children: ["暂不可用 · ", capability.unavailableReason]
|
|
408
|
-
})
|
|
409
|
-
]
|
|
410
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Switch, {
|
|
411
|
-
checked: capability.enabled,
|
|
412
|
-
disabled: busy || unavailable,
|
|
413
|
-
label: (capability.enabled ? "停用 " : "启用 ") + capability.label,
|
|
414
|
-
onChange: (next) => {
|
|
415
|
-
onToggleCapability(capability.id, next);
|
|
416
|
-
}
|
|
417
|
-
})]
|
|
418
|
-
}, capability.id);
|
|
419
|
-
})]
|
|
420
|
-
}) : null,
|
|
421
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
422
|
-
style: {
|
|
423
|
-
display: "flex",
|
|
424
|
-
alignItems: "center",
|
|
425
|
-
justifyContent: "space-between",
|
|
426
|
-
gap: 8,
|
|
427
|
-
marginTop: "auto",
|
|
428
|
-
fontSize: 10,
|
|
429
|
-
color: colors.muted
|
|
430
|
-
},
|
|
431
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: enabled ? "该连接器任务 " + String(taskCount) + " 条" : "启用后在此查看连接器任务" }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
432
|
-
size: "sm",
|
|
433
|
-
variant: "ghost",
|
|
434
|
-
disabled: loading,
|
|
435
|
-
onClick: onReload,
|
|
436
|
-
children: "刷新状态"
|
|
437
|
-
})]
|
|
438
|
-
})
|
|
439
|
-
]
|
|
440
|
-
});
|
|
441
|
-
}
|
|
442
|
-
/**
|
|
443
|
-
* The disabled connector's empty state, with the one path that can enable it.
|
|
444
|
-
* @param props.onOpenSkillCenter - select the skill center's connector tab.
|
|
445
|
-
* @returns the empty state.
|
|
446
|
-
*/
|
|
447
|
-
function ConnectorDisabledState({ onOpenSkillCenter }) {
|
|
448
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
449
|
-
"data-connector-disabled-state": true,
|
|
450
|
-
style: {
|
|
451
|
-
display: "grid",
|
|
452
|
-
justifyItems: "center",
|
|
453
|
-
gap: 8,
|
|
454
|
-
padding: "36px 20px 40px",
|
|
455
|
-
color: colors.muted,
|
|
456
|
-
textAlign: "center"
|
|
457
|
-
},
|
|
458
|
-
children: [
|
|
459
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
460
|
-
style: {
|
|
461
|
-
display: "inline-flex",
|
|
462
|
-
width: 36,
|
|
463
|
-
height: 36,
|
|
464
|
-
alignItems: "center",
|
|
465
|
-
justifyContent: "center",
|
|
466
|
-
borderRadius: 18,
|
|
467
|
-
background: colors.panelAlt,
|
|
468
|
-
color: colors.muted
|
|
469
|
-
},
|
|
470
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConnectorGlyph, {})
|
|
471
|
-
}),
|
|
472
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
473
|
-
style: {
|
|
474
|
-
fontSize: 13,
|
|
475
|
-
fontWeight: 600,
|
|
476
|
-
color: colors.text
|
|
477
|
-
},
|
|
478
|
-
children: "连接器未启用"
|
|
479
|
-
}),
|
|
480
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
481
|
-
style: {
|
|
482
|
-
maxWidth: 380,
|
|
483
|
-
fontSize: 12,
|
|
484
|
-
lineHeight: 1.6
|
|
485
|
-
},
|
|
486
|
-
children: [
|
|
487
|
-
"在技能中心的连接器页面启用「",
|
|
488
|
-
CONNECTOR_NAME,
|
|
489
|
-
"」后,这里会显示它接收的审批任务。"
|
|
490
|
-
]
|
|
491
|
-
}),
|
|
492
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
493
|
-
size: "sm",
|
|
494
|
-
variant: "outline",
|
|
495
|
-
onClick: onOpenSkillCenter,
|
|
496
|
-
children: "前往技能中心启用"
|
|
497
|
-
})
|
|
498
|
-
]
|
|
499
|
-
});
|
|
500
|
-
}
|
|
501
|
-
//#endregion
|
|
502
25
|
//#region src/client/index.tsx
|
|
503
26
|
/**
|
|
504
27
|
* The Task Center surface in the frame-wide overlay.
|
|
@@ -512,8 +35,7 @@ window.__ModuleLoader__.load({
|
|
|
512
35
|
"locale",
|
|
513
36
|
"uiWorkspace",
|
|
514
37
|
"sessions",
|
|
515
|
-
"sidebarRight"
|
|
516
|
-
"layout"
|
|
38
|
+
"sidebarRight"
|
|
517
39
|
];
|
|
518
40
|
const ROUTE = "/dsh-task-bus/api";
|
|
519
41
|
const TASK_BUS_MODAL_CLASS = "task-bus-center-modal";
|
|
@@ -585,26 +107,7 @@ window.__ModuleLoader__.load({
|
|
|
585
107
|
dateLocale: "en-US"
|
|
586
108
|
}
|
|
587
109
|
};
|
|
588
|
-
|
|
589
|
-
border: "1px solid " + colors.line,
|
|
590
|
-
background: colors.panel,
|
|
591
|
-
color: colors.text,
|
|
592
|
-
borderRadius: 8,
|
|
593
|
-
padding: "7px 11px",
|
|
594
|
-
fontSize: 12,
|
|
595
|
-
cursor: "pointer"
|
|
596
|
-
};
|
|
597
|
-
/** Capability filter chip; the active chip keeps the accent fill and stroke. */
|
|
598
|
-
const filterChipStyle = (active) => ({
|
|
599
|
-
padding: "4px 10px",
|
|
600
|
-
borderRadius: 999,
|
|
601
|
-
border: "1px solid " + (active ? colors.accent : colors.line),
|
|
602
|
-
background: active ? colors.accentSoft : "transparent",
|
|
603
|
-
color: active ? colors.accent : colors.muted,
|
|
604
|
-
fontSize: 11,
|
|
605
|
-
lineHeight: 1.6,
|
|
606
|
-
cursor: "pointer"
|
|
607
|
-
});
|
|
110
|
+
"" + colors.line, colors.panel, colors.text;
|
|
608
111
|
const statusTagTone = (status) => {
|
|
609
112
|
if (status === "completed") return "success";
|
|
610
113
|
if (status === "cancelled") return "neutral";
|
|
@@ -1196,7 +699,7 @@ window.__ModuleLoader__.load({
|
|
|
1196
699
|
]
|
|
1197
700
|
});
|
|
1198
701
|
};
|
|
1199
|
-
const TaskCenterButton = ({ openSession
|
|
702
|
+
const TaskCenterButton = ({ openSession }) => {
|
|
1200
703
|
const [open, setOpen] = (0, react.useState)(false);
|
|
1201
704
|
const [tasks, setTasks] = (0, react.useState)([]);
|
|
1202
705
|
const [loading, setLoading] = (0, react.useState)(false);
|
|
@@ -1204,20 +707,9 @@ window.__ModuleLoader__.load({
|
|
|
1204
707
|
const [tab, setTab] = (0, react.useState)("all");
|
|
1205
708
|
const [busyId, setBusyId] = (0, react.useState)(null);
|
|
1206
709
|
const [aiBusyId, setAiBusyId] = (0, react.useState)(null);
|
|
1207
|
-
const [creating, setCreating] = (0, react.useState)(false);
|
|
1208
|
-
const [draftTitle, setDraftTitle] = (0, react.useState)("");
|
|
1209
|
-
const [draftSource, setDraftSource] = (0, react.useState)("manual");
|
|
1210
|
-
const [createBusy, setCreateBusy] = (0, react.useState)(false);
|
|
1211
710
|
const [selected, setSelected] = (0, react.useState)(null);
|
|
1212
711
|
const [anchor, setAnchor] = (0, react.useState)(null);
|
|
1213
|
-
const [connector, setConnector] = (0, react.useState)(null);
|
|
1214
|
-
const [connectorLoading, setConnectorLoading] = (0, react.useState)(true);
|
|
1215
|
-
const [connectorError, setConnectorError] = (0, react.useState)(null);
|
|
1216
|
-
const [connectorBusy, setConnectorBusy] = (0, react.useState)(false);
|
|
1217
|
-
const [capabilityFilter, setCapabilityFilter] = (0, react.useState)("all");
|
|
1218
|
-
const [skillCenterError, setSkillCenterError] = (0, react.useState)(null);
|
|
1219
712
|
const [pendingCount, setPendingCount] = (0, react.useState)(0);
|
|
1220
|
-
const connectorEnabled = connector?.enabled === true;
|
|
1221
713
|
(0, react.useEffect)(() => {
|
|
1222
714
|
if (document.getElementById(TASK_BUS_STYLE_ID) !== null) return;
|
|
1223
715
|
const style = document.createElement("style");
|
|
@@ -1260,39 +752,7 @@ window.__ModuleLoader__.load({
|
|
|
1260
752
|
window.removeEventListener("resize", update);
|
|
1261
753
|
};
|
|
1262
754
|
}, []);
|
|
1263
|
-
const readConnector = async () => {
|
|
1264
|
-
setConnectorLoading(true);
|
|
1265
|
-
setConnectorError(null);
|
|
1266
|
-
try {
|
|
1267
|
-
setConnector(await fetchConnectorState());
|
|
1268
|
-
} catch (cause) {
|
|
1269
|
-
setConnectorError(cause instanceof Error ? cause.message : String(cause));
|
|
1270
|
-
} finally {
|
|
1271
|
-
setConnectorLoading(false);
|
|
1272
|
-
}
|
|
1273
|
-
};
|
|
1274
|
-
(0, react.useEffect)(() => {
|
|
1275
|
-
let alive = true;
|
|
1276
|
-
setConnectorLoading(true);
|
|
1277
|
-
setConnectorError(null);
|
|
1278
|
-
fetchConnectorState().then((next) => {
|
|
1279
|
-
if (alive) setConnector(next);
|
|
1280
|
-
}).catch((cause) => {
|
|
1281
|
-
if (alive) setConnectorError(cause instanceof Error ? cause.message : String(cause));
|
|
1282
|
-
}).finally(() => {
|
|
1283
|
-
if (alive) setConnectorLoading(false);
|
|
1284
|
-
});
|
|
1285
|
-
return () => {
|
|
1286
|
-
alive = false;
|
|
1287
|
-
};
|
|
1288
|
-
}, []);
|
|
1289
755
|
const load = async (silent = false) => {
|
|
1290
|
-
if (!connectorEnabled) {
|
|
1291
|
-
setTasks([]);
|
|
1292
|
-
setLoading(false);
|
|
1293
|
-
setError(null);
|
|
1294
|
-
return;
|
|
1295
|
-
}
|
|
1296
756
|
if (!silent) setLoading(true);
|
|
1297
757
|
setError(null);
|
|
1298
758
|
try {
|
|
@@ -1304,53 +764,8 @@ window.__ModuleLoader__.load({
|
|
|
1304
764
|
if (!silent) setLoading(false);
|
|
1305
765
|
}
|
|
1306
766
|
};
|
|
1307
|
-
const setConnectorEnabled = async (enabled) => {
|
|
1308
|
-
setConnectorBusy(true);
|
|
1309
|
-
setConnectorError(null);
|
|
1310
|
-
try {
|
|
1311
|
-
setConnector(await saveConnectorState({ enabled }));
|
|
1312
|
-
if (!enabled) {
|
|
1313
|
-
setTasks([]);
|
|
1314
|
-
setCapabilityFilter("all");
|
|
1315
|
-
}
|
|
1316
|
-
} catch (cause) {
|
|
1317
|
-
setConnectorError(cause instanceof Error ? cause.message : String(cause));
|
|
1318
|
-
} finally {
|
|
1319
|
-
setConnectorBusy(false);
|
|
1320
|
-
}
|
|
1321
|
-
};
|
|
1322
|
-
const toggleCapability = async (capabilityId, enabled) => {
|
|
1323
|
-
if (connector === null) return;
|
|
1324
|
-
setConnectorBusy(true);
|
|
1325
|
-
setConnectorError(null);
|
|
1326
|
-
try {
|
|
1327
|
-
setConnector(await saveConnectorState({
|
|
1328
|
-
enabled: connector.enabled,
|
|
1329
|
-
capabilities: { [capabilityId]: enabled }
|
|
1330
|
-
}));
|
|
1331
|
-
} catch (cause) {
|
|
1332
|
-
setConnectorError(cause instanceof Error ? cause.message : String(cause));
|
|
1333
|
-
} finally {
|
|
1334
|
-
setConnectorBusy(false);
|
|
1335
|
-
}
|
|
1336
|
-
};
|
|
1337
|
-
const openSkillCenterFromPanel = () => {
|
|
1338
|
-
if (openSkillCenter()) {
|
|
1339
|
-
setSkillCenterError(null);
|
|
1340
|
-
setOpen(false);
|
|
1341
|
-
return;
|
|
1342
|
-
}
|
|
1343
|
-
setSkillCenterError("技能中心未安装,无法打开连接器页面");
|
|
1344
|
-
};
|
|
1345
767
|
(0, react.useEffect)(() => {
|
|
1346
768
|
if (!open) return;
|
|
1347
|
-
if (!connectorEnabled) {
|
|
1348
|
-
setTab("connectors");
|
|
1349
|
-
setTasks([]);
|
|
1350
|
-
setError(null);
|
|
1351
|
-
setLoading(false);
|
|
1352
|
-
return;
|
|
1353
|
-
}
|
|
1354
769
|
load();
|
|
1355
770
|
const timer = window.setInterval(() => {
|
|
1356
771
|
load(true);
|
|
@@ -1358,12 +773,8 @@ window.__ModuleLoader__.load({
|
|
|
1358
773
|
return () => {
|
|
1359
774
|
window.clearInterval(timer);
|
|
1360
775
|
};
|
|
1361
|
-
}, [open
|
|
776
|
+
}, [open]);
|
|
1362
777
|
(0, react.useEffect)(() => {
|
|
1363
|
-
if (!connectorEnabled) {
|
|
1364
|
-
setPendingCount(0);
|
|
1365
|
-
return;
|
|
1366
|
-
}
|
|
1367
778
|
let alive = true;
|
|
1368
779
|
const refresh = async () => {
|
|
1369
780
|
try {
|
|
@@ -1379,19 +790,13 @@ window.__ModuleLoader__.load({
|
|
|
1379
790
|
alive = false;
|
|
1380
791
|
window.clearInterval(timer);
|
|
1381
792
|
};
|
|
1382
|
-
}, [
|
|
793
|
+
}, []);
|
|
1383
794
|
const filtered = (0, react.useMemo)(() => {
|
|
1384
|
-
if (tab === "connectors") return connectorEnabled ? filterConnectorTasks(tasks, capabilityFilter) : [];
|
|
1385
795
|
if (tab === "group") return tasks.filter((task) => task.sourceType === "task_bus" && task.source.type.includes("group"));
|
|
1386
796
|
if (tab === "mine") return tasks.filter((task) => task.status !== "completed" && task.status !== "cancelled");
|
|
1387
797
|
if (tab === "personal") return tasks.filter((task) => task.sourceType === "task_bus" && !task.source.type.includes("group"));
|
|
1388
798
|
return tasks;
|
|
1389
|
-
}, [
|
|
1390
|
-
tasks,
|
|
1391
|
-
tab,
|
|
1392
|
-
connectorEnabled,
|
|
1393
|
-
capabilityFilter
|
|
1394
|
-
]);
|
|
799
|
+
}, [tasks, tab]);
|
|
1395
800
|
const actionable = tasks.filter((task) => task.status !== "completed" && task.status !== "cancelled").length;
|
|
1396
801
|
const tabItems = [
|
|
1397
802
|
{
|
|
@@ -1429,15 +834,6 @@ window.__ModuleLoader__.load({
|
|
|
1429
834
|
style: { opacity: .55 },
|
|
1430
835
|
children: tasks.filter((task) => task.sourceType === "task_bus" && task.source.type.includes("group")).length
|
|
1431
836
|
})] })
|
|
1432
|
-
},
|
|
1433
|
-
{
|
|
1434
|
-
value: "connectors",
|
|
1435
|
-
id: "task-bus-tab-connectors",
|
|
1436
|
-
panelId: "task-bus-panel-connectors",
|
|
1437
|
-
label: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: ["连接器 ", /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1438
|
-
style: { opacity: .55 },
|
|
1439
|
-
children: connector === null ? 0 : 1
|
|
1440
|
-
})] })
|
|
1441
837
|
}
|
|
1442
838
|
];
|
|
1443
839
|
const transition = async (task, action) => {
|
|
@@ -1461,31 +857,6 @@ window.__ModuleLoader__.load({
|
|
|
1461
857
|
setBusyId(null);
|
|
1462
858
|
}
|
|
1463
859
|
};
|
|
1464
|
-
const createTask = async () => {
|
|
1465
|
-
const title = draftTitle.trim();
|
|
1466
|
-
if (!title) return;
|
|
1467
|
-
setCreateBusy(true);
|
|
1468
|
-
setError(null);
|
|
1469
|
-
try {
|
|
1470
|
-
const response = await fetch(ROUTE + "/generic", {
|
|
1471
|
-
method: "POST",
|
|
1472
|
-
headers: { "content-type": "application/json" },
|
|
1473
|
-
body: JSON.stringify({
|
|
1474
|
-
title,
|
|
1475
|
-
sourceType: draftSource
|
|
1476
|
-
})
|
|
1477
|
-
});
|
|
1478
|
-
const payload = await response.json();
|
|
1479
|
-
if (!response.ok) throw new Error(payload.error ?? "创建任务失败");
|
|
1480
|
-
setDraftTitle("");
|
|
1481
|
-
setCreating(false);
|
|
1482
|
-
await load();
|
|
1483
|
-
} catch (cause) {
|
|
1484
|
-
setError(cause instanceof Error ? cause.message : String(cause));
|
|
1485
|
-
} finally {
|
|
1486
|
-
setCreateBusy(false);
|
|
1487
|
-
}
|
|
1488
|
-
};
|
|
1489
860
|
const aiAccept = async (task) => {
|
|
1490
861
|
setAiBusyId(task.id);
|
|
1491
862
|
setError(null);
|
|
@@ -1596,13 +967,6 @@ window.__ModuleLoader__.load({
|
|
|
1596
967
|
children: "任务中心"
|
|
1597
968
|
})
|
|
1598
969
|
}),
|
|
1599
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1600
|
-
size: "sm",
|
|
1601
|
-
variant: "outline",
|
|
1602
|
-
disabled: !connectorEnabled,
|
|
1603
|
-
onClick: () => setCreating((value) => !value),
|
|
1604
|
-
children: "新建"
|
|
1605
|
-
}),
|
|
1606
970
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1607
971
|
size: "sm",
|
|
1608
972
|
variant: "ghost",
|
|
@@ -1635,69 +999,6 @@ window.__ModuleLoader__.load({
|
|
|
1635
999
|
label: "任务中心分类"
|
|
1636
1000
|
})
|
|
1637
1001
|
}),
|
|
1638
|
-
creating ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1639
|
-
style: {
|
|
1640
|
-
margin: "0 24px 12px",
|
|
1641
|
-
padding: 12,
|
|
1642
|
-
border: "1px solid " + colors.line,
|
|
1643
|
-
borderRadius: 9,
|
|
1644
|
-
display: "grid",
|
|
1645
|
-
gap: 7
|
|
1646
|
-
},
|
|
1647
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
1648
|
-
value: draftTitle,
|
|
1649
|
-
onChange: (event) => setDraftTitle(event.target.value),
|
|
1650
|
-
placeholder: "任务标题,例如:整理演示材料",
|
|
1651
|
-
autoFocus: true,
|
|
1652
|
-
style: {
|
|
1653
|
-
...buttonStyle,
|
|
1654
|
-
cursor: "text",
|
|
1655
|
-
padding: "7px 9px"
|
|
1656
|
-
}
|
|
1657
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1658
|
-
style: {
|
|
1659
|
-
display: "flex",
|
|
1660
|
-
gap: 6
|
|
1661
|
-
},
|
|
1662
|
-
children: [
|
|
1663
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
1664
|
-
value: draftSource,
|
|
1665
|
-
onChange: (event) => setDraftSource(event.target.value),
|
|
1666
|
-
style: {
|
|
1667
|
-
...buttonStyle,
|
|
1668
|
-
padding: "6px 8px"
|
|
1669
|
-
},
|
|
1670
|
-
children: [
|
|
1671
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1672
|
-
value: "manual",
|
|
1673
|
-
children: "手工任务"
|
|
1674
|
-
}),
|
|
1675
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1676
|
-
value: "session",
|
|
1677
|
-
children: "会话任务"
|
|
1678
|
-
}),
|
|
1679
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
1680
|
-
value: "group",
|
|
1681
|
-
children: "群聊任务"
|
|
1682
|
-
})
|
|
1683
|
-
]
|
|
1684
|
-
}),
|
|
1685
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1686
|
-
size: "sm",
|
|
1687
|
-
variant: "primary",
|
|
1688
|
-
disabled: createBusy || draftTitle.trim() === "",
|
|
1689
|
-
onClick: () => void createTask(),
|
|
1690
|
-
children: createBusy ? "创建中…" : "创建"
|
|
1691
|
-
}),
|
|
1692
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1693
|
-
size: "sm",
|
|
1694
|
-
variant: "ghost",
|
|
1695
|
-
onClick: () => setCreating(false),
|
|
1696
|
-
children: "取消"
|
|
1697
|
-
})
|
|
1698
|
-
]
|
|
1699
|
-
})]
|
|
1700
|
-
}) : null,
|
|
1701
1002
|
error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1702
1003
|
style: {
|
|
1703
1004
|
padding: "8px 10px",
|
|
@@ -1725,59 +1026,6 @@ window.__ModuleLoader__.load({
|
|
|
1725
1026
|
task: selected,
|
|
1726
1027
|
onBack: () => setSelected(null)
|
|
1727
1028
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
1728
|
-
tab === "connectors" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1729
|
-
style: {
|
|
1730
|
-
display: "grid",
|
|
1731
|
-
gridTemplateColumns: "repeat(auto-fill, minmax(320px, 1fr))",
|
|
1732
|
-
gap: 10
|
|
1733
|
-
},
|
|
1734
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConnectorCard, {
|
|
1735
|
-
state: connector,
|
|
1736
|
-
loading: connectorLoading,
|
|
1737
|
-
error: connectorError,
|
|
1738
|
-
busy: connectorBusy,
|
|
1739
|
-
taskCount: filtered.length,
|
|
1740
|
-
onSetEnabled: (enabled) => {
|
|
1741
|
-
setConnectorEnabled(enabled);
|
|
1742
|
-
},
|
|
1743
|
-
onToggleCapability: (capabilityId, enabled) => {
|
|
1744
|
-
toggleCapability(capabilityId, enabled);
|
|
1745
|
-
},
|
|
1746
|
-
onReload: () => {
|
|
1747
|
-
readConnector();
|
|
1748
|
-
}
|
|
1749
|
-
})
|
|
1750
|
-
}), connectorEnabled ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1751
|
-
role: "group",
|
|
1752
|
-
"aria-label": "连接器能力筛选",
|
|
1753
|
-
style: {
|
|
1754
|
-
display: "flex",
|
|
1755
|
-
flexWrap: "wrap",
|
|
1756
|
-
gap: 6
|
|
1757
|
-
},
|
|
1758
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1759
|
-
type: "button",
|
|
1760
|
-
"aria-pressed": capabilityFilter === "all",
|
|
1761
|
-
onClick: () => setCapabilityFilter("all"),
|
|
1762
|
-
style: filterChipStyle(capabilityFilter === "all"),
|
|
1763
|
-
children: "全部"
|
|
1764
|
-
}), visibleCapabilities(connector).map((capability) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1765
|
-
type: "button",
|
|
1766
|
-
"data-capability-filter": capability.id,
|
|
1767
|
-
"aria-pressed": capabilityFilter === capability.id,
|
|
1768
|
-
onClick: () => setCapabilityFilter(capability.id),
|
|
1769
|
-
style: filterChipStyle(capabilityFilter === capability.id),
|
|
1770
|
-
children: capability.label
|
|
1771
|
-
}, capability.id))]
|
|
1772
|
-
}) : connectorLoading ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConnectorDisabledState, { onOpenSkillCenter: openSkillCenterFromPanel }), skillCenterError === null ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1773
|
-
role: "alert",
|
|
1774
|
-
style: {
|
|
1775
|
-
textAlign: "center",
|
|
1776
|
-
color: colors.danger,
|
|
1777
|
-
fontSize: 11
|
|
1778
|
-
},
|
|
1779
|
-
children: skillCenterError
|
|
1780
|
-
})] })] }) : null,
|
|
1781
1029
|
loading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1782
1030
|
style: {
|
|
1783
1031
|
padding: 18,
|
|
@@ -1787,7 +1035,7 @@ window.__ModuleLoader__.load({
|
|
|
1787
1035
|
},
|
|
1788
1036
|
children: "正在加载…"
|
|
1789
1037
|
}) : null,
|
|
1790
|
-
!loading &&
|
|
1038
|
+
!loading && filtered.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1791
1039
|
style: {
|
|
1792
1040
|
padding: 18,
|
|
1793
1041
|
textAlign: "center",
|
|
@@ -1796,22 +1044,6 @@ window.__ModuleLoader__.load({
|
|
|
1796
1044
|
},
|
|
1797
1045
|
children: "暂无任务"
|
|
1798
1046
|
}) : null,
|
|
1799
|
-
!loading && tab === "connectors" && connectorEnabled && filtered.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1800
|
-
style: {
|
|
1801
|
-
padding: 18,
|
|
1802
|
-
textAlign: "center",
|
|
1803
|
-
color: colors.muted,
|
|
1804
|
-
fontSize: 12
|
|
1805
|
-
},
|
|
1806
|
-
children: capabilityFilter === "all" ? "暂无来自该连接器的任务" : "该能力下暂无任务"
|
|
1807
|
-
}) : null,
|
|
1808
|
-
!loading && tab === "connectors" && filtered.length > 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1809
|
-
style: {
|
|
1810
|
-
fontSize: 10,
|
|
1811
|
-
color: colors.muted
|
|
1812
|
-
},
|
|
1813
|
-
children: "来自该连接器的任务"
|
|
1814
|
-
}) : null,
|
|
1815
1047
|
!loading && filtered.map((task) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TaskCard, {
|
|
1816
1048
|
task,
|
|
1817
1049
|
busy: busyId === task.id,
|
|
@@ -1941,6 +1173,35 @@ window.__ModuleLoader__.load({
|
|
|
1941
1173
|
reference.release?.();
|
|
1942
1174
|
}
|
|
1943
1175
|
};
|
|
1176
|
+
/**
|
|
1177
|
+
* The design system's standard 16-unit clock glyph, drawn locally.
|
|
1178
|
+
*
|
|
1179
|
+
* The client primitives package this runtime serves (0.2.2-alpha.2) exports
|
|
1180
|
+
* `IconClockOutline`, `IconClockOutlineRegular`, and `IconClockOutlineMedium`,
|
|
1181
|
+
* not the newer `IconClockOutline16` name. A missing named export resolves to
|
|
1182
|
+
* `undefined`, so importing it crashed this header slot with React error #130
|
|
1183
|
+
* and removed the button entirely; the standard geometry is inlined instead.
|
|
1184
|
+
*/
|
|
1185
|
+
const MessageHistoryIcon = ({ size = 16 }) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("svg", {
|
|
1186
|
+
width: size,
|
|
1187
|
+
height: size,
|
|
1188
|
+
viewBox: "0 0 16 16",
|
|
1189
|
+
fill: "none",
|
|
1190
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
1191
|
+
"aria-hidden": "true",
|
|
1192
|
+
strokeWidth: "1.5",
|
|
1193
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("circle", {
|
|
1194
|
+
cx: "8",
|
|
1195
|
+
cy: "8",
|
|
1196
|
+
r: "6.375",
|
|
1197
|
+
stroke: "currentColor"
|
|
1198
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
1199
|
+
d: "M8 4.4V8.3L10.7 9.85",
|
|
1200
|
+
stroke: "currentColor",
|
|
1201
|
+
strokeLinecap: "round",
|
|
1202
|
+
strokeLinejoin: "round"
|
|
1203
|
+
})]
|
|
1204
|
+
});
|
|
1944
1205
|
const HistoryButton = ({ sessionId, sessions, t }) => {
|
|
1945
1206
|
const [open, setOpen] = (0, react.useState)(false);
|
|
1946
1207
|
const [entries, setEntries] = (0, react.useState)([]);
|
|
@@ -2033,7 +1294,7 @@ window.__ModuleLoader__.load({
|
|
|
2033
1294
|
color: "inherit",
|
|
2034
1295
|
cursor: "pointer"
|
|
2035
1296
|
},
|
|
2036
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1297
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MessageHistoryIcon, { size: 16 })
|
|
2037
1298
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
2038
1299
|
open,
|
|
2039
1300
|
onClose: () => setOpen(false),
|
|
@@ -2131,7 +1392,7 @@ window.__ModuleLoader__.load({
|
|
|
2131
1392
|
background: colors.panelAlt,
|
|
2132
1393
|
color: colors.muted
|
|
2133
1394
|
},
|
|
2134
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1395
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MessageHistoryIcon, { size: 16 })
|
|
2135
1396
|
}),
|
|
2136
1397
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2137
1398
|
style: {
|
|
@@ -2258,18 +1519,7 @@ window.__ModuleLoader__.load({
|
|
|
2258
1519
|
document.removeEventListener("click", onFileClick, true);
|
|
2259
1520
|
};
|
|
2260
1521
|
}, "task-bus: native file card preview");
|
|
2261
|
-
const
|
|
2262
|
-
try {
|
|
2263
|
-
surface.layout.selectPanel("skill-center");
|
|
2264
|
-
return true;
|
|
2265
|
-
} catch {
|
|
2266
|
-
return false;
|
|
2267
|
-
}
|
|
2268
|
-
};
|
|
2269
|
-
const Surface = () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TaskCenterButton, {
|
|
2270
|
-
openSession: (sessionId) => surface.uiWorkspace.openSession(sessionId),
|
|
2271
|
-
openSkillCenter
|
|
2272
|
-
});
|
|
1522
|
+
const Surface = () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TaskCenterButton, { openSession: (sessionId) => surface.uiWorkspace.openSession(sessionId) });
|
|
2273
1523
|
ctx.effect(() => surface.slots.inject("shell.overlay", () => surface.slots.register({
|
|
2274
1524
|
name: "shell.overlay",
|
|
2275
1525
|
id: "task-bus.center"
|
|
@@ -2277,7 +1527,7 @@ window.__ModuleLoader__.load({
|
|
|
2277
1527
|
ctx.effect(() => {
|
|
2278
1528
|
const style = document.createElement("style");
|
|
2279
1529
|
style.id = "task-bus-history-replaces-file-manager";
|
|
2280
|
-
style.textContent = "
|
|
1530
|
+
style.textContent = ["[data-slot=\"conversation.session.header.utilities\"] > *:has([data-open-target]) { display: none !important; }", "[data-message-attachments] > * { cursor: pointer; }"].join("\n");
|
|
2281
1531
|
document.head.appendChild(style);
|
|
2282
1532
|
return () => {
|
|
2283
1533
|
style.remove();
|