@blocklet/pages-kit 0.2.317 → 0.2.319

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 (52) hide show
  1. package/lib/cjs/builtin/async/ai-runtime/locales/index.js +26 -0
  2. package/lib/cjs/builtin/async/ai-runtime/runtime-components/ChatOutput/MessageErrorView.js +2 -2
  3. package/lib/cjs/builtin/async/ai-runtime/runtime-components/GoogleSearch/GoogleSearchSourcesView.js +1 -1
  4. package/lib/cjs/builtin/async/ai-runtime/runtime-components/SimpleChat/index.js +13 -9
  5. package/lib/cjs/builtin/async/ai-runtime/runtime-components/V0/Input.js +66 -36
  6. package/lib/cjs/builtin/async/ai-runtime/runtime-components/V0/Output.js +190 -57
  7. package/lib/cjs/builtin/async/ai-runtime/runtime-components/V0/Page.js +236 -83
  8. package/lib/cjs/builtin/async/ai-runtime/runtime-components/V0/components/CodePreview.js +101 -0
  9. package/lib/cjs/builtin/async/ai-runtime/runtime-components/V0/components/ConfirmDialog.js +60 -0
  10. package/lib/cjs/builtin/async/ai-runtime/runtime-components/V0/components/Loading.js +152 -0
  11. package/lib/cjs/builtin/async/ai-runtime/runtime-components/V0/components/PropertiesSetting.js +80 -0
  12. package/lib/cjs/builtin/async/ai-runtime/runtime-components/V0/components/UserQuestion.js +32 -0
  13. package/lib/cjs/builtin/async/ai-runtime/runtime-components/V0/contexts/V0Runtime.js +54 -0
  14. package/lib/cjs/builtin/async/ai-runtime/runtime-components/V0/utils.js +13 -0
  15. package/lib/cjs/builtin/async/ai-runtime/state/session.js +52 -23
  16. package/lib/cjs/components/CustomComponentRenderer/state.js +23 -4
  17. package/lib/cjs/tsconfig.tsbuildinfo +1 -1
  18. package/lib/cjs/utils/inject-global-components-dump-json.js +1 -1
  19. package/lib/esm/builtin/async/ai-runtime/locales/index.js +26 -0
  20. package/lib/esm/builtin/async/ai-runtime/runtime-components/ChatOutput/MessageErrorView.js +2 -2
  21. package/lib/esm/builtin/async/ai-runtime/runtime-components/GoogleSearch/GoogleSearchSourcesView.js +1 -1
  22. package/lib/esm/builtin/async/ai-runtime/runtime-components/SimpleChat/index.js +16 -12
  23. package/lib/esm/builtin/async/ai-runtime/runtime-components/V0/Input.js +60 -30
  24. package/lib/esm/builtin/async/ai-runtime/runtime-components/V0/Output.js +191 -58
  25. package/lib/esm/builtin/async/ai-runtime/runtime-components/V0/Page.js +236 -83
  26. package/lib/esm/builtin/async/ai-runtime/runtime-components/V0/components/CodePreview.js +92 -0
  27. package/lib/esm/builtin/async/ai-runtime/runtime-components/V0/components/ConfirmDialog.js +55 -0
  28. package/lib/esm/builtin/async/ai-runtime/runtime-components/V0/components/Loading.js +144 -0
  29. package/lib/esm/builtin/async/ai-runtime/runtime-components/V0/components/PropertiesSetting.js +75 -0
  30. package/lib/esm/builtin/async/ai-runtime/runtime-components/V0/components/UserQuestion.js +26 -0
  31. package/lib/esm/builtin/async/ai-runtime/runtime-components/V0/contexts/V0Runtime.js +49 -0
  32. package/lib/esm/builtin/async/ai-runtime/runtime-components/V0/utils.js +9 -0
  33. package/lib/esm/builtin/async/ai-runtime/state/session.js +52 -23
  34. package/lib/esm/components/CustomComponentRenderer/state.js +22 -4
  35. package/lib/esm/tsconfig.tsbuildinfo +1 -1
  36. package/lib/esm/utils/inject-global-components-dump-json.js +1 -1
  37. package/lib/types/builtin/async/ai-runtime/api/session.d.ts +1 -0
  38. package/lib/types/builtin/async/ai-runtime/locales/index.d.ts +26 -0
  39. package/lib/types/builtin/async/ai-runtime/runtime-components/ChatOutput/MessageErrorView.d.ts +2 -1
  40. package/lib/types/builtin/async/ai-runtime/runtime-components/V0/Input.d.ts +1 -1
  41. package/lib/types/builtin/async/ai-runtime/runtime-components/V0/components/CodePreview.d.ts +20 -0
  42. package/lib/types/builtin/async/ai-runtime/runtime-components/V0/components/ConfirmDialog.d.ts +6 -0
  43. package/lib/types/builtin/async/ai-runtime/runtime-components/V0/components/Loading.d.ts +3 -0
  44. package/lib/types/builtin/async/ai-runtime/runtime-components/V0/components/PropertiesSetting.d.ts +6 -0
  45. package/lib/types/builtin/async/ai-runtime/runtime-components/V0/components/UserQuestion.d.ts +3 -0
  46. package/lib/types/builtin/async/ai-runtime/runtime-components/V0/contexts/V0Runtime.d.ts +16 -0
  47. package/lib/types/builtin/async/ai-runtime/runtime-components/V0/utils.d.ts +7 -0
  48. package/lib/types/builtin/async/ai-runtime/state/session.d.ts +11 -3
  49. package/lib/types/components/CustomComponentRenderer/state.d.ts +1 -0
  50. package/lib/types/tsconfig.tsbuildinfo +1 -1
  51. package/lib/types/types/core.d.ts +2 -1
  52. package/package.json +7 -7
@@ -426,7 +426,7 @@ export default function FormDemo() {
426
426
  import { Icon } from '@blocklet/pages-kit/builtin/iconify/react';
427
427
 
428
428
  export default function TablerSuccessIcon() {
429
- return <Icon icon="tabler:check" />;
429
+ return <Icon icon="tabler:check" fontSize={24} color="rgba(75, 85, 99, 1)"/>;
430
430
  }
431
431
  `,
432
432
  },
@@ -34,6 +34,7 @@ export const translations = {
34
34
  rename: 'Rename',
35
35
  delete: 'Delete',
36
36
  confirmDelete: 'Confirm Delete?',
37
+ confirm: 'Confirm',
37
38
  noData: 'No {data} yet',
38
39
  createObject: 'Create {object}',
39
40
  title: 'Title',
@@ -92,6 +93,18 @@ export const translations = {
92
93
  send: 'Send',
93
94
  session: 'Session',
94
95
  loadMore: 'Load More',
96
+ v0: {
97
+ title: 'AIGNE v0',
98
+ description: 'AIGNE v0 is an AI-based code tool that can help you generate code quickly.',
99
+ noData: 'No conversation information yet, click the button below to start generating!',
100
+ deleteSessionTitle: 'Delete Conversation Information',
101
+ deleteSessionTip: 'Are you sure you want to delete this Conversation Information?',
102
+ propertiesSetting: 'Properties Setting',
103
+ propertiesSettingTip: 'This function is used for debugging components and does not affect the final code',
104
+ cannotSetPropertiesTip: 'Failed to parse PROPERTIES_SCHEMA, this code cannot be set properties',
105
+ codePreview: 'Code Preview',
106
+ codePreviewTip: 'Here is the code preview, you can view the generated code, and editing is not supported yet.',
107
+ },
95
108
  },
96
109
  zh: {
97
110
  by: '作者',
@@ -128,6 +141,7 @@ export const translations = {
128
141
  rename: '重命名',
129
142
  delete: '删除',
130
143
  confirmDelete: '确定删除?',
144
+ confirm: '确定',
131
145
  noData: '暂无{data}',
132
146
  createObject: '创建{object}',
133
147
  title: '标题',
@@ -186,5 +200,17 @@ export const translations = {
186
200
  send: '发送',
187
201
  session: '会话',
188
202
  loadMore: '加载更多',
203
+ v0: {
204
+ title: 'AIGNE v0',
205
+ description: 'AIGNE v0 是一个基于人工智能的代码工具,可以帮助您快速生成代码。',
206
+ noData: '暂无生成记录,点击下方按钮开始生成吧!',
207
+ deleteSessionTitle: '删除生成记录',
208
+ deleteSessionTip: '确定要删除此生成记录吗?',
209
+ propertiesSetting: '属性设置',
210
+ propertiesSettingTip: '此功能用于调试组件,不影响最终代码',
211
+ cannotSetPropertiesTip: '解析 PROPERTIES_SCHEMA 失败,此代码无法进行属性设置',
212
+ codePreview: '代码预览',
213
+ codePreviewTip: '以下是代码预览,您可以查看生成的代码,目前还不支持编辑。',
214
+ },
189
215
  },
190
216
  };
@@ -2,12 +2,12 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Alert, Box } from '@mui/material';
3
3
  import { useLocaleContext } from '../../../../locale';
4
4
  import MarkdownRenderer from '../../components/MarkdownRenderer';
5
- export default function MessageErrorView({ error }) {
5
+ export default function MessageErrorView({ error, sx }) {
6
6
  const { t } = useLocaleContext();
7
7
  if (!error)
8
8
  return null;
9
9
  if (error.status === 401) {
10
10
  return (_jsx(Box, { className: "ai-chat-message-error", children: _jsx(Box, { className: "message-response", children: _jsx(MarkdownRenderer, { children: t('requireLogin') }) }) }));
11
11
  }
12
- return (_jsx(Alert, { className: "ai-chat-message-error", severity: "error", sx: { mr: 5 }, children: error.message }));
12
+ return (_jsx(Alert, { className: "ai-chat-message-error", severity: "error", sx: Object.assign({ mr: 5 }, sx), children: error.message }));
13
13
  }
@@ -8,7 +8,7 @@ const searchResultSchema = Joi.object({
8
8
  organic_results: Joi.array().items(Joi.object({
9
9
  title: Joi.string().required(),
10
10
  link: Joi.string().required(),
11
- snippet: Joi.string().required(),
11
+ snippet: Joi.string().empty([null, '']),
12
12
  favicon: Joi.string().empty([null, '']),
13
13
  source: Joi.string().empty([null, '']),
14
14
  })),
@@ -9,8 +9,8 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
- import { ThemeProvider, alpha, createTheme, useTheme } from '@mui/material';
12
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
13
+ import { Box, CircularProgress, ThemeProvider, alpha, createTheme, useTheme } from '@mui/material';
14
14
  import { useEffect, useMemo } from 'react';
15
15
  import { useScrollToBottom } from 'react-scroll-to-bottom';
16
16
  import SimpleHeader from '../../components/Header/SimpleHeader';
@@ -20,7 +20,7 @@ import { useActiveAgent } from '../../contexts/ActiveAgent';
20
20
  import { ComponentPreferencesProvider } from '../../contexts/ComponentPreferences';
21
21
  import CurrentAgentProvider from '../../contexts/CurrentAgent';
22
22
  import { useHeaderMenu } from '../../hooks/use-header-menu';
23
- import { useAutoLoadSessionState, useCurrentSessionState } from '../../state/session';
23
+ import { useAutoLoadSessionState, useCurrentSessionState, useSessionState } from '../../state/session';
24
24
  import BackgroundImage from './BackgroundImage';
25
25
  import InputsView from './InputsView';
26
26
  import MessagesView from './MessagesView';
@@ -56,14 +56,18 @@ function SimpleChatView() {
56
56
  if (running)
57
57
  scrollToBottom({ behavior: 'smooth' });
58
58
  }, [scrollToBottom, running]);
59
+ const messages = useCurrentSessionState((s) => s === null || s === void 0 ? void 0 : s.messages);
60
+ const sessionLoading = useCurrentSessionState((s) => s === null || s === void 0 ? void 0 : s.loading);
61
+ const loading = useSessionState((s) => s === null || s === void 0 ? void 0 : s.loading) || sessionLoading;
59
62
  useHeaderMenu();
60
- return (_jsxs(SimpleLayout, { children: [_jsx(SimpleHeader, { px: 2 }), _jsx(CurrentAgentProvider, { agentId: activeAgentId, children: _jsx(MessagesView, { className: "aigne-outputs aigne-simple-chat-outputs", flexGrow: 1, pb: 10 }) }), _jsx(CurrentAgentProvider, { agentId: activeAgentId, children: _jsx(InputsView, { className: "aigne-inputs aigne-simple-chat-inputs", sx: {
61
- position: 'sticky',
62
- bottom: 0,
63
- p: 2,
64
- zIndex: 10,
65
- borderRadius: 1,
66
- bgcolor: (theme) => alpha(theme.palette.background.paper, 0.7),
67
- backdropFilter: 'blur(10px)',
68
- } }) })] }));
63
+ return (_jsxs(SimpleLayout, { px: 0, children: [_jsx(SimpleHeader, { px: 4 }), loading ? (_jsx(Box, { textAlign: "center", my: 10, children: _jsx(CircularProgress, { size: 24 }) })) : (_jsxs(_Fragment, { children: [_jsx(CurrentAgentProvider, { agentId: activeAgentId, children: _jsx(MessagesView, { className: "aigne-outputs aigne-simple-chat-outputs", flexGrow: (messages === null || messages === void 0 ? void 0 : messages.length) ? 1 : 0, pb: (messages === null || messages === void 0 ? void 0 : messages.length) ? 10 : 2, px: { xs: 2, sm: 3 } }) }), _jsx(CurrentAgentProvider, { agentId: activeAgentId, children: _jsx(InputsView, { className: "aigne-inputs aigne-simple-chat-inputs", sx: {
64
+ position: 'sticky',
65
+ bottom: 0,
66
+ py: 2,
67
+ px: { xs: 2, sm: 3 },
68
+ zIndex: 10,
69
+ borderRadius: 1,
70
+ bgcolor: (theme) => alpha(theme.palette.background.paper, 0.7),
71
+ backdropFilter: 'blur(10px)',
72
+ } }) })] }))] }));
69
73
  }
@@ -9,7 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  };
10
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
11
  import { cx } from '@emotion/css';
12
- import { Box, FormLabel, InputAdornment, Stack, ThemeProvider, createTheme, formLabelClasses, outlinedInputClasses, styled, useTheme, } from '@mui/material';
12
+ import { Icon } from '@iconify/react';
13
+ import { Box, Button, FormLabel, InputAdornment, Stack, ThemeProvider, createTheme, formLabelClasses, outlinedInputClasses, styled, useTheme, } from '@mui/material';
13
14
  import isEmpty from 'lodash/isEmpty';
14
15
  import omit from 'lodash/omit';
15
16
  import { useEffect, useMemo, useState } from 'react';
@@ -18,14 +19,20 @@ import { useLocaleContext } from '../../../../locale';
18
19
  import AgentInputField from '../../components/AgentInputField';
19
20
  import LoadingButton from '../../components/LoadingButton';
20
21
  import { useCurrentAgent } from '../../contexts/CurrentAgent';
22
+ import { useOpeningQuestions } from '../../hooks/use-appearances';
21
23
  import { useRuntimeState } from '../../state/runtime';
22
- import { useCurrentSessionState } from '../../state/session';
24
+ import { useCurrentSessionState, useSessionState } from '../../state/session';
23
25
  import { isValidInput } from '../../utils/agent-inputs';
24
- export default function AutoForm({ submitText, inlineLabel, autoFillLastForm = true, submitInQuestionField, chatMode, }) {
26
+ import { useV0RuntimeContext } from './contexts/V0Runtime';
27
+ export default function V0Input({ submitText, inlineLabel, autoFillLastForm = false, submitInQuestionField = true, chatMode = true, }) {
28
+ var _a, _b;
25
29
  const { t } = useLocaleContext();
26
30
  const { aid, agent } = useCurrentAgent();
31
+ const opening = useOpeningQuestions();
27
32
  const { execute } = useRuntimeState();
28
- const running = useCurrentSessionState((s) => s === null || s === void 0 ? void 0 : s.running);
33
+ const { running } = useCurrentSessionState((s) => s) || {};
34
+ const { createSession, currentSessionId } = useSessionState((s) => s) || {};
35
+ const { setCurrentMessageTaskId } = useV0RuntimeContext();
29
36
  const parameters = useMemo(() => {
30
37
  var _a;
31
38
  return (_a = agent.parameters) === null || _a === void 0 ? void 0 : _a.filter(isValidInput).map((i) => {
@@ -42,47 +49,70 @@ export default function AutoForm({ submitText, inlineLabel, autoFillLastForm = t
42
49
  }
43
50
  }, [defaultForm, autoFillLastForm, form, chatMode]);
44
51
  const onSubmit = (parameters) => __awaiter(this, void 0, void 0, function* () {
52
+ if (!(parameters === null || parameters === void 0 ? void 0 : parameters.question))
53
+ return;
54
+ if (!currentSessionId) {
55
+ yield createSession({
56
+ name: parameters === null || parameters === void 0 ? void 0 : parameters.question,
57
+ });
58
+ }
59
+ // in session page, send message
45
60
  yield execute({
46
61
  aid,
47
62
  parameters,
48
63
  onResponseStart: () => {
64
+ setCurrentMessageTaskId(undefined);
49
65
  if (chatMode)
50
66
  form.resetField('question', { defaultValue: '' });
51
67
  },
52
68
  });
53
69
  });
54
- return (_jsx(ThemeProvider, { theme: theme, children: _jsxs(Form, { component: "form", className: cx('form', `label-position-${inlineLabel ? 'start' : 'top'}`), onSubmit: form.handleSubmit(onSubmit), children: [parameters === null || parameters === void 0 ? void 0 : parameters.map((parameter, index) => {
55
- const { key, required } = parameter !== null && parameter !== void 0 ? parameter : {};
56
- return (_jsx(Box, { children: _jsx(Controller, { control: form.control, name: key, rules: {
57
- required,
58
- min: parameter.type === 'number' && typeof parameter.min === 'number'
59
- ? { value: parameter.min, message: '' }
60
- : undefined,
61
- max: parameter.type === 'number' && typeof parameter.max === 'number'
62
- ? { value: parameter.max, message: '' }
63
- : undefined,
64
- minLength: parameter.type === 'string' && typeof parameter.minLength === 'number'
65
- ? { value: parameter.minLength, message: '' }
66
- : undefined,
67
- maxLength: parameter.type === 'string' && typeof parameter.maxLength === 'number'
68
- ? { value: parameter.maxLength, message: '' }
69
- : undefined,
70
- }, render: ({ field, fieldState }) => {
71
- var _a;
72
- return (_jsxs(Stack, { className: "form-item", children: [parameter.label && _jsx(FormLabel, { children: parameter.label }), _jsx(AgentInputField, { inputRef: field.ref, autoFocus: index === 0, size: "small", hiddenLabel: true, fullWidth: true, label: undefined, parameter: parameter, maxRows: !(parameter === null || parameter === void 0 ? void 0 : parameter.type) || (parameter === null || parameter === void 0 ? void 0 : parameter.type) === 'string' ? 5 : undefined, value: field.value || '', onChange: (value) => field.onChange({ target: { value } }), error: Boolean(fieldState.error), helperText: ((_a = fieldState.error) === null || _a === void 0 ? void 0 : _a.message) || (parameter === null || parameter === void 0 ? void 0 : parameter.helper), InputProps: parameter.key === 'question' && submitInQuestionField
73
- ? {
74
- endAdornment: (_jsx(InputAdornment, { position: "end", sx: { py: 3, mr: -0.75, alignSelf: 'flex-end' }, children: _jsx(LoadingButton, { type: "submit", variant: "contained", loading: running, sx: { borderRadius: 100 }, children: submitText }) })),
75
- }
76
- : undefined })] }));
77
- } }) }, parameter.id));
78
- }), !(submitInQuestionField && (parameters === null || parameters === void 0 ? void 0 : parameters.some((i) => i.key === 'question'))) && (_jsx(LoadingButton, { type: "submit", variant: "contained", loading: running, sx: { height: 40 }, children: submitText || t('generate') }))] }) }));
70
+ return (_jsxs(ThemeProvider, { theme: theme, children: [!currentSessionId && ((_a = opening === null || opening === void 0 ? void 0 : opening.questions) === null || _a === void 0 ? void 0 : _a.length) && (_jsx(Stack, { sx: {
71
+ flexDirection: 'row',
72
+ gap: 1,
73
+ mb: 1,
74
+ }, children: (_b = opening === null || opening === void 0 ? void 0 : opening.questions) === null || _b === void 0 ? void 0 : _b.map((item) => {
75
+ const { title, parameters, id } = item;
76
+ const question = (parameters === null || parameters === void 0 ? void 0 : parameters.questions) || title;
77
+ return (_jsx(Button, { variant: "outlined", size: "small", endIcon: _jsx(Icon, { icon: "tabler:arrow-down-right", style: {
78
+ marginLeft: -4,
79
+ } }), onClick: () => {
80
+ form.reset(Object.assign({}, parameters));
81
+ onSubmit(Object.assign({}, parameters));
82
+ }, children: question }, id));
83
+ }) })), _jsxs(Form, { id: "v0-input", component: "form", className: cx('form', `label-position-${inlineLabel ? 'start' : 'top'}`), onSubmit: form.handleSubmit(onSubmit), children: [parameters === null || parameters === void 0 ? void 0 : parameters.map((parameter, index) => {
84
+ const { key, required } = parameter !== null && parameter !== void 0 ? parameter : {};
85
+ return (_jsx(Box, { children: _jsx(Controller, { control: form.control, name: key, rules: {
86
+ required,
87
+ min: parameter.type === 'number' && typeof parameter.min === 'number'
88
+ ? { value: parameter.min, message: '' }
89
+ : undefined,
90
+ max: parameter.type === 'number' && typeof parameter.max === 'number'
91
+ ? { value: parameter.max, message: '' }
92
+ : undefined,
93
+ minLength: parameter.type === 'string' && typeof parameter.minLength === 'number'
94
+ ? { value: parameter.minLength, message: '' }
95
+ : undefined,
96
+ maxLength: parameter.type === 'string' && typeof parameter.maxLength === 'number'
97
+ ? { value: parameter.maxLength, message: '' }
98
+ : undefined,
99
+ }, render: ({ field, fieldState }) => {
100
+ var _a;
101
+ return (_jsxs(Stack, { className: "form-item", children: [parameter.label && _jsx(FormLabel, { children: parameter.label }), _jsx(AgentInputField, { inputRef: field.ref, autoFocus: index === 0, size: "small", hiddenLabel: true, fullWidth: true, label: undefined, parameter: parameter, maxRows: !(parameter === null || parameter === void 0 ? void 0 : parameter.type) || (parameter === null || parameter === void 0 ? void 0 : parameter.type) === 'string' ? 5 : undefined, value: field.value || '', onChange: (value) => field.onChange({ target: { value } }), error: Boolean(fieldState.error), helperText: ((_a = fieldState.error) === null || _a === void 0 ? void 0 : _a.message) || (parameter === null || parameter === void 0 ? void 0 : parameter.helper), InputProps: parameter.key === 'question' && submitInQuestionField
102
+ ? {
103
+ endAdornment: (_jsx(InputAdornment, { position: "end", sx: { py: 3, mr: -0.75, alignSelf: 'flex-end' }, children: _jsx(LoadingButton, { type: "submit", variant: "contained", loading: running, sx: { borderRadius: 100 }, children: submitText || t('generate') }) })),
104
+ }
105
+ : undefined })] }));
106
+ } }) }, parameter.id));
107
+ }), !(submitInQuestionField && (parameters === null || parameters === void 0 ? void 0 : parameters.some((i) => i.key === 'question'))) && (_jsx(LoadingButton, { type: "submit", variant: "contained", loading: running, sx: { height: 40 }, children: submitText || t('generate') }))] })] }));
79
108
  }
109
+ const autoSetLastParameters = false;
80
110
  function useInitialFormValues() {
81
111
  const { agent } = useCurrentAgent();
82
112
  const lastMessage = useCurrentSessionState((s) => { var _a; return (_a = s === null || s === void 0 ? void 0 : s.messages) === null || _a === void 0 ? void 0 : _a.at(-1); });
83
113
  const [lastInputs, setLastInputs] = useState();
84
114
  useEffect(() => {
85
- if (!lastInputs) {
115
+ if (autoSetLastParameters && !lastInputs) {
86
116
  const lastParameters = lastMessage === null || lastMessage === void 0 ? void 0 : lastMessage.parameters;
87
117
  if (!isEmpty(lastParameters))
88
118
  setLastInputs(lastParameters);
@@ -1,73 +1,206 @@
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
1
10
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
11
+ import Toast from '@arcblock/ux/lib/Toast';
2
12
  import { Icon } from '@iconify/react';
3
- import { Box, Drawer, IconButton, Skeleton, Stack } from '@mui/material';
4
- import { useState } from 'react';
5
- import CustomComponentRenderer from '../../../../../components/CustomComponentRenderer';
13
+ import { Alert, Box, Button, ButtonGroup, Drawer, Stack, Typography } from '@mui/material';
14
+ import groupBy from 'lodash/groupBy';
15
+ import { Suspense, useRef, useState } from 'react';
16
+ import { transpileAndLoadScript } from '../../../../../components/CustomComponentRenderer';
17
+ import { useLocaleContext } from '../../../../locale';
6
18
  import MarkdownRenderer from '../../components/MarkdownRenderer';
7
19
  import ShareActions from '../../components/ShareActions';
8
20
  import { useCurrentMessage } from '../../contexts/CurrentMessage';
9
- import MessageErrorView from '../ChatOutput/MessageErrorView';
10
21
  import MessageMetadataRenderer from '../ChatOutput/MessageMetadataRenderer';
11
- const codeField = 'code';
22
+ import { CodeRenderByMessageMemo as CodeRenderByMessage, getCurrentCodeByTaskId } from './components/CodePreview';
23
+ import Loading from './components/Loading';
24
+ import PropertiesSetting from './components/PropertiesSetting';
25
+ import UserQuestion from './components/UserQuestion';
26
+ import { useV0RuntimeContext } from './contexts/V0Runtime';
27
+ const DEFAULT_DESKTOP_SX = {
28
+ width: '100%',
29
+ height: '100%',
30
+ };
12
31
  export default function V0Output() {
13
32
  var _a, _b;
14
33
  const { message } = useCurrentMessage();
34
+ const propertiesSettingRef = useRef(null);
35
+ const { propertiesValueMap, setPropertiesValueMap } = useV0RuntimeContext();
36
+ const [code, setCode] = useState('');
37
+ const { t, locale } = useLocaleContext();
38
+ const [codePreviewExtraSx, setCodePreviewExtraSx] = useState(DEFAULT_DESKTOP_SX);
15
39
  const objects = (_a = message.result) === null || _a === void 0 ? void 0 : _a.objects;
16
- const { error } = message;
40
+ const { taskId, parameters } = message;
17
41
  const isMessageLoading = (message.loading || !message.result) && !message.error;
18
- return (_jsxs(Stack, { gap: 2, sx: {
19
- py: 2,
20
- }, children: [error && _jsx(MessageErrorView, { error: error }), isMessageLoading && (_jsx(Stack, { sx: {
21
- flex: 1,
22
- }, children: _jsx(Skeleton, { variant: "rectangular", sx: {
23
- height: 400,
24
- borderRadius: 1,
25
- } }) })), objects === null || objects === void 0 ? void 0 : objects.map((item) => {
26
- // @ts-ignore
27
- const code = item.data[codeField];
28
- return (_jsx(Box, { flex: 1, sx: {
29
- display: 'flex',
30
- justifyContent: 'center',
31
- alignItems: 'center',
32
- }, children: _jsx(CodePreview, { code: code }) }));
33
- }), objects === null || objects === void 0 ? void 0 : objects.map((item) => _jsx(MessageMetadataRenderer, { object: item.data })), !isMessageLoading && ((_b = message.result) === null || _b === void 0 ? void 0 : _b.content) && (_jsx(ShareActions, { direction: "row", justifyContent: "flex-end", sx: { mt: 2 } }))] }));
34
- }
35
- function CodePreview({ code }) {
36
- const [showCode, setShowCode] = useState(false);
37
- if (!code)
38
- return null;
42
+ const disabled = isMessageLoading || !(objects === null || objects === void 0 ? void 0 : objects.length) || message.error;
43
+ const responsiveSx = {
44
+ backgroundColor: 'white',
45
+ borderColor: 'rgba(0, 0, 0, 0.1) !important',
46
+ };
47
+ const tooltipOptions = [
48
+ {
49
+ key: 'Desktop',
50
+ icon: 'tabler:device-desktop',
51
+ props: {
52
+ sx: Object.assign({}, responsiveSx),
53
+ onClick: () => setCodePreviewExtraSx(DEFAULT_DESKTOP_SX),
54
+ },
55
+ group: 'responsive',
56
+ },
57
+ {
58
+ key: 'Tablet',
59
+ icon: 'tabler:device-tablet',
60
+ props: {
61
+ sx: Object.assign({}, responsiveSx),
62
+ onClick: () => setCodePreviewExtraSx({
63
+ width: '768px',
64
+ height: '1024px',
65
+ }),
66
+ },
67
+ group: 'responsive',
68
+ },
69
+ {
70
+ key: 'Mobile',
71
+ icon: 'tabler:device-mobile',
72
+ props: {
73
+ sx: Object.assign({}, responsiveSx),
74
+ onClick: () => setCodePreviewExtraSx({
75
+ width: '375px',
76
+ height: '667px',
77
+ }),
78
+ },
79
+ group: 'responsive',
80
+ },
81
+ // setting
82
+ {
83
+ key: 'Setting',
84
+ icon: 'tabler:settings-2',
85
+ props: {
86
+ disabled,
87
+ sx: Object.assign({}, responsiveSx),
88
+ onClick: (e) => __awaiter(this, void 0, void 0, function* () {
89
+ var _c;
90
+ const { taskid: taskId } = ((_c = e === null || e === void 0 ? void 0 : e.currentTarget) === null || _c === void 0 ? void 0 : _c.dataset) || {};
91
+ const currentCode = getCurrentCodeByTaskId(message, taskId);
92
+ try {
93
+ yield transpileAndLoadScript(currentCode).then((m) => {
94
+ var _a, _b;
95
+ if (typeof (m === null || m === void 0 ? void 0 : m.PROPERTIES_SCHEMA) === 'object' && (m === null || m === void 0 ? void 0 : m.PROPERTIES_SCHEMA.length)) {
96
+ const schemaDefaultValues = Object.fromEntries(m.PROPERTIES_SCHEMA.map((item) => {
97
+ const { key, locales } = item;
98
+ const currentLocale = (locales === null || locales === void 0 ? void 0 : locales[locale]) || (locales === null || locales === void 0 ? void 0 : locales.en);
99
+ return [key, currentLocale === null || currentLocale === void 0 ? void 0 : currentLocale.defaultValue];
100
+ }));
101
+ const defaultValues = Object.assign(Object.assign({}, schemaDefaultValues), (_a = propertiesValueMap[taskId]) === null || _a === void 0 ? void 0 : _a[locale]);
102
+ // format default values
103
+ m.PROPERTIES_SCHEMA.forEach((item) => {
104
+ const { key, type } = item;
105
+ if (type === 'json' && typeof defaultValues[key] === 'object') {
106
+ try {
107
+ defaultValues[key] = JSON.stringify(defaultValues[key], null, 2);
108
+ }
109
+ catch (error) {
110
+ // ignore error
111
+ }
112
+ }
113
+ });
114
+ // @ts-ignore
115
+ (_b = propertiesSettingRef.current) === null || _b === void 0 ? void 0 : _b.open({
116
+ schema: m.PROPERTIES_SCHEMA,
117
+ onSubmit: (values) => {
118
+ const realValues = {};
119
+ m.PROPERTIES_SCHEMA.forEach((item) => {
120
+ const { key, type } = item;
121
+ if (type === 'json' && typeof values[key] === 'string') {
122
+ try {
123
+ realValues[key] = JSON.parse(values[key]);
124
+ return;
125
+ }
126
+ catch (error) {
127
+ // ignore error
128
+ }
129
+ }
130
+ realValues[key] = values[key];
131
+ });
132
+ setPropertiesValueMap(Object.assign(Object.assign({}, propertiesValueMap), { [taskId]: Object.assign(Object.assign({}, propertiesValueMap[taskId]), { [locale]: realValues }) }));
133
+ },
134
+ defaultValues,
135
+ });
136
+ return;
137
+ }
138
+ throw new Error('No properties schema found');
139
+ });
140
+ }
141
+ catch (error) {
142
+ // ignore error
143
+ // send cannot set properties message
144
+ Toast.info(t('v0.cannotSetPropertiesTip'));
145
+ }
146
+ }),
147
+ },
148
+ group: 'setting',
149
+ },
150
+ {
151
+ key: 'CodePreview',
152
+ icon: code ? 'tabler:layout-board' : 'tabler:code',
153
+ buttonText: code ? 'Canvas' : 'Code',
154
+ props: {
155
+ disabled,
156
+ variant: 'contained',
157
+ color: 'primary',
158
+ onClick: (e) => {
159
+ var _a;
160
+ const { taskid: taskId } = ((_a = e === null || e === void 0 ? void 0 : e.currentTarget) === null || _a === void 0 ? void 0 : _a.dataset) || {};
161
+ setCode(getCurrentCodeByTaskId(message, taskId));
162
+ },
163
+ },
164
+ group: 'codePreview',
165
+ },
166
+ ];
39
167
  return (_jsxs(Stack, { sx: {
40
- flex: 1,
41
- }, children: [_jsx(Box, { sx: {
42
- display: 'flex',
43
- justifyContent: 'flex-end',
44
- }, children: _jsx(IconButton, { onClick: () => setShowCode((prev) => !prev), sx: {
45
- color: 'textColor',
46
- }, children: _jsx(Icon, { icon: showCode ? 'tabler:layout-sidebar' : 'tabler:code' }) }) }), _jsx(Stack, { gap: 2, sx: {
168
+ p: 2,
169
+ gap: 2,
170
+ height: '100%',
171
+ display: 'flex',
172
+ justifyContent: 'flex-start',
173
+ alignItems: 'center',
174
+ flexDirection: 'column',
175
+ }, children: [_jsxs(Stack, { sx: {
47
176
  display: 'flex',
48
- flexDirection: 'row',
177
+ justifyContent: 'space-between',
49
178
  alignItems: 'center',
50
- justifyContent: 'center',
51
- }, children: _jsx(Box, { sx: {
52
- display: 'flex',
53
- justifyContent: 'center',
54
- alignItems: 'center',
55
- }, children: _jsx(CustomComponentRenderer, { componentId: "mock-dev-component", dev: {
56
- components: {
57
- 'mock-dev-component': {
58
- data: {
59
- id: 'mock-dev-component',
60
- createdAt: '',
61
- updatedAt: '',
62
- renderer: {
63
- type: 'react-component',
64
- script: code,
65
- },
66
- },
67
- },
68
- },
69
- } }) }) }), _jsx(Drawer, { anchor: "right", open: showCode, onClose: () => setShowCode(false), children: _jsx(Box, { sx: {
70
- p: 2,
71
- maxWidth: '40vw',
72
- }, children: _jsx(MarkdownRenderer, { children: `\`\`\`typescript\n${code}\n\`\`\`` }) }) })] }));
179
+ width: '100%',
180
+ gap: 1.5,
181
+ flexDirection: 'row',
182
+ }, children: [_jsx(UserQuestion, { question: parameters === null || parameters === void 0 ? void 0 : parameters.question }), _jsx(Box, { sx: {
183
+ display: 'flex',
184
+ alignItems: 'center',
185
+ gap: 1.5,
186
+ }, children: Object.entries(groupBy(tooltipOptions, 'group')).map(([group, options]) => {
187
+ return (_jsx(ButtonGroup, { variant: "text", color: "inherit", size: "small", sx: {
188
+ borderColor: 'rgba(0, 0, 0, 0.1) !important',
189
+ border: 1,
190
+ }, children: options.map((option) => {
191
+ const { icon, key, props, buttonText } = option;
192
+ return (_jsxs(Button, Object.assign({ "data-taskId": taskId }, props, { children: [_jsx(Icon, { icon: icon, fontSize: 22 }), buttonText && _jsx(Box, { sx: { ml: 1 }, children: buttonText })] }), key));
193
+ }) }, group));
194
+ }) })] }), _jsx(Box, { sx: Object.assign({ display: 'flex', justifyContent: 'center', overflow: 'hidden', backgroundColor: 'white', borderRadius: 1 }, codePreviewExtraSx), children: _jsx(CodeRenderByMessage, { message: message, zoom: 1, sx: {
195
+ overflowX: 'auto',
196
+ overflowY: 'auto',
197
+ scrollbarWidth: 'thin',
198
+ scrollbarColor: 'grey transparent',
199
+ }, propertiesValueMap: propertiesValueMap }) }), objects === null || objects === void 0 ? void 0 : objects.map((item, index) => _jsx(MessageMetadataRenderer, { object: item.data }, index)), !isMessageLoading && ((_b = message.result) === null || _b === void 0 ? void 0 : _b.content) && (_jsx(ShareActions, { direction: "row", justifyContent: "flex-end", sx: { mt: 2 } })), _jsxs(Suspense, { fallback: _jsx(Loading, {}), children: [_jsx(Drawer, { anchor: "right", open: !!code, onClose: () => setCode(''), children: _jsxs(Box, { sx: {
200
+ p: 2,
201
+ maxWidth: '60vw',
202
+ }, children: [_jsx(Typography, { variant: "h6", sx: {
203
+ lineHeight: 2,
204
+ mb: 1,
205
+ }, children: t('v0.codePreview') }), _jsx(Alert, { severity: "info", sx: { mb: 2 }, children: t('v0.codePreviewTip') }), _jsx(MarkdownRenderer, { children: `\`\`\`typescript\n${code}\n\`\`\`` })] }) }), _jsx(PropertiesSetting, { ref: propertiesSettingRef })] })] }));
73
206
  }