@antv/dumi-theme-antv 0.8.0-beta.8 → 0.8.1

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.
Files changed (45) hide show
  1. package/README.md +52 -13
  2. package/dist/components/AI/HomeDialog/ModeSelector/ModeSelectorDropdown.js +42 -0
  3. package/dist/components/AI/HomeDialog/PromptTextarea/ChooseLib/index.js +12 -4
  4. package/dist/components/AI/HomeDialog/PromptTextarea/SendButton.js +1 -1
  5. package/dist/components/AI/HomeDialog/PromptTextarea/index.js +42 -18
  6. package/dist/components/AI/HomeDialog/RecommendCase/Card.js +14 -11
  7. package/dist/components/AI/HomeDialog/RecommendCase/card.module.less +2 -2
  8. package/dist/components/AI/HomeDialog/RecommendCase/index.js +73 -24
  9. package/dist/components/AI/HomeDialog/RecommendCase/index.module.less +2 -0
  10. package/dist/components/AI/HomeDialog/RecommendCase/recommend.json +41 -17
  11. package/dist/components/AI/HomeDialog/index.js +27 -40
  12. package/dist/components/AI/constant.js +4 -2
  13. package/dist/components/Login/LoginForm.js +2 -8
  14. package/dist/components/Login/LoginForm.less +3 -4
  15. package/dist/hooks/useProducts.js +23 -3
  16. package/dist/layouts/GlobalLayout/index.js +1 -0
  17. package/dist/locales/en.json +12 -1
  18. package/dist/locales/zh.json +12 -1
  19. package/dist/model/AIChat.js +41 -4
  20. package/dist/model/auth.js +26 -8
  21. package/dist/pages/AIPlayground/components/ConversationsMenu/index.js +15 -7
  22. package/dist/pages/AIPlayground/components/MarkdownComponent/MarkdownCodeBlock.js +15 -10
  23. package/dist/pages/AIPlayground/components/MarkdownComponent/index.js +2 -2
  24. package/dist/pages/AIPlayground/components/MsgBox/index.js +117 -39
  25. package/dist/pages/AIPlayground/components/SessionLayout/index.js +41 -12
  26. package/dist/pages/AIPlayground/components/SessionLayout/index.module.less +4 -3
  27. package/dist/pages/AIPlayground/components/TaskBox/generateCode.js +128 -13
  28. package/dist/pages/AIPlayground/components/TaskBox/index.js +23 -6
  29. package/dist/pages/AIPlayground/index.js +4 -1
  30. package/dist/pages/AIPlayground/index.module.less +5 -0
  31. package/dist/slots/CodeEditor/Toolbar.js +2 -22
  32. package/dist/slots/CodeEditor/index.js +23 -7
  33. package/dist/slots/CodeEditor/index.module.less +0 -1
  34. package/dist/slots/CodeEditor/utils.js +2 -1
  35. package/dist/slots/CodeRunner/index.js +20 -11
  36. package/dist/slots/Detail/index.js +2 -1
  37. package/dist/slots/Header/Search/SearchResult.js +14 -9
  38. package/dist/slots/Header/index.js +22 -25
  39. package/dist/slots/LiveExample/index.js +1 -1
  40. package/dist/typings.d.ts +6 -0
  41. package/dist/utils/analytics.js +16 -0
  42. package/dist/utils/env.js +43 -17
  43. package/dist/utils/index.js +7 -0
  44. package/package.json +12 -20
  45. package/dist/utils/uid.js +0 -17
package/README.md CHANGED
@@ -2,18 +2,24 @@
2
2
 
3
3
  [![NPM version](https://img.shields.io/npm/v/@antv/dumi-theme-antv.svg?style=flat)](https://npmjs.org/package/@antv/dumi-theme-antv) [![NPM downloads](http://img.shields.io/npm/dm/@antv/dumi-theme-antv.svg?style=flat)](https://npmjs.org/package/@antv/dumi-theme-antv)
4
4
 
5
- A theme package for the [dumi](https://next.d.umijs.org) framework.
5
+ A theme package for the [dumi](https://next.d.umijs.org) framework, serving AntV official websites including G2, G6, X6, F2, S2, L7, and more.
6
6
 
7
- ## Usage
7
+ [dumi](https://next.d.umijs.org) 框架的主题包,服务于 AntV 官网,包括 G2、G6、X6、F2、S2、L7 等等。
8
+
9
+ ## Usage / 用法
8
10
 
9
11
  Install this theme into `devDependencies`:
10
12
 
13
+ 安装此主题到 `devDependencies`:
14
+
11
15
  ```bash
12
16
  $ npm i @antv/dumi-theme-antv -D
13
17
  ```
14
18
 
15
19
  Configure it in dumi config file `.dumirc.ts`:
16
20
 
21
+ 在 dumi 配置文件 `.dumirc.ts` 中配置:
22
+
17
23
  ```ts
18
24
  import { defineConfig } from 'dumi';
19
25
 
@@ -26,35 +32,68 @@ export defineConfig({
26
32
 
27
33
  That's all, now you can execute `dumi dev` and enjoy this theme.
28
34
 
29
- ## Options
35
+ 这就行了,现在你可以执行 `dumi dev` 并享受这个主题了。
36
+
37
+ ## Options / 选项
30
38
 
31
39
  TODO
32
40
 
41
+ `themeConfig.docsearchOptions.sort` creates a sorting rule for search results. This can be defined using an array of strings.
42
+
33
43
  `themeConfig.docsearchOptions.sort` 用于配置搜索结果的排序规则。可以通过字符串数组来定义排序逻辑。
34
44
 
45
+ - Each string can be a path segment used to match the link of search results.
46
+ - If a string starts with `!`, it means results NOT containing that path segment should be ranked before those that do.
47
+
35
48
  - 每个字符串可以是一个路径片段,用于匹配搜索结果的链接。
36
49
  - 如果字符串以 `!` 开头,则表示不包含该路径片段的结果应排在包含该路径片段的结果之前。
37
50
 
38
- ## Development
51
+ ## Development / 开发
39
52
 
40
53
  ```bash
41
54
  $ npm install
42
55
  ```
43
56
 
44
- After the dependencies are installed, a symlink from `example/.dumi/theme` to `../../src` will be created automatically, the symlink makes dumi load our theme package as a local theme, so we can start the example directly, HMR is also available:
57
+ If you want to test locally, it is recommended to `npm link` directly to the corresponding AntV official website project for testing, so that HMR (Hot Module Replacement) works. Testing directly using this project (e.g. in `example`) does not support HMR.
45
58
 
46
- ```bash
47
- # switch to example directory
48
- $ cd example
59
+ 如果想本地测试,建议直接通过 `npm link` 到对应的 AntV 官网项目中测试,这样才有热更新 (HMR)。直接使用本项目测试(如 `example` 目录)是没有热更新的。
60
+
61
+ dumi theme development documentation: https://next.d.umijs.org/theme
62
+
63
+ dumi 主题开发文档:https://next.d.umijs.org/theme
64
+
65
+ ## Release / 发布
66
+
67
+ This project uses GitHub Actions for automated releasing and [Trusted Publishing](https://docs.npmjs.com/trusted-publishers).
49
68
 
50
- # downloads the dependencies
51
- npm install
69
+ 本项目使用 GitHub Actions 进行自动化发布,并采用了 [可信发布 (Trusted Publishing)](https://docs.npmjs.com/trusted-publishers)。
52
70
 
53
- # start dev server to preview
54
- npm run dev
71
+ To publish a new version, simply push a git tag:
72
+
73
+ 发布新版本只需推送一个 git tag:
74
+
75
+ ```bash
76
+ # for stable release / 正式发布
77
+ git tag v0.8.0
78
+ git push origin v0.8.0
79
+
80
+ # for pre-release (auto-tagged as beta/alpha/etc on npm based on the suffix)
81
+ # 预发布(根据后缀自动在 npm 标记为 beta/alpha 等)
82
+ git tag v0.8.0-beta.1
83
+ git push origin v0.8.0-beta.1
55
84
  ```
56
85
 
57
- dumi theme development documentation: https://next.d.umijs.org/theme
86
+ The CI will automatically:
87
+ 1. Parse the version from the tag.
88
+ 2. Build the project.
89
+ 3. Publish to npm (with provenance).
90
+ 4. Create a GitHub Release.
91
+
92
+ CI 将会自动:
93
+ 1. 从 tag 中解析版本号。
94
+ 2. 构建项目。
95
+ 3. 发布到 npm(带有 provenance)。
96
+ 4. 创建 GitHub Release。
58
97
 
59
98
  ## LICENSE
60
99
 
@@ -0,0 +1,42 @@
1
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
2
+ 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
+ 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
+ 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
+ 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
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
+ import { Dropdown, Space } from 'antd';
8
+ import { useIntl } from 'dumi';
9
+ import React from 'react';
10
+ import { useSnapshot } from 'valtio';
11
+ import { AIChatStore } from "../../../../model/AIChat";
12
+ import { AIModeMeta } from "../../constant";
13
+ export function ModeSelectorDropdown() {
14
+ var _useIntl = useIntl(),
15
+ formatMessage = _useIntl.formatMessage;
16
+ var snap = useSnapshot(AIChatStore);
17
+ var items = Object.entries(AIModeMeta).map(function (_ref) {
18
+ var _ref2 = _slicedToArray(_ref, 2),
19
+ key = _ref2[0],
20
+ value = _ref2[1];
21
+ return {
22
+ key: key,
23
+ label: formatMessage({
24
+ id: value.shortName
25
+ }),
26
+ icon: value.icon,
27
+ // @ts-ignore
28
+ onClick: function onClick() {
29
+ return AIChatStore.mode = key;
30
+ }
31
+ };
32
+ });
33
+ return /*#__PURE__*/React.createElement(Dropdown, {
34
+ menu: {
35
+ items: items
36
+ }
37
+ }, /*#__PURE__*/React.createElement("button", {
38
+ type: "button"
39
+ }, /*#__PURE__*/React.createElement("a", null, /*#__PURE__*/React.createElement(Space, null, AIModeMeta[snap.mode].icon, formatMessage({
40
+ id: AIModeMeta[snap.mode].shortName
41
+ })))));
42
+ }
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Dropdown } from "antd";
3
- import { useProducts } from "../../../../../hooks/useProducts";
4
- import { useLocale, useIntl, FormattedMessage } from "dumi";
3
+ import { useAntVConfig, useProducts } from "../../../../../hooks/useProducts";
4
+ import { useLocale, FormattedMessage } from "dumi";
5
5
  import styles from "./index.module.less";
6
6
  export function ChooseLib(props) {
7
7
  var _data$find;
@@ -15,11 +15,20 @@ export function ChooseLib(props) {
15
15
  var _useProducts = useProducts(),
16
16
  _useProducts$data = _useProducts.data,
17
17
  data = _useProducts$data === void 0 ? [] : _useProducts$data;
18
+ var _useAntVConfig = useAntVConfig(),
19
+ _useAntVConfig$data = _useAntVConfig.data,
20
+ _useAntVConfig$data2 = _useAntVConfig$data === void 0 ? {
21
+ library: []
22
+ } : _useAntVConfig$data,
23
+ _useAntVConfig$data2$ = _useAntVConfig$data2.library,
24
+ library = _useAntVConfig$data2$ === void 0 ? [] : _useAntVConfig$data2$;
18
25
  var onSelect = function onSelect(key) {
19
26
  onChange === null || onChange === void 0 || onChange(key);
20
27
  };
21
28
  var items = data.filter(function (item) {
22
- return item.lang === lang && ["G2", "F2", "S2", "G6", "X6", "AVA"].includes(item.title);
29
+ return item.lang === lang && library.map(function (l) {
30
+ return l.toUpperCase();
31
+ }).includes(item.title);
23
32
  }).map(function (item) {
24
33
  return {
25
34
  key: item.title,
@@ -35,7 +44,6 @@ export function ChooseLib(props) {
35
44
  }
36
45
  };
37
46
  });
38
- var intl = useIntl();
39
47
  return /*#__PURE__*/React.createElement(Dropdown, {
40
48
  menu: {
41
49
  items: items
@@ -11,7 +11,7 @@ function SendButton(props) {
11
11
  disabled = props.disabled,
12
12
  tip = props.tip;
13
13
  return /*#__PURE__*/React.createElement(Tooltip, {
14
- title: disabled ? tip : null
14
+ title: tip
15
15
  }, /*#__PURE__*/React.createElement("img", {
16
16
  className: classnames(styles.actionBtn, _defineProperty({}, styles.disabled, disabled)),
17
17
  onClick: function onClick() {
@@ -12,7 +12,7 @@ import { DatasourceCard } from "./DatasourceCard";
12
12
  import { useEventListener } from 'ahooks';
13
13
  import classnames from 'classnames';
14
14
  import _ from 'lodash';
15
- import React, { useState } from 'react';
15
+ import React, { useEffect, useRef, useState } from 'react';
16
16
  import styles from "./index.module.less";
17
17
  import { SendButton } from "./SendButton";
18
18
  import { ChooseLib } from "./ChooseLib";
@@ -21,6 +21,8 @@ import { ic } from "../../../../slots/hooks";
21
21
  import { useTypewriter } from "../../../../hooks/useTypewriter";
22
22
  import { authStore, showLoginModal } from "../../../../model/auth";
23
23
  import { useSnapshot } from "valtio";
24
+ import { AIChatStore } from "../../../../model/AIChat";
25
+ import { ModeSelectorDropdown } from "../ModeSelector/ModeSelectorDropdown";
24
26
  var PLACEHOLDER = {
25
27
  implement: 'ai.placeholder.implement',
26
28
  solve: 'ai.placeholder.solve'
@@ -33,15 +35,25 @@ export var PromptTextarea = /*#__PURE__*/React.memo(function PromptTextareaInner
33
35
  onConfirm = props.onConfirm,
34
36
  onCancel = props.onCancel,
35
37
  loading = props.loading,
36
- mode = props.mode,
37
- lib = props.lib,
38
- onLibChange = props.onLibChange,
39
38
  _props$showAction = props.showAction,
40
- showAction = _props$showAction === void 0 ? true : _props$showAction;
39
+ showAction = _props$showAction === void 0 ? true : _props$showAction,
40
+ _props$showModeSelect = props.showModeSelector,
41
+ showModeSelector = _props$showModeSelect === void 0 ? false : _props$showModeSelect,
42
+ _props$skipLoginCheck = props.skipLoginCheck,
43
+ skipLoginCheck = _props$skipLoginCheck === void 0 ? false : _props$skipLoginCheck,
44
+ sendButtonTip = props.sendButtonTip;
45
+ var snap = useSnapshot(AIChatStore);
41
46
  var authSnap = useSnapshot(authStore);
42
47
  var _useIntl = useIntl(),
43
48
  formatMessage = _useIntl.formatMessage;
44
-
49
+ var textareaRef = useRef(null);
50
+ var _useSiteData = useSiteData(),
51
+ themeConfig = _useSiteData.themeConfig;
52
+ useEffect(function () {
53
+ if (!themeConfig.isAntVSite && !snap.lib) {
54
+ AIChatStore.lib = themeConfig.title;
55
+ }
56
+ }, [themeConfig.isAntVSite, themeConfig.title]);
45
57
  // 将fileMeta状态移到组件内部管理
46
58
  var _useState = useState(null),
47
59
  _useState2 = _slicedToArray(_useState, 2),
@@ -54,8 +66,6 @@ export var PromptTextarea = /*#__PURE__*/React.memo(function PromptTextareaInner
54
66
  focus = _useState4[0],
55
67
  setFocus = _useState4[1];
56
68
  var isCompact = size === 'compact';
57
- var _useSiteData = useSiteData(),
58
- themeConfig = _useSiteData.themeConfig;
59
69
  var typedPlaceholder = useTypewriter({
60
70
  texts: [formatMessage({
61
71
  id: 'ai.placeholder.whatis'
@@ -92,14 +102,23 @@ export var PromptTextarea = /*#__PURE__*/React.memo(function PromptTextareaInner
92
102
  }
93
103
  var datasourceNode = renderDatasourceCard();
94
104
  var promptTextValid = Boolean(value);
105
+ var pureSend = function pureSend() {
106
+ if (promptTextValid) {
107
+ onConfirm === null || onConfirm === void 0 || onConfirm();
108
+ }
109
+ };
95
110
  var send = function send() {
96
- if (!authSnap.isAuthenticated) {
97
- showLoginModal();
111
+ // 如果跳过登录检查,直接发送
112
+ if (skipLoginCheck) {
113
+ pureSend();
98
114
  return;
99
115
  }
100
- if (promptTextValid) {
101
- onConfirm === null || onConfirm === void 0 || onConfirm();
116
+ // 否则检查登录状态
117
+ if (!authSnap.isAuthenticated) {
118
+ showLoginModal(pureSend);
119
+ return;
102
120
  }
121
+ pureSend();
103
122
  };
104
123
  useEventListener('keydown', function (event) {
105
124
  if (event.key === 'Enter') {
@@ -109,6 +128,8 @@ export var PromptTextarea = /*#__PURE__*/React.memo(function PromptTextareaInner
109
128
  send(); // 触发自定义事件
110
129
  }
111
130
  }
131
+ }, {
132
+ target: textareaRef
112
133
  });
113
134
  return /*#__PURE__*/React.createElement("div", {
114
135
  className: classnames(styles.container, _defineProperty(_defineProperty(_defineProperty({}, styles.active, focus), styles.compact, isCompact), styles.withDatasource, Boolean(datasourceNode))),
@@ -124,10 +145,11 @@ export var PromptTextarea = /*#__PURE__*/React.memo(function PromptTextareaInner
124
145
  },
125
146
  id: "prompt-textarea",
126
147
  className: classnames(styles.promptTextarea),
148
+ ref: textareaRef,
127
149
  placeholder:
128
150
  // (!isCompact && !themeConfig.isAntVSite && ic(themeConfig.metas.description)) ||
129
151
  !isCompact && !themeConfig.isAntVSite ? typedPlaceholder : formatMessage({
130
- id: _.get(PLACEHOLDER, mode, 'ai.placeholder.implement')
152
+ id: _.get(PLACEHOLDER, snap.mode, 'ai.placeholder.implement')
131
153
  }),
132
154
  value: value,
133
155
  onChange: function onChange(evt) {
@@ -138,10 +160,12 @@ export var PromptTextarea = /*#__PURE__*/React.memo(function PromptTextareaInner
138
160
  }, /*#__PURE__*/React.createElement("div", {
139
161
  className: styles.dataActions
140
162
  }, showAction && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ChooseLib, {
141
- value: lib,
142
- onChange: onLibChange,
143
- size: size
144
- }))), /*#__PURE__*/React.createElement("div", {
163
+ size: size,
164
+ value: snap.lib,
165
+ onChange: function onChange(s) {
166
+ return AIChatStore.lib = s;
167
+ }
168
+ })), showModeSelector && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(ModeSelectorDropdown, null))), /*#__PURE__*/React.createElement("div", {
145
169
  className: styles.actions
146
170
  }, loading ? /*#__PURE__*/React.createElement("img", {
147
171
  className: styles.actionBtn,
@@ -152,6 +176,6 @@ export var PromptTextarea = /*#__PURE__*/React.memo(function PromptTextareaInner
152
176
  disabled: !promptTextValid,
153
177
  tip: !promptTextValid ? formatMessage({
154
178
  id: 'ai.msgbox.send.tip'
155
- }) : undefined
179
+ }) : sendButtonTip
156
180
  }))));
157
181
  });
@@ -1,25 +1,28 @@
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
  import { Popover } from 'antd';
2
3
  import React from 'react';
3
4
  import styles from "./card.module.less";
4
5
  import { BarChartOutlined, QuestionCircleOutlined } from "@ant-design/icons";
5
6
  import { AIMode, AIModeMeta, COLORS } from "../../constant";
6
- import { FormattedMessage } from 'dumi';
7
+ import { FormattedMessage, useLocale } from 'dumi';
7
8
  export var Card = function Card(_ref) {
8
9
  var _AIModeMeta$tag;
9
10
  var item = _ref.item,
10
- index = _ref.index;
11
- var query = item.query,
12
- description = item.description,
11
+ index = _ref.index,
12
+ onClick = _ref.onClick;
13
+ var _item$query = item.query,
14
+ query = _item$query === void 0 ? {} : _item$query,
15
+ _item$description = item.description,
16
+ description = _item$description === void 0 ? {} : _item$description,
13
17
  _item$imageUrls = item.imageUrls,
14
18
  imageUrls = _item$imageUrls === void 0 ? [] : _item$imageUrls,
15
- link = item.link,
16
19
  tag = item.tag;
17
20
  var style = COLORS[index];
21
+ var locale = useLocale();
22
+ var lang = locale.id === 'zh' ? 'zh' : 'en';
18
23
  var handleClick = function handleClick(e) {
19
24
  e.stopPropagation();
20
- var urlObj = new URL(location.href);
21
- urlObj.hash = "";
22
- window.open(urlObj.toString(), '_blank');
25
+ onClick === null || onClick === void 0 || onClick();
23
26
  };
24
27
  var popoverContent = /*#__PURE__*/React.createElement("div", {
25
28
  className: styles.popoverContent
@@ -31,7 +34,7 @@ export var Card = function Card(_ref) {
31
34
  id: "ai.recommend.card.caseName"
32
35
  })), /*#__PURE__*/React.createElement("div", {
33
36
  className: styles.popoverValue
34
- }, query)), /*#__PURE__*/React.createElement("div", {
37
+ }, _typeof(query) === 'object' ? query[lang] : query)), /*#__PURE__*/React.createElement("div", {
35
38
  className: styles.popoverItem
36
39
  }, /*#__PURE__*/React.createElement("div", {
37
40
  className: styles.popoverLabel
@@ -39,7 +42,7 @@ export var Card = function Card(_ref) {
39
42
  id: "ai.recommend.card.description"
40
43
  })), /*#__PURE__*/React.createElement("div", {
41
44
  className: styles.popoverValue
42
- }, description)));
45
+ }, _typeof(description) === 'object' ? description[lang] : description)));
43
46
  return /*#__PURE__*/React.createElement(Popover, {
44
47
  content: popoverContent,
45
48
  placement: "top",
@@ -63,7 +66,7 @@ export var Card = function Card(_ref) {
63
66
  id: ((_AIModeMeta$tag = AIModeMeta[tag]) === null || _AIModeMeta$tag === void 0 ? void 0 : _AIModeMeta$tag.name) || tag
64
67
  }))), /*#__PURE__*/React.createElement("div", {
65
68
  className: styles.title
66
- }, query), /*#__PURE__*/React.createElement("div", {
69
+ }, _typeof(query) === 'object' ? query[lang] : query), /*#__PURE__*/React.createElement("div", {
67
70
  className: styles.imageContainer
68
71
  }, imageUrls.slice(0, 2).map(function (item, idx) {
69
72
  return /*#__PURE__*/React.createElement("img", {
@@ -100,7 +100,7 @@
100
100
  }
101
101
 
102
102
  .popoverContent {
103
- max-width: 372px;
103
+ max-width: 800px;
104
104
 
105
105
  .popoverItem {
106
106
  display: flex;
@@ -112,7 +112,7 @@
112
112
  color: #1d2129e6;
113
113
  line-height: 22px;
114
114
  font-weight: 500;
115
- min-width: 56px;
115
+ min-width: 80px;
116
116
  }
117
117
 
118
118
  .popoverValue {
@@ -9,45 +9,87 @@ 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, { useCallback, useEffect, useState } from '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";
16
16
  import RecommendJson from "./recommend.json";
17
17
  import classnames from "classnames";
18
- import { FormattedMessage } from 'dumi';
18
+ import { FormattedMessage, useSiteData } from 'dumi';
19
+ import { sample, sampleSize } from "lodash-es";
20
+ import { AIChatStore } from "../../../../model/AIChat";
21
+ import { useAntVConfig } from "../../../../hooks/useProducts";
22
+ import { getBaseSiteDataUrl } from "../../../../utils/env";
19
23
  export var RecommendCase = function RecommendCase(props) {
20
24
  var _useState = useState(false),
21
25
  _useState2 = _slicedToArray(_useState, 2),
22
26
  loading = _useState2[0],
23
27
  setLoading = _useState2[1];
28
+ var _useSiteData = useSiteData(),
29
+ themeConfig = _useSiteData.themeConfig;
24
30
  var _useState3 = useState([]),
25
31
  _useState4 = _slicedToArray(_useState3, 2),
26
32
  list = _useState4[0],
27
33
  setList = _useState4[1];
28
- var fetchList = useCallback( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
29
- var data;
30
- return _regeneratorRuntime().wrap(function _callee$(_context) {
31
- while (1) switch (_context.prev = _context.next) {
32
- case 0:
33
- try {
34
+ var _useAntVConfig = useAntVConfig(),
35
+ _useAntVConfig$data = _useAntVConfig.data,
36
+ _useAntVConfig$data2 = _useAntVConfig$data === void 0 ? {
37
+ library: []
38
+ } : _useAntVConfig$data,
39
+ _useAntVConfig$data2$ = _useAntVConfig$data2.library,
40
+ library = _useAntVConfig$data2$ === void 0 ? [] : _useAntVConfig$data2$;
41
+ var fetchList = /*#__PURE__*/function () {
42
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
43
+ var _themeConfig$ai, data, url;
44
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
45
+ while (1) switch (_context.prev = _context.next) {
46
+ case 0:
47
+ _context.prev = 0;
34
48
  setLoading(true);
49
+ data = [];
50
+ 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");
51
+ if (!url) {
52
+ _context.next = 10;
53
+ break;
54
+ }
55
+ _context.next = 7;
56
+ return fetch(url).then(function (res) {
57
+ return res.json();
58
+ });
59
+ case 7:
60
+ data = _context.sent;
61
+ _context.next = 11;
62
+ break;
63
+ case 10:
35
64
  data = RecommendJson;
36
- setList(data.slice(0, 4));
37
- } catch (err) {
38
- console.log(err);
39
- } finally {
65
+ case 11:
66
+ setList(sampleSize(data, 4));
67
+ _context.next = 18;
68
+ break;
69
+ case 14:
70
+ _context.prev = 14;
71
+ _context.t0 = _context["catch"](0);
72
+ setList(RecommendJson);
73
+ console.log(_context.t0);
74
+ case 18:
75
+ _context.prev = 18;
40
76
  setLoading(false);
41
- }
42
- case 1:
43
- case "end":
44
- return _context.stop();
45
- }
46
- }, _callee);
47
- })), [list]);
77
+ return _context.finish(18);
78
+ case 21:
79
+ case "end":
80
+ return _context.stop();
81
+ }
82
+ }, _callee, null, [[0, 14, 18, 21]]);
83
+ }));
84
+ return function fetchList() {
85
+ return _ref.apply(this, arguments);
86
+ };
87
+ }();
48
88
  useEffect(function () {
49
- fetchList();
50
- }, []);
89
+ if (library.length) {
90
+ fetchList();
91
+ }
92
+ }, [themeConfig.isAntVSite, library.length]);
51
93
  if (!list.length) {
52
94
  return null;
53
95
  }
@@ -59,14 +101,14 @@ export var RecommendCase = function RecommendCase(props) {
59
101
  className: styles.quickStart
60
102
  }, /*#__PURE__*/React.createElement(FormattedMessage, {
61
103
  id: "ai.recommend.title"
62
- })), /*#__PURE__*/React.createElement("span", {
104
+ })), (list === null || list === void 0 ? void 0 : list.length) > 4 ? /*#__PURE__*/React.createElement("span", {
63
105
  className: styles.refresh,
64
106
  onClick: function onClick() {
65
107
  return fetchList();
66
108
  }
67
109
  }, /*#__PURE__*/React.createElement(ReloadOutlined, null), /*#__PURE__*/React.createElement(FormattedMessage, {
68
110
  id: "ai.recommend.refresh"
69
- }))), /*#__PURE__*/React.createElement(Spin, {
111
+ })) : /*#__PURE__*/React.createElement(React.Fragment, null)), /*#__PURE__*/React.createElement(Spin, {
70
112
  spinning: loading,
71
113
  wrapperClassName: classnames(styles.listContainer, props.className)
72
114
  }, /*#__PURE__*/React.createElement("div", {
@@ -75,7 +117,14 @@ export var RecommendCase = function RecommendCase(props) {
75
117
  return /*#__PURE__*/React.createElement(Card, {
76
118
  key: item.caseId,
77
119
  item: item,
78
- index: index
120
+ index: index,
121
+ onClick: function onClick() {
122
+ var _props$onClick;
123
+ (_props$onClick = props.onClick) === null || _props$onClick === void 0 || _props$onClick.call(props, item);
124
+ if (item.tag) {
125
+ AIChatStore.mode = item.tag;
126
+ }
127
+ }
79
128
  });
80
129
  }))));
81
130
  };
@@ -1,7 +1,9 @@
1
1
  .container {
2
+ position: relative;
2
3
  margin-top: 32px;
3
4
  margin-left: auto;
4
5
  margin-right: auto;
6
+ z-index: 10;
5
7
  }
6
8
 
7
9
  .title {
@@ -2,41 +2,65 @@
2
2
  {
3
3
  "caseId": "1",
4
4
  "tag": "implement",
5
- "query": "一个城市过去五年来的年度降雨量分别是:2016年800毫米,2017年900毫米,2018年700毫米,2019年1000毫米,2020年1100毫米。使用折线图描绘这些数据。",
6
- "description": "自然语言描述需求,生成可视化代码",
5
+ "query": {
6
+ "zh": "你有一份公司多产品线销售数据:data = [ {month: '1月', productA: 12000, productB: 8500, productC: 15200}, {month: '2月', productA: 13500, productB: 9200, productC: 14800}, {month: '3月', productA: 15200, productB: 10800, productC: 16500}, {month: '4月', productA: 14800, productB: 11500, productC: 17200}, {month: '5月', productA: 16500, productB: 12200, productC: 18800}, {month: '6月', productA: 18200, productB: 13800, productC: 19500}, {month: '7月', productA: 19800, productB: 14500, productC: 20200}, {month: '8月', productA: 21500, productB: 15200, productC: 21800}, {month: '9月', productA: 20200, productB: 16800, productC: 22500}, {month: '10月', productA: 22800, productB: 17500, productC: 23200}, {month: '11月', productA: 24500, productB: 18200, productC: 24800}, {month: '12月', productA: 26200, productB: 19800, productC: 25500} ], 请绘制一个多折线图展示三条产品线的销售趋势变化,通过不同线型和颜色清晰区分各产品表现。 同时在最高点进行数据标注。",
7
+ "en": "You have multi-product line sales data for a company: data = [ {month: 'January', productA: 12000, productB: 8500, productC: 15200}, {month: 'February', productA: 13500, productB: 9200, productC: 14800}, {month: 'March', productA: 15200, productB: 10800, productC: 16500}, {month: 'April', productA: 14800, productB: 11500, productC: 17200}, {month: 'May', productA: 16500, productB: 12200, productC: 18800}, {month: 'June', productA: 18200, productB: 13800, productC: 19500}, {month: 'July', productA: 19800, productB: 14500, productC: 20200}, {month: 'August', productA: 21500, productB: 15200, productC: 21800}, {month: 'September', productA: 20200, productB: 16800, productC: 22500}, {month: 'October', productA: 22800, productB: 17500, productC: 23200}, {month: 'November', productA: 24500, productB: 18200, productC: 24800}, {month: 'December', productA: 26200, productB: 19800, productC: 25500} ]. Please draw a multi-line chart to show the sales trend changes of the three product lines, clearly distinguishing each product's performance through different line styles and colors. Also add data annotations at the highest points."
8
+ },
9
+ "description": {
10
+ "zh": "自然语言描述需求,生成可视化代码",
11
+ "en": "Natural language description of requirements, generate visualization code"
12
+ },
7
13
  "imageUrls": [
8
- "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*K5iUTrYme5QAAAAAQpAAAAgAemJ7AQ/original",
9
- "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*K5iUTrYme5QAAAAAQpAAAAgAemJ7AQ/original"
14
+ "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*zUKtR4U75fcAAAAAROAAAAgAemJ7AQ/original",
15
+ "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*zUKtR4U75fcAAAAAROAAAAgAemJ7AQ/original"
10
16
  ]
11
17
  },
12
18
  {
13
19
  "caseId": "2",
14
20
  "tag": "implement",
15
- "query": "使用文件中的数据,生成柱状图",
16
- "description": "多种数据源引入,专业图表生成,有数据就能生成图表。",
21
+ "query": {
22
+ "zh": "一家咖啡店的饮品销售比例为:咖啡 60%,茶 25%,果汁 15%。请用环图可视化这些饮品销售数据,并将色板调整为橙色系。",
23
+ "en": "A coffee shop's beverage sales ratio is: Coffee 60%, Tea 25%, Juice 15%. Please visualize these beverage sales data with a donut chart and adjust the color palette to orange tones."
24
+ },
25
+ "description": {
26
+ "zh": "自然语言描述需求,生成可视化代码",
27
+ "en": "Natural language description of requirements, generate visualization code"
28
+ },
17
29
  "imageUrls": [
18
- "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*K5iUTrYme5QAAAAAQpAAAAgAemJ7AQ/original",
19
- "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*K5iUTrYme5QAAAAAQpAAAAgAemJ7AQ/original"
30
+ "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*oMezTK-Yf2EAAAAAQmAAAAgAemJ7AQ/original",
31
+ "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*oMezTK-Yf2EAAAAAQmAAAAgAemJ7AQ/original"
20
32
  ]
21
33
  },
22
34
  {
23
35
  "caseId": "3",
24
- "tag": "implement",
25
- "query": "基于设计稿生成图表代码,还原视觉细节",
26
- "description": "基于设计稿生成图表代码,还原视觉细节",
36
+ "tag": "solve",
37
+ "query": {
38
+ "zh": "为什么配置了 state 没有生效?",
39
+ "en": "Why is the configured state not taking effect?"
40
+ },
41
+ "description": {
42
+ "zh": "精准定位并提供针对渲染异常、性能瓶颈及数据不匹配等问题的解决方案。",
43
+ "en": "Precisely locate and provide solutions for rendering anomalies, performance bottlenecks, and data mismatches."
44
+ },
27
45
  "imageUrls": [
28
- "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*K5iUTrYme5QAAAAAQpAAAAgAemJ7AQ/original",
29
- "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*K5iUTrYme5QAAAAAQpAAAAgAemJ7AQ/original"
46
+ "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*15mgQ4lA5CUAAAAASzAAAAgAemJ7AQ/original",
47
+ "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*15mgQ4lA5CUAAAAASzAAAAgAemJ7AQ/original"
30
48
  ]
31
49
  },
32
50
  {
33
51
  "caseId": "4",
34
52
  "tag": "solve",
35
- "query": "怎么配置堆叠面积图的描边为不同的颜色",
36
- "description": "精准定位并提供针对渲染异常、性能瓶颈及数据不匹配等问题的解决方案。",
53
+ "query": {
54
+ "zh": "数据标签互相遮挡了怎么办?",
55
+ "en": "What to do when data labels overlap each other?"
56
+ },
57
+ "description": {
58
+ "zh": "精准定位并提供针对渲染异常、性能瓶颈及数据不匹配等问题的解决方案。",
59
+ "en": "Precisely locate and provide solutions for rendering anomalies, performance bottlenecks, and data mismatches."
60
+ },
37
61
  "imageUrls": [
38
- "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*K5iUTrYme5QAAAAAQpAAAAgAemJ7AQ/original",
39
- "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*K5iUTrYme5QAAAAAQpAAAAgAemJ7AQ/original"
62
+ "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*thpQQIB3LG4AAAAASMAAAAgAemJ7AQ/original",
63
+ "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*thpQQIB3LG4AAAAASMAAAAgAemJ7AQ/original"
40
64
  ]
41
65
  }
42
66
  ]