Skip to content

Commit a69db0f

Browse files
authored
Merge pull request #319 from easyops-cn/steve/tsx-control-nodes
feat(): support fragment and :forEach
2 parents 2332fda + 11db4f2 commit a69db0f

File tree

22 files changed

+504
-168
lines changed

22 files changed

+504
-168
lines changed

bricks/ai-portal/src/cruise-canvas/legacy-reducers/jobs.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@ function getJobGeneratedView(
221221
const view = (
222222
result.code.includes("<eo-view") ? parseJsx : parseTsx
223223
)(result.code);
224+
if (view.errors.length > 0) {
225+
// eslint-disable-next-line no-console
226+
console.warn("Parsed generated view with errors:", view.errors);
227+
}
224228
return { viewId: result.viewId, ...view };
225229
}
226230
return result;
@@ -248,6 +252,10 @@ function getJobStaticDataView(
248252
const view = parseTsx(part.data.code, {
249253
withContexts: ["RESPONSE"],
250254
});
255+
if (view.errors.length > 0) {
256+
// eslint-disable-next-line no-console
257+
console.warn("Parsed static data view with errors:", view.errors);
258+
}
251259
return { viewId: part.data.viewId, ...view };
252260
} catch (e) {
253261
// eslint-disable-next-line no-console

bricks/ai-portal/src/cruise-canvas/reducers/tasks.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ function getJobGeneratedView(
233233
const view = (
234234
result.code.includes("<eo-view") ? parseJsx : parseTsx
235235
)(result.code);
236+
if (view.errors.length > 0) {
237+
// eslint-disable-next-line no-console
238+
console.warn("Parsed generated view with errors:", view.errors);
239+
}
236240
return { viewId: result.viewId, ...view };
237241
} catch {
238242
// Do nothing, continue to next part
@@ -258,6 +262,10 @@ function getJobStaticDataView(
258262
const view = parseTsx(part.data.code, {
259263
withContexts: ["RESPONSE"],
260264
});
265+
if (view.errors.length > 0) {
266+
// eslint-disable-next-line no-console
267+
console.warn("Parsed static data view with errors:", view.errors);
268+
}
261269
return { viewId: part.data.viewId, ...view };
262270
} catch (e) {
263271
// eslint-disable-next-line no-console

bricks/ai-portal/src/cruise-canvas/useConversationGraph.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export function useConversationGraph(
3030

3131
const {
3232
list,
33+
roots: jobRoots,
3334
map: jobMap,
3435
levels: jobLevels,
3536
downstreamMap,
@@ -45,6 +46,23 @@ export function useConversationGraph(
4546

4647
const nodeIds: string[] = [];
4748

49+
if (jobRoots.includes(jobId)) {
50+
const userInput = messages
51+
?.find((msg) => msg.role === "user")
52+
?.parts?.find((part) => part.type === "text")?.text;
53+
if (userInput !== undefined) {
54+
const requirementId = `requirement:${jobId}`;
55+
nodes.push({
56+
type: "requirement",
57+
id: requirementId,
58+
content: userInput,
59+
});
60+
nodeIds.push(requirementId);
61+
jobNodesMap.set(jobId, nodeIds);
62+
continue;
63+
}
64+
}
65+
4866
if (job.instruction) {
4967
const instructionNodeId = `instruction:${jobId}`;
5068
nodes.push({
@@ -110,8 +128,9 @@ export function useConversationGraph(
110128
});
111129
}
112130
const source = nodeIds[nodeIds.length - 1];
113-
for (const target of downstreams) {
114-
edges.push({ source, target });
131+
for (const targetJobId of downstreams) {
132+
const targetNodeIds = jobNodesMap.get(targetJobId)!;
133+
edges.push({ source, target: targetNodeIds[0] });
115134
}
116135
}
117136

bricks/ai-portal/src/cruise-canvas/utils/jsx-converters/convertButton.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import type { ButtonProps } from "@next-shared/jsx-storyboard/lib/components.js"
44

55
export default function convertButton(component: Component): BrickConf {
66
const { properties } = component;
7-
const props = properties as ButtonProps;
7+
const props = properties as ButtonProps & {
8+
textContent?: string;
9+
};
810
return {
911
brick: "eo-button",
1012
properties: {
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import type { BrickConf } from "@next-core/types";
2+
import type { Component } from "@next-shared/jsx-storyboard";
3+
import type { CardProps } from "@next-shared/jsx-storyboard/lib/components.js";
4+
5+
export default function convertCard(component: Component): BrickConf {
6+
const { properties } = component;
7+
const { title, textContent } = properties as CardProps & {
8+
textContent?: string;
9+
};
10+
return {
11+
brick: "eo-card",
12+
properties: {
13+
themeVariant: "elevo",
14+
cardTitle: title,
15+
background: false,
16+
...(textContent ? { textContent } : null),
17+
},
18+
};
19+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import type { BrickConf } from "@next-core/types";
2+
import type { Component } from "@next-shared/jsx-storyboard";
3+
4+
export default function convertForEach(component: Component): BrickConf {
5+
const { properties } = component;
6+
const { dataSource } = properties as {
7+
dataSource?: unknown;
8+
};
9+
return {
10+
brick: ":forEach",
11+
dataSource,
12+
};
13+
}

bricks/ai-portal/src/cruise-canvas/utils/jsx-converters/convertJsx.ts

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,16 @@ import convertModal from "./convertModal";
1717
import convertToolbar from "./convertToolbar";
1818
import convertText from "./convertText";
1919
import type { ConstructedView } from "../../interfaces";
20+
import convertCard from "./convertCard";
21+
import convertForEach from "./convertForEach";
2022

2123
export async function convertJsx(
2224
result: ConstructedView,
2325
options: ConvertViewOptions
2426
) {
25-
const convert = async (component: Component) => {
27+
const convert = async (
28+
component: Component
29+
): Promise<BrickConf | BrickConf[]> => {
2630
let brick: BrickConf | null = null;
2731
switch (component.name) {
2832
case "List":
@@ -37,6 +41,9 @@ export async function convertJsx(
3741
case "eo-descriptions":
3842
brick = await convertDescriptions(component, result, options);
3943
break;
44+
case "Card":
45+
brick = await convertCard(component);
46+
break;
4047
case "Dashboard":
4148
case "eo-dashboard":
4249
brick = await convertDashboard(component, result, options);
@@ -86,10 +93,16 @@ export async function convertJsx(
8693
convertComponentName(component.name)
8794
);
8895
break;
96+
case "ForEach":
97+
brick = await convertForEach(component);
98+
break;
99+
default:
100+
// eslint-disable-next-line no-console
101+
console.error("Unsupported component:", component.name);
89102
}
90103

91104
if (!brick) {
92-
return null;
105+
return [];
93106
}
94107

95108
// Set [data-component-id] for the brick
@@ -105,7 +118,16 @@ export async function convertJsx(
105118
if (component.children?.length) {
106119
brick.children = (
107120
await Promise.all(component.children.map(convert))
108-
).filter(Boolean) as BrickConf[];
121+
).flat();
122+
123+
if (component.name === "Card" && brick.children.length > 1) {
124+
brick.children = [
125+
{
126+
brick: "eo-content-layout",
127+
children: brick.children,
128+
},
129+
];
130+
}
109131
}
110132

111133
return brick;
@@ -142,9 +164,7 @@ export async function convertJsx(
142164
},
143165
];
144166

145-
const children = (await Promise.all(result.components.map(convert))).filter(
146-
Boolean
147-
) as BrickConf[];
167+
const children = (await Promise.all(result.components.map(convert))).flat();
148168

149169
const needBox = result.components.every((component) =>
150170
[
@@ -168,7 +188,7 @@ export async function convertJsx(
168188
}
169189

170190
function mergeTexts(
171-
items: (
191+
...items: (
172192
| { type: "text"; text: string }
173193
| { type: "expression"; value: unknown }
174194
)[]

bricks/ai-portal/src/cruise-canvas/utils/jsx-converters/convertModal.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ import type { ModalProps } from "@next-shared/jsx-storyboard/lib/components.js";
44

55
export default function convertModal(component: Component): BrickConf {
66
const { properties } = component;
7-
const { title, confirmText, cancelText } = properties as Partial<ModalProps>;
7+
const { title, confirmText, cancelText, textContent } =
8+
properties as Partial<ModalProps> & {
9+
textContent?: string;
10+
};
811
return {
912
brick: "eo-modal",
1013
portal: true,
@@ -14,6 +17,7 @@ export default function convertModal(component: Component): BrickConf {
1417
confirmText: confirmText,
1518
cancelText: cancelText,
1619
keyboard: true,
20+
...(textContent ? { textContent } : null),
1721
},
1822
};
1923
}

bricks/ai-portal/src/cruise-canvas/utils/jsx-converters/convertTable.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default async function convertTable(
1414
): Promise<BrickConf> {
1515
const { properties } = component;
1616
const { dataSource, size, columns, rowKey, pagination, ...restProps } =
17-
properties as Omit<TableProps<any, boolean>, "dataSource"> & {
17+
properties as Omit<TableProps<any>, "dataSource"> & {
1818
dataSource: string | object;
1919
size?: "small" | "medium" | "large";
2020
pagination?: boolean;

bricks/ai-portal/src/cruise-canvas/utils/jsx-converters/convertText.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ export default function convertText(component: Component): BrickConf {
88
};
99
return {
1010
brick: "span",
11-
portal: true,
1211
properties: {
1312
textContent,
1413
},

0 commit comments

Comments
 (0)