@antv/dumi-theme-antv 0.8.0-beta.13 → 0.8.0-beta.15
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/AI/HomeDialog/RecommendCase/index.js +48 -42
- package/dist/components/AI/HomeDialog/index.js +2 -1
- package/dist/locales/en.json +6 -1
- package/dist/locales/zh.json +6 -1
- package/dist/model/AIChat.js +28 -5
- package/dist/pages/AIPlayground/components/ConversationsMenu/index.js +7 -1
- package/dist/pages/AIPlayground/components/MsgBox/index.js +76 -9
- package/dist/pages/AIPlayground/components/SessionLayout/index.js +2 -1
- package/dist/pages/AIPlayground/components/SessionLayout/index.module.less +2 -1
- package/dist/pages/AIPlayground/components/TaskBox/generateCode.js +89 -11
- package/dist/pages/AIPlayground/components/TaskBox/index.js +12 -3
- package/dist/pages/AIPlayground/index.js +4 -1
- package/dist/pages/AIPlayground/index.module.less +5 -0
- package/dist/slots/Header/Search/SearchResult.js +4 -2
- package/dist/slots/Header/index.js +3 -21
- package/dist/utils/analytics.js +16 -0
- package/package.json +1 -1
|
@@ -9,7 +9,7 @@ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len
|
|
|
9
9
|
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
10
10
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
11
11
|
import { Spin } from 'antd';
|
|
12
|
-
import React, {
|
|
12
|
+
import React, { useEffect, useState } from 'react';
|
|
13
13
|
import { Card } from "./Card";
|
|
14
14
|
import styles from "./index.module.less";
|
|
15
15
|
import { ReloadOutlined } from "@ant-design/icons";
|
|
@@ -27,54 +27,60 @@ export var RecommendCase = function RecommendCase(props) {
|
|
|
27
27
|
setLoading = _useState2[1];
|
|
28
28
|
var _useSiteData = useSiteData(),
|
|
29
29
|
themeConfig = _useSiteData.themeConfig;
|
|
30
|
-
var _useState3 = useState(
|
|
30
|
+
var _useState3 = useState([]),
|
|
31
31
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
32
32
|
list = _useState4[0],
|
|
33
33
|
setList = _useState4[1];
|
|
34
34
|
var _useLibrary = useLibrary(),
|
|
35
35
|
_useLibrary$data = _useLibrary.data,
|
|
36
36
|
library = _useLibrary$data === void 0 ? [] : _useLibrary$data;
|
|
37
|
-
var fetchList =
|
|
38
|
-
var
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
37
|
+
var fetchList = /*#__PURE__*/function () {
|
|
38
|
+
var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
|
|
39
|
+
var _themeConfig$ai, data, url;
|
|
40
|
+
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
41
|
+
while (1) switch (_context.prev = _context.next) {
|
|
42
|
+
case 0:
|
|
43
|
+
_context.prev = 0;
|
|
44
|
+
setLoading(true);
|
|
45
|
+
data = [];
|
|
46
|
+
url = themeConfig.isAntVSite && library.length ? "".concat(getBaseSiteDataUrl(), "/").concat(sample(library).toLowerCase(), "/recommend.json") : (themeConfig === null || themeConfig === void 0 || (_themeConfig$ai = themeConfig.ai) === null || _themeConfig$ai === void 0 ? void 0 : _themeConfig$ai.recommend) || "".concat(getBaseSiteDataUrl(), "/").concat(themeConfig.title, "/recommend.json");
|
|
47
|
+
if (!url) {
|
|
48
|
+
_context.next = 10;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
_context.next = 7;
|
|
52
|
+
return fetch(url).then(function (res) {
|
|
53
|
+
return res.json();
|
|
54
|
+
});
|
|
55
|
+
case 7:
|
|
56
|
+
data = _context.sent;
|
|
57
|
+
_context.next = 11;
|
|
48
58
|
break;
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
return _context.stop();
|
|
75
|
-
}
|
|
76
|
-
}, _callee, null, [[0, 14, 17, 20]]);
|
|
77
|
-
})), [list]);
|
|
59
|
+
case 10:
|
|
60
|
+
data = RecommendJson;
|
|
61
|
+
case 11:
|
|
62
|
+
setList(sampleSize(data, 4));
|
|
63
|
+
_context.next = 18;
|
|
64
|
+
break;
|
|
65
|
+
case 14:
|
|
66
|
+
_context.prev = 14;
|
|
67
|
+
_context.t0 = _context["catch"](0);
|
|
68
|
+
setList(RecommendJson);
|
|
69
|
+
console.log(_context.t0);
|
|
70
|
+
case 18:
|
|
71
|
+
_context.prev = 18;
|
|
72
|
+
setLoading(false);
|
|
73
|
+
return _context.finish(18);
|
|
74
|
+
case 21:
|
|
75
|
+
case "end":
|
|
76
|
+
return _context.stop();
|
|
77
|
+
}
|
|
78
|
+
}, _callee, null, [[0, 14, 18, 21]]);
|
|
79
|
+
}));
|
|
80
|
+
return function fetchList() {
|
|
81
|
+
return _ref.apply(this, arguments);
|
|
82
|
+
};
|
|
83
|
+
}();
|
|
78
84
|
useEffect(function () {
|
|
79
85
|
fetchList();
|
|
80
86
|
}, []);
|
package/dist/locales/en.json
CHANGED
|
@@ -207,6 +207,7 @@
|
|
|
207
207
|
"ai.msgbox.start.new.chat": "Start New Chat",
|
|
208
208
|
"ai.msgbox.send.tip": "Please enter content before sending",
|
|
209
209
|
"ai.msgbox.error.response": "Sorry, I couldn't successfully process your request, please try again later",
|
|
210
|
+
"ai.msgbox.continue.from.here": "Continue from here",
|
|
210
211
|
"ai.recommend.title": "Featured Cases",
|
|
211
212
|
"ai.recommend.refresh": "Refresh",
|
|
212
213
|
"ai.recommend.card.caseName": "Case Name",
|
|
@@ -229,12 +230,16 @@
|
|
|
229
230
|
"ai.conversations.pin": "Pin",
|
|
230
231
|
"ai.conversations.delete": "Delete",
|
|
231
232
|
"ai.conversations.edit.title": "Edit Conversation Name",
|
|
233
|
+
"ai.conversations.ok": "OK",
|
|
234
|
+
"ai.conversations.cancel": "Cancel",
|
|
235
|
+
"ai.msgbox.delete": "Delete",
|
|
236
|
+
"ai.msgbox.auto.fix": "Auto Fix",
|
|
237
|
+
"ai.msgbox.auto.fix.prompt": "This code encountered a problem during execution. Here is the exact error message it threw.",
|
|
232
238
|
"ai.chooseLib.placeholder": "Choose Technology Stack",
|
|
233
239
|
"ai.search.try": "Try",
|
|
234
240
|
"ai.search.visualization": "Q&A",
|
|
235
241
|
"ai.assistant.editor.intro": "I am AntV AI Assistant. You can ask me questions at any time to:\n1. Interpret the code configuration of the current chart.\n2. Generate new code based on the current case through natural language dialogue to customize the chart.",
|
|
236
242
|
"ai.placeholder.whatis": "What is {title}?",
|
|
237
|
-
"header.ai.code": "AI Code Generation",
|
|
238
243
|
"header.user.history": "History",
|
|
239
244
|
"header.user.logout": "Logout",
|
|
240
245
|
"header.user.deleteAccount": "Delete Account",
|
package/dist/locales/zh.json
CHANGED
|
@@ -222,18 +222,23 @@
|
|
|
222
222
|
"ai.toolbar.clear.conversation": "清空对话",
|
|
223
223
|
"ai.conversations.expand": "展开",
|
|
224
224
|
"ai.conversations.collapse": "收起",
|
|
225
|
+
"ai.msgbox.continue.from.here": "从这里继续",
|
|
225
226
|
"ai.conversations.new": "开始新对话",
|
|
226
227
|
"ai.conversations.history": "历史对话",
|
|
227
228
|
"ai.conversations.rename": "重命名",
|
|
228
229
|
"ai.conversations.pin": "置顶",
|
|
229
230
|
"ai.conversations.delete": "删除",
|
|
230
231
|
"ai.conversations.edit.title": "编辑对话名称",
|
|
232
|
+
"ai.conversations.ok": "确定",
|
|
233
|
+
"ai.conversations.cancel": "取消",
|
|
234
|
+
"ai.msgbox.delete": "删除",
|
|
235
|
+
"ai.msgbox.auto.fix": "自动修复",
|
|
236
|
+
"ai.msgbox.auto.fix.prompt": "这个代码在执行时遇到了问题。下面是它抛出的确切错误信息。",
|
|
231
237
|
"ai.chooseLib.placeholder": "选择技术栈",
|
|
232
238
|
"ai.search.try": "试试",
|
|
233
239
|
"ai.search.visualization": "可视化答疑",
|
|
234
240
|
"ai.assistant.editor.intro": "我是AntV AI助手。您可以随时向我提问,让我为您:\n\n1、解读当前图表的代码配置。\n2、通过自然语言对话,基于当前案例生成新代码以定制图表。",
|
|
235
241
|
"ai.placeholder.whatis": "{title}是什么?",
|
|
236
|
-
"header.ai.code": "AI生码",
|
|
237
242
|
"header.user.history": "历史会话",
|
|
238
243
|
"header.user.logout": "退出登录",
|
|
239
244
|
"header.user.deleteAccount": "注销账号",
|
package/dist/model/AIChat.js
CHANGED
|
@@ -15,6 +15,7 @@ import FingerprintJS from '@fingerprintjs/fingerprintjs';
|
|
|
15
15
|
import { history } from "dumi";
|
|
16
16
|
import { message } from "antd";
|
|
17
17
|
import { AIMode } from "../components/AI/constant";
|
|
18
|
+
import { trackEvent } from "../utils/analytics";
|
|
18
19
|
|
|
19
20
|
// --- 配置 ---
|
|
20
21
|
// 定义需要持久化的 state key
|
|
@@ -30,7 +31,8 @@ var initialState = {
|
|
|
30
31
|
tempMessage: null,
|
|
31
32
|
codeBlock: null,
|
|
32
33
|
lib: null,
|
|
33
|
-
mode: AIMode.implement
|
|
34
|
+
mode: AIMode.implement,
|
|
35
|
+
errorMsg: null
|
|
34
36
|
};
|
|
35
37
|
|
|
36
38
|
// --- valtio Store 创建 ---
|
|
@@ -205,9 +207,11 @@ subscribeKey(AIChatStore, 'activeSessionId', function () {
|
|
|
205
207
|
});
|
|
206
208
|
export var createPureNewSession = function createPureNewSession(title) {
|
|
207
209
|
var newConversationName = 'New Conversation';
|
|
208
|
-
|
|
210
|
+
var existNewSession = AIChatStore.sessions.find(function (s) {
|
|
209
211
|
return s.title === newConversationName && s.messages.length === 0;
|
|
210
|
-
})
|
|
212
|
+
});
|
|
213
|
+
if (existNewSession) {
|
|
214
|
+
AIChatStore.activeSessionId = existNewSession.id;
|
|
211
215
|
return;
|
|
212
216
|
}
|
|
213
217
|
var newSessionId = crypto.randomUUID();
|
|
@@ -220,7 +224,6 @@ export var createPureNewSession = function createPureNewSession(title) {
|
|
|
220
224
|
AIChatStore.activeSessionId = newSessionId;
|
|
221
225
|
};
|
|
222
226
|
export var createNewSession = function createNewSession(config) {
|
|
223
|
-
// todo 埋点
|
|
224
227
|
// 1. 创建一个新的会话
|
|
225
228
|
createPureNewSession(config.promptText);
|
|
226
229
|
|
|
@@ -238,6 +241,16 @@ export var createNewSession = function createNewSession(config) {
|
|
|
238
241
|
var _config$lang;
|
|
239
242
|
history.push("/".concat((_config$lang = config.lang) !== null && _config$lang !== void 0 ? _config$lang : 'zh', "/ai-playground"));
|
|
240
243
|
}
|
|
244
|
+
// 埋点
|
|
245
|
+
if ((typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object') {
|
|
246
|
+
trackEvent('start_ai_chat', {
|
|
247
|
+
entry_point: config.entry_point,
|
|
248
|
+
mode: AIChatStore.mode,
|
|
249
|
+
lib: AIChatStore.lib,
|
|
250
|
+
page_title: document.title,
|
|
251
|
+
location: location.href
|
|
252
|
+
});
|
|
253
|
+
}
|
|
241
254
|
};
|
|
242
255
|
|
|
243
256
|
/**
|
|
@@ -287,4 +300,14 @@ export var clearAllChatData = /*#__PURE__*/function () {
|
|
|
287
300
|
return function clearAllChatData() {
|
|
288
301
|
return _ref2.apply(this, arguments);
|
|
289
302
|
};
|
|
290
|
-
}();
|
|
303
|
+
}();
|
|
304
|
+
export function deleteMessage(msgId) {
|
|
305
|
+
derivedState.activeSession.messages = derivedState.activeSession.messages.filter(function (m) {
|
|
306
|
+
return m.id !== msgId;
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
export function branchMessage(index) {
|
|
310
|
+
var messages = derivedState.activeSession.messages.slice(0, index + 1);
|
|
311
|
+
createPureNewSession(messages[0].content);
|
|
312
|
+
AIChatStore.sessions[0].messages = messages;
|
|
313
|
+
}
|
|
@@ -156,7 +156,13 @@ export var ConversationsMenu = function ConversationsMenu() {
|
|
|
156
156
|
},
|
|
157
157
|
okButtonProps: {
|
|
158
158
|
disabled: !state.rename
|
|
159
|
-
}
|
|
159
|
+
},
|
|
160
|
+
okText: formatMessage({
|
|
161
|
+
id: 'ai.conversations.ok'
|
|
162
|
+
}),
|
|
163
|
+
cancelText: formatMessage({
|
|
164
|
+
id: 'ai.conversations.cancel'
|
|
165
|
+
})
|
|
160
166
|
}, /*#__PURE__*/React.createElement(Input, {
|
|
161
167
|
showCount: true,
|
|
162
168
|
maxLength: 100,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
1
2
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
|
|
2
3
|
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
3
4
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
4
5
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
5
6
|
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
6
7
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
7
|
-
import { CheckOutlined, CopyOutlined, PlusSquareOutlined, SyncOutlined } from '@ant-design/icons';
|
|
8
|
+
import { BranchesOutlined, CheckOutlined, CopyOutlined, DeleteOutlined, PlusSquareOutlined, SyncOutlined, ToolOutlined } from '@ant-design/icons';
|
|
8
9
|
import { Bubble } from '@ant-design/x';
|
|
9
10
|
import { Button, Flex, Space, Tooltip } from 'antd';
|
|
10
11
|
import { useChat } from '@ai-sdk/react';
|
|
@@ -15,13 +16,14 @@ import React, { useEffect, useState, useMemo, useRef } from 'react';
|
|
|
15
16
|
import { useCopyToClipboard } from 'react-use';
|
|
16
17
|
import { useSnapshot } from 'valtio';
|
|
17
18
|
import { PromptTextarea } from "../../../../components/AI/HomeDialog/PromptTextarea";
|
|
18
|
-
import { AIChatStore, clearEmptySession, createPureNewSession, derivedState } from "../../../../model/AIChat";
|
|
19
|
+
import { AIChatStore, branchMessage, clearEmptySession, createPureNewSession, deleteMessage, derivedState } from "../../../../model/AIChat";
|
|
19
20
|
import { getCodeFromMarkdown, isPreviewable } from "../../../../utils/code";
|
|
20
21
|
import { MarkdownComponent } from "../MarkdownComponent";
|
|
21
22
|
import styles from "./index.module.less";
|
|
22
23
|
import { useAutoScroll } from "./useAutoScroll";
|
|
23
24
|
import { getBaseURL } from "../../../../utils/env";
|
|
24
25
|
import { AIMode } from "../../../../components/AI/constant";
|
|
26
|
+
import { trackEvent } from "../../../../utils/analytics";
|
|
25
27
|
var avatar = {
|
|
26
28
|
icon: /*#__PURE__*/React.createElement("img", {
|
|
27
29
|
draggable: false,
|
|
@@ -188,9 +190,9 @@ function MsgBox(props) {
|
|
|
188
190
|
text: promptText
|
|
189
191
|
}, {
|
|
190
192
|
body: {
|
|
191
|
-
context: fileSummary,
|
|
192
|
-
lib: snap.lib,
|
|
193
|
-
mode: snap.mode
|
|
193
|
+
// context: fileSummary,
|
|
194
|
+
// lib: snap.lib,
|
|
195
|
+
// mode: snap.mode,
|
|
194
196
|
}
|
|
195
197
|
});
|
|
196
198
|
setPromptText('');
|
|
@@ -203,6 +205,16 @@ function MsgBox(props) {
|
|
|
203
205
|
lib: snap.lib
|
|
204
206
|
});
|
|
205
207
|
chatScrollIntoView();
|
|
208
|
+
// 埋点
|
|
209
|
+
if ((typeof window === "undefined" ? "undefined" : _typeof(window)) === 'object') {
|
|
210
|
+
trackEvent('start_ai_chat', {
|
|
211
|
+
entry_point: simple ? 'Drawer' : 'MsgBox',
|
|
212
|
+
mode: AIChatStore.mode,
|
|
213
|
+
lib: AIChatStore.lib,
|
|
214
|
+
page_title: document.title,
|
|
215
|
+
location: location.href
|
|
216
|
+
});
|
|
217
|
+
}
|
|
206
218
|
};
|
|
207
219
|
|
|
208
220
|
// 同步 Valtio store -> useChat state
|
|
@@ -254,12 +266,36 @@ function MsgBox(props) {
|
|
|
254
266
|
useEffect(function () {
|
|
255
267
|
chatScrollIntoView();
|
|
256
268
|
stop();
|
|
269
|
+
AIChatStore.errorMsg = null;
|
|
257
270
|
}, [snap.activeSessionId]);
|
|
258
271
|
|
|
259
272
|
// 将 messages 数组作为依赖项。当它变化时,Hook 会运行。
|
|
260
273
|
var _useAutoScroll = useAutoScroll(messages),
|
|
261
274
|
containerRef = _useAutoScroll.containerRef,
|
|
262
275
|
anchorRef = _useAutoScroll.anchorRef;
|
|
276
|
+
var autofix = function autofix() {
|
|
277
|
+
var _derivedState$activeS6;
|
|
278
|
+
var autoFixPromptText = "".concat(formatMessage({
|
|
279
|
+
id: 'ai.msgbox.auto.fix.prompt'
|
|
280
|
+
}), ": [").concat(snap.errorMsg, "]");
|
|
281
|
+
sendMessage({
|
|
282
|
+
text: autoFixPromptText
|
|
283
|
+
}, {
|
|
284
|
+
body: {
|
|
285
|
+
antvContext: snap.codeBlock
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
AIChatStore.errorMsg = null;
|
|
289
|
+
(_derivedState$activeS6 = derivedState.activeSession) === null || _derivedState$activeS6 === void 0 || (_derivedState$activeS6 = _derivedState$activeS6.messages) === null || _derivedState$activeS6 === void 0 || _derivedState$activeS6.push({
|
|
290
|
+
id: crypto.randomUUID(),
|
|
291
|
+
role: 'user',
|
|
292
|
+
content: autoFixPromptText,
|
|
293
|
+
createdAt: Date.now(),
|
|
294
|
+
context: snap.codeBlock,
|
|
295
|
+
lib: snap.lib
|
|
296
|
+
});
|
|
297
|
+
chatScrollIntoView();
|
|
298
|
+
};
|
|
263
299
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Flex, {
|
|
264
300
|
gap: "middle",
|
|
265
301
|
vertical: true,
|
|
@@ -274,9 +310,9 @@ function MsgBox(props) {
|
|
|
274
310
|
showRunButton: !props.simple
|
|
275
311
|
}),
|
|
276
312
|
avatar: msg.role === 'assistant' ? avatar : null,
|
|
277
|
-
footer:
|
|
313
|
+
footer: status === 'ready' && /*#__PURE__*/React.createElement(Space, {
|
|
278
314
|
size: "small"
|
|
279
|
-
}, /*#__PURE__*/React.createElement(Tooltip, {
|
|
315
|
+
}, msg.role === 'assistant' && index === messages.length - 1 && /*#__PURE__*/React.createElement(Tooltip, {
|
|
280
316
|
title: formatMessage({
|
|
281
317
|
id: 'ai.msgbox.retry'
|
|
282
318
|
})
|
|
@@ -301,7 +337,31 @@ function MsgBox(props) {
|
|
|
301
337
|
return copyToClipboard(textContent);
|
|
302
338
|
},
|
|
303
339
|
icon: copyState.value === textContent ? /*#__PURE__*/React.createElement(CheckOutlined, null) : /*#__PURE__*/React.createElement(CopyOutlined, null)
|
|
304
|
-
}))
|
|
340
|
+
})), /*#__PURE__*/React.createElement(Tooltip, {
|
|
341
|
+
title: formatMessage({
|
|
342
|
+
id: 'ai.msgbox.continue.from.here'
|
|
343
|
+
})
|
|
344
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
345
|
+
color: "default",
|
|
346
|
+
variant: "text",
|
|
347
|
+
size: "small",
|
|
348
|
+
onClick: function onClick() {
|
|
349
|
+
return branchMessage(index);
|
|
350
|
+
},
|
|
351
|
+
icon: /*#__PURE__*/React.createElement(BranchesOutlined, null)
|
|
352
|
+
})), msg.role === 'assistant' && /*#__PURE__*/React.createElement(Tooltip, {
|
|
353
|
+
title: formatMessage({
|
|
354
|
+
id: 'ai.msgbox.delete'
|
|
355
|
+
})
|
|
356
|
+
}, /*#__PURE__*/React.createElement(Button, {
|
|
357
|
+
color: "default",
|
|
358
|
+
variant: "text",
|
|
359
|
+
size: "small",
|
|
360
|
+
onClick: function onClick() {
|
|
361
|
+
return deleteMessage(msg.id);
|
|
362
|
+
},
|
|
363
|
+
icon: /*#__PURE__*/React.createElement(DeleteOutlined, null)
|
|
364
|
+
}))),
|
|
305
365
|
placement: msg.role === 'user' ? 'end' : 'start'
|
|
306
366
|
});
|
|
307
367
|
}), (status === 'streaming' || status === 'submitted') && ((_messages = messages[messages.length - 1]) === null || _messages === void 0 ? void 0 : _messages.role) === 'user' && /*#__PURE__*/React.createElement(Bubble, {
|
|
@@ -321,7 +381,14 @@ function MsgBox(props) {
|
|
|
321
381
|
className: styles.newButton
|
|
322
382
|
}, /*#__PURE__*/React.createElement(Space, null, /*#__PURE__*/React.createElement(PlusSquareOutlined, null), formatMessage({
|
|
323
383
|
id: 'ai.msgbox.start.new.chat'
|
|
324
|
-
})))
|
|
384
|
+
}))), snap.errorMsg && status === 'ready' && /*#__PURE__*/React.createElement(Button, {
|
|
385
|
+
onClick: autofix,
|
|
386
|
+
color: "danger",
|
|
387
|
+
variant: "filled",
|
|
388
|
+
icon: /*#__PURE__*/React.createElement(ToolOutlined, null)
|
|
389
|
+
}, formatMessage({
|
|
390
|
+
id: 'ai.msgbox.auto.fix'
|
|
391
|
+
})))), /*#__PURE__*/React.createElement(PromptTextarea, {
|
|
325
392
|
size: "compact",
|
|
326
393
|
value: promptText,
|
|
327
394
|
onChange: setPromptText,
|
|
@@ -38,7 +38,8 @@ function SessionLayout(props) {
|
|
|
38
38
|
primary: "second",
|
|
39
39
|
style: {
|
|
40
40
|
position: 'unset'
|
|
41
|
-
}
|
|
41
|
+
},
|
|
42
|
+
minSize: 100
|
|
42
43
|
}, /*#__PURE__*/React.createElement("div", {
|
|
43
44
|
className: classnames(styles.msgBox)
|
|
44
45
|
}, children[0]), /*#__PURE__*/React.createElement("div", {
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
3
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
|
|
4
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
1
5
|
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
2
6
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
3
7
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
@@ -75,25 +79,99 @@ export function generateDependencies(codeString) {
|
|
|
75
79
|
}
|
|
76
80
|
return dependencies;
|
|
77
81
|
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* 基于代码内容,启发式地判断其最合适的文件扩展名。
|
|
85
|
+
* @param {string} code - 要分析的前端代码字符串。
|
|
86
|
+
* @returns {'tsx' | 'jsx' | 'ts' | 'js'} - 推断出的文件扩展名(不含点)。
|
|
87
|
+
*/
|
|
88
|
+
export function getLanguageExtension(code) {
|
|
89
|
+
// --- 特征检测函数 ---
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* 检查代码是否包含 JSX 语法。
|
|
93
|
+
* 这是一个启发式检查,它查找类似HTML标签的模式。
|
|
94
|
+
* - 匹配 <div...>, <MyComponent...>, </tag>, <Component/>, <>
|
|
95
|
+
*/
|
|
96
|
+
var containsJsx = function containsJsx(text) {
|
|
97
|
+
// 1. 查找开/闭标签 <...> 或自闭合标签 <.../>
|
|
98
|
+
// 2. 忽略可能误判的比较操作,如 `i < j`
|
|
99
|
+
// 这个正则查找一个'<'符号,后面不能是'!' (注释)或'=' (小于等于),
|
|
100
|
+
// 并且后面跟着一个合法的标签名(字母开头)或闭合标签'/'。
|
|
101
|
+
// 这比简单的 /<...>/ 更可靠。
|
|
102
|
+
var jsxRegex = /<(?![\s!=])([a-zA-Z][a-zA-Z0-9-]*|\/|)/;
|
|
103
|
+
return jsxRegex.test(text);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* 检查代码是否包含 TypeScript 语法。
|
|
108
|
+
* 这是一个启发式检查,查找TS独有的关键字和语法模式。
|
|
109
|
+
*/
|
|
110
|
+
var containsTypeScript = function containsTypeScript(text) {
|
|
111
|
+
// 检查点 1: 类型/接口定义(非常明确的信号)
|
|
112
|
+
// 匹配 `type MyType = ...` 或 `interface MyInterface { ... }`
|
|
113
|
+
var typeDefinitionRegex = /\b(interface|type)\s+[A-Z][a-zA-Z0-9]*\b/;
|
|
114
|
+
if (typeDefinitionRegex.test(text)) {
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 检查点 2: 变量或参数的类型注解(强信号)
|
|
119
|
+
// 匹配 `: string`, `: number`, `: MyType` 等
|
|
120
|
+
// 这个正则查找一个冒号,后面跟着一个类型(通常大写字母开头或ts内置类型)
|
|
121
|
+
var typeAnnotationRegex = /:\s*([A-Z][a-zA-Z0-9<>.]*|string|number|boolean|any\[?\]?)/;
|
|
122
|
+
if (typeAnnotationRegex.test(text)) {
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 检查点 3: 其他TS关键字
|
|
127
|
+
// 匹配 `as someType`, `implements`, `private`, `public`, `protected` 等
|
|
128
|
+
var tsKeywordsRegex = /\b(as|implements|private|public|protected|readonly)\s+[a-zA-Z]/;
|
|
129
|
+
if (tsKeywordsRegex.test(text)) {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
// --- 决策逻辑 ---
|
|
136
|
+
|
|
137
|
+
if (containsJsx(code)) {
|
|
138
|
+
if (containsTypeScript(code)) {
|
|
139
|
+
return 'tsx';
|
|
140
|
+
}
|
|
141
|
+
return 'jsx';
|
|
142
|
+
} else {
|
|
143
|
+
if (containsTypeScript(code)) {
|
|
144
|
+
return 'ts';
|
|
145
|
+
}
|
|
146
|
+
return 'js';
|
|
147
|
+
}
|
|
148
|
+
}
|
|
78
149
|
export function wrap2VisionSnap() {
|
|
79
150
|
var codeBlock = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
|
|
151
|
+
var ext = getLanguageExtension(codeBlock);
|
|
152
|
+
var mainFile = "/src/index.".concat(ext);
|
|
153
|
+
var appFile = "/src/App.".concat(ext);
|
|
80
154
|
var dependencies = generateDependencies(codeBlock);
|
|
81
155
|
var rootElementType = dependencies['@antv/f2'] ? 'canvas' : 'div';
|
|
156
|
+
var dependenciesJSON = {
|
|
157
|
+
"name": "AntV-adapted-project",
|
|
158
|
+
"version": "1.0.0",
|
|
159
|
+
"main": mainFile,
|
|
160
|
+
"dependencies": dependencies
|
|
161
|
+
};
|
|
82
162
|
return {
|
|
83
|
-
modules: {
|
|
163
|
+
modules: _defineProperty(_defineProperty({
|
|
84
164
|
'/package.json': {
|
|
85
165
|
fpath: '/package.json',
|
|
86
|
-
code:
|
|
87
|
-
},
|
|
88
|
-
'/src/index.jsx': {
|
|
89
|
-
fpath: '/src/index.jsx',
|
|
90
|
-
code: "\n// --- Adapter Script ---\n\n// 1. \u627E\u5230\u7F16\u8F91\u5668\u73AF\u5883\u63D0\u4F9B\u7684\u6839\u8282\u70B9 #root\nconst rootElement = document.getElementById('root');\n\nif (rootElement) {\n // 2. \u5728 #root \u5185\u90E8\u521B\u5EFA\u4E00\u4E2A ".concat(rootElementType, "\n const containerElement = document.createElement('").concat(rootElementType, "');\n\n // 3. \u5C06\u8FD9\u4E2A div \u7684 id \u8BBE\u7F6E\u4E3A 'container'\uFF0C\u4EE5\u6EE1\u8DB3\u7528\u6237\u4EE3\u7801\u7684\u9700\u6C42\n containerElement.id = 'container';\n\n // 4. \u5C06\u5B83\u6DFB\u52A0\u5230 #root \u4E2D\n rootElement.appendChild(containerElement);\n\n // 5. \u73B0\u5728 DOM \u4E2D\u5DF2\u7ECF\u5B58\u5728 #container\uFF0C\u5B89\u5168\u5730\u5BFC\u5165\u5E76\u6267\u884C\u7528\u6237\u7684\u4EE3\u7801\n import('./App.jsx');\n\n}\n ")
|
|
91
|
-
},
|
|
92
|
-
'/src/App.jsx': {
|
|
93
|
-
fpath: '/src/App.jsx',
|
|
94
|
-
code: codeBlock
|
|
166
|
+
code: JSON.stringify(dependenciesJSON, null, 2)
|
|
95
167
|
}
|
|
96
|
-
}
|
|
168
|
+
}, mainFile, {
|
|
169
|
+
fpath: mainFile,
|
|
170
|
+
code: "\n// --- Adapter Script ---\n\n// 1. \u627E\u5230\u7F16\u8F91\u5668\u73AF\u5883\u63D0\u4F9B\u7684\u6839\u8282\u70B9 #root\nconst rootElement = document.getElementById('root');\n\nif (rootElement) {\n // 2. \u5728 #root \u5185\u90E8\u521B\u5EFA\u4E00\u4E2A ".concat(rootElementType, "\n const containerElement = document.createElement('").concat(rootElementType, "');\n\n // 3. \u5C06\u8FD9\u4E2A div \u7684 id \u8BBE\u7F6E\u4E3A 'container'\uFF0C\u4EE5\u6EE1\u8DB3\u7528\u6237\u4EE3\u7801\u7684\u9700\u6C42\n containerElement.id = 'container';\n\n // 4. \u5C06\u5B83\u6DFB\u52A0\u5230 #root \u4E2D\n rootElement.appendChild(containerElement);\n\n // 5. \u73B0\u5728 DOM \u4E2D\u5DF2\u7ECF\u5B58\u5728 #container\uFF0C\u5B89\u5168\u5730\u5BFC\u5165\u5E76\u6267\u884C\u7528\u6237\u7684\u4EE3\u7801\n import('./App.").concat(ext, "');\n\n}\n ")
|
|
171
|
+
}), appFile, {
|
|
172
|
+
fpath: [appFile],
|
|
173
|
+
code: codeBlock
|
|
174
|
+
})
|
|
97
175
|
};
|
|
98
176
|
}
|
|
99
177
|
export function wrap2Sandpack() {
|
|
@@ -48,7 +48,15 @@ function TaskBox() {
|
|
|
48
48
|
if (loading) {
|
|
49
49
|
return /*#__PURE__*/React.createElement(Loading, null);
|
|
50
50
|
}
|
|
51
|
-
|
|
51
|
+
var wrappedVisionSnapCode = wrap2VisionSnap(snap.codeBlock);
|
|
52
|
+
var handleEsmLoadFailed = function handleEsmLoadFailed(err) {
|
|
53
|
+
// F2的异常没法修,VisionSnap的异常信息不准确
|
|
54
|
+
if (!wrappedVisionSnapCode.modules["/package.json"].code.includes("@antv/f2")) {
|
|
55
|
+
var _err$data;
|
|
56
|
+
AIChatStore.errorMsg = ((_err$data = err.data) === null || _err$data === void 0 || (_err$data = _err$data.error) === null || _err$data === void 0 || (_err$data = _err$data.split('\n')) === null || _err$data === void 0 ? void 0 : _err$data[1]) || JSON.stringify(err) || err.message;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
if (themeConfig.isAntVSite || ((_themeConfig$ai = themeConfig.ai) === null || _themeConfig$ai === void 0 ? void 0 : _themeConfig$ai.codeRunner) === "VisionSnap" || !((_themeConfig$ai2 = themeConfig.ai) !== null && _themeConfig$ai2 !== void 0 && _themeConfig$ai2.codeRunner) || !wrappedVisionSnapCode.modules["/package.json"].code.includes("@antv/f2")) {
|
|
52
60
|
return /*#__PURE__*/React.createElement(ErrorBoundary, {
|
|
53
61
|
FallbackComponent: ErrorFallback
|
|
54
62
|
}, /*#__PURE__*/React.createElement(sdk.VisionPreview, {
|
|
@@ -61,13 +69,14 @@ function TaskBox() {
|
|
|
61
69
|
displayMode: "code-and-preview",
|
|
62
70
|
initialView: "preview",
|
|
63
71
|
theme: "light",
|
|
64
|
-
code:
|
|
72
|
+
code: wrappedVisionSnapCode,
|
|
65
73
|
requestProxy: requestProxy,
|
|
66
74
|
isStreaming: false,
|
|
67
75
|
proxyOptions: {
|
|
68
76
|
isWAN: true
|
|
69
77
|
},
|
|
70
|
-
src: "https://www.weavefox.cn/_visionsnap_render/index.html?version=3.2.15&enableInspector=1"
|
|
78
|
+
src: "https://www.weavefox.cn/_visionsnap_render/index.html?version=3.2.15&enableInspector=1",
|
|
79
|
+
onEsmLoadFailed: handleEsmLoadFailed
|
|
71
80
|
}));
|
|
72
81
|
} else {
|
|
73
82
|
return /*#__PURE__*/React.createElement(CodeRunner, {
|
|
@@ -3,7 +3,10 @@ import { SessionLayout } from "./components/SessionLayout";
|
|
|
3
3
|
import MsgBox from "./components/MsgBox";
|
|
4
4
|
import TaskBox from "./components/TaskBox";
|
|
5
5
|
import Header from "dumi/theme/slots/Header";
|
|
6
|
+
import styles from "./index.module.less";
|
|
6
7
|
function AIPlayground() {
|
|
7
|
-
return /*#__PURE__*/React.createElement(
|
|
8
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
9
|
+
className: styles.aiPlayground
|
|
10
|
+
}, /*#__PURE__*/React.createElement(Header, null), /*#__PURE__*/React.createElement(SessionLayout, null, /*#__PURE__*/React.createElement(MsgBox, null), /*#__PURE__*/React.createElement(TaskBox, null)));
|
|
8
11
|
}
|
|
9
12
|
export default AIPlayground;
|
|
@@ -2,7 +2,7 @@ import { useIntl, useSiteData } from 'dumi';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import styles from "./SearchResult.module.less";
|
|
4
4
|
import classnames from "classnames";
|
|
5
|
-
import { createNewSession } from "../../../model/AIChat";
|
|
5
|
+
import { AIChatStore, createNewSession } from "../../../model/AIChat";
|
|
6
6
|
import { authStore, showLoginModal } from "../../../model/auth";
|
|
7
7
|
import { useSnapshot } from "valtio";
|
|
8
8
|
var getHighlightInfo = function getHighlightInfo(textSegments) {
|
|
@@ -25,12 +25,14 @@ export var SearchResult = function SearchResult(_ref) {
|
|
|
25
25
|
var intl = useIntl();
|
|
26
26
|
var authSnap = useSnapshot(authStore);
|
|
27
27
|
function pureSearch() {
|
|
28
|
+
AIChatStore.mode = 'solve';
|
|
28
29
|
createNewSession({
|
|
29
30
|
promptText: keywords,
|
|
30
31
|
mode: 'solve',
|
|
31
32
|
lib: !themeConfig.isAntVSite ? themeConfig.title : undefined,
|
|
32
33
|
jump: true,
|
|
33
|
-
lang: intl.locale === 'zh' ? 'zh' : 'en'
|
|
34
|
+
lang: intl.locale === 'zh' ? 'zh' : 'en',
|
|
35
|
+
entry_point: 'SearchResult'
|
|
34
36
|
});
|
|
35
37
|
}
|
|
36
38
|
return /*#__PURE__*/React.createElement("div", {
|
|
@@ -18,7 +18,7 @@ import { Alert, Button, Dropdown, Menu, Modal, Popover } from 'antd';
|
|
|
18
18
|
import cx from 'classnames';
|
|
19
19
|
import { FormattedMessage, Link, useLocale, useSiteData, useIntl, history } from 'dumi';
|
|
20
20
|
import { get, map, size } from 'lodash-es';
|
|
21
|
-
import React, { useEffect,
|
|
21
|
+
import React, { useEffect, useState } from 'react';
|
|
22
22
|
import { useMedia } from 'react-use';
|
|
23
23
|
import { getPurePathname } from "../../utils/location";
|
|
24
24
|
import { ic, icWithLocale } from "../hooks";
|
|
@@ -57,9 +57,6 @@ var HeaderComponent = function HeaderComponent(_ref) {
|
|
|
57
57
|
showAntVProductsCard = _ref$showAntVProducts === void 0 ? true : _ref$showAntVProducts,
|
|
58
58
|
_ref$showLanguageSwit = _ref.showLanguageSwitcher,
|
|
59
59
|
showLanguageSwitcher = _ref$showLanguageSwit === void 0 ? true : _ref$showLanguageSwit,
|
|
60
|
-
_ref$showWeavefox = _ref.showWeavefox,
|
|
61
|
-
showWeavefox = _ref$showWeavefox === void 0 ? {} : _ref$showWeavefox,
|
|
62
|
-
isInternalUser = _ref.isInternalUser,
|
|
63
60
|
logo = _ref.logo,
|
|
64
61
|
onLanguageChange = _ref.onLanguageChange,
|
|
65
62
|
_ref$showWxQrcode = _ref.showWxQrcode,
|
|
@@ -154,8 +151,7 @@ var HeaderComponent = function HeaderComponent(_ref) {
|
|
|
154
151
|
}),
|
|
155
152
|
link: ''
|
|
156
153
|
}, logo),
|
|
157
|
-
img = _img$link$logo.img
|
|
158
|
-
link = _img$link$logo.link;
|
|
154
|
+
img = _img$link$logo.img;
|
|
159
155
|
var _useLocation = useLocation(),
|
|
160
156
|
pathname = _useLocation.pathname;
|
|
161
157
|
useEffect(function () {
|
|
@@ -190,27 +186,13 @@ var HeaderComponent = function HeaderComponent(_ref) {
|
|
|
190
186
|
var handleSwitchLanguage = function handleSwitchLanguage() {
|
|
191
187
|
onLanguageChange === null || onLanguageChange === void 0 || onLanguageChange(lang);
|
|
192
188
|
};
|
|
193
|
-
var weavefox = useMemo(function () {
|
|
194
|
-
var configKey = isInternalUser ? 'internal' : 'public';
|
|
195
|
-
var configValue = showWeavefox[configKey];
|
|
196
|
-
if (!configValue) return /*#__PURE__*/React.createElement(React.Fragment, null);
|
|
197
|
-
var defaultLink = isInternalUser ? 'https://weavefox.antgroup-inc.cn/agent/@huiyu.zjt/AntV' : 'https://weavefox.alipay.com/agent/@ufox-b8tydq-0758/202505AP7vfl00422922';
|
|
198
|
-
var href = typeof configValue === 'string' ? configValue : defaultLink;
|
|
199
|
-
return /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement("a", {
|
|
200
|
-
href: href,
|
|
201
|
-
target: "_blank",
|
|
202
|
-
rel: "noreferrer"
|
|
203
|
-
}, /*#__PURE__*/React.createElement(FormattedMessage, {
|
|
204
|
-
id: "header.ai.code"
|
|
205
|
-
})));
|
|
206
|
-
}, [isInternalUser, showWeavefox]);
|
|
207
189
|
var menu = /*#__PURE__*/React.createElement("ul", {
|
|
208
190
|
className: cx(styles.menu, _defineProperty(_defineProperty({}, styles.popup, !isWide), styles.popupHidden, !popupMenuVisible))
|
|
209
191
|
}, /** 最左侧的菜单,一般是 教程、API、示例,或者其他自定义,有配置文件中的 `navs` 决定 */
|
|
210
192
|
size(navs) ? /*#__PURE__*/React.createElement(Navs, {
|
|
211
193
|
navs: navs,
|
|
212
194
|
path: pathname
|
|
213
|
-
}) : null,
|
|
195
|
+
}) : null, /** 生态产品 */
|
|
214
196
|
size(ecosystems) ? /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement(Dropdown, {
|
|
215
197
|
className: styles.ecoSystems,
|
|
216
198
|
overlay: /*#__PURE__*/React.createElement(Menu, null, map(ecosystems, function (_ref2) {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 统一的事件跟踪函数
|
|
3
|
+
* @param {string} eventName - 事件名称,如 'button_click'
|
|
4
|
+
* @param {object} params - 事件相关的参数
|
|
5
|
+
*/
|
|
6
|
+
export var trackEvent = function trackEvent(eventName) {
|
|
7
|
+
var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
8
|
+
if (typeof window === 'undefined') {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
if (window.gtag) {
|
|
12
|
+
window.gtag('event', eventName, params);
|
|
13
|
+
} else {
|
|
14
|
+
console.warn('[Analytics] gtag is not available.');
|
|
15
|
+
}
|
|
16
|
+
};
|