Skip to content

Commit d51fee4

Browse files
authored
feat: Added the ability to obtain SDK installation information (#146)
* fix: 新增sdk安装信息 * feat: 新增sdk安装信息
1 parent abd2528 commit d51fee4

File tree

12 files changed

+5973
-15
lines changed

12 files changed

+5973
-15
lines changed

media/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
"less": "^4.2.0",
5656
"postcss": "^8",
5757
"prettier": "^3.3.3",
58+
"react-syntax-highlighter": "^15.5.0",
5859
"tailwindcss": "^3.4.10",
5960
"typescript": "^5",
6061
"vite": "^2.9.18"
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import React from "react";
2+
import { Row, Col, Typography, Tooltip } from "antd";
3+
import I18N from "../../../utils/I18N";
4+
import HighlightCode from "../../common/HighlightCode";
5+
import { PontUIService } from "../../../service/UIService";
6+
7+
export class SDKInfoProps {
8+
sdkDetail: any;
9+
lanKey: string;
10+
product: string;
11+
version: string;
12+
theme: string;
13+
}
14+
15+
export const SDKInfo: React.FC<SDKInfoProps> = (props) => {
16+
const { sdkDetail, lanKey } = props;
17+
18+
const getSdkInstall = (install, lan) => {
19+
if (["java", "java-async"].includes(lan)) {
20+
const arr = (install || "").split(":");
21+
return `<dependency>\n <groupId>${arr?.[0]}</groupId>\n <artifactId>${arr?.[1]}</artifactId>\n <version>${arr?.[2]}</version>\n</dependency>`;
22+
}
23+
24+
return install;
25+
};
26+
27+
const items = [
28+
{
29+
title: "SDK包名称:",
30+
content: (
31+
<Typography.Text className="text-xs text-[var(--vscode-textPreformat-foreground)]" copyable>
32+
{sdkDetail.package_name}
33+
</Typography.Text>
34+
),
35+
},
36+
{
37+
title: "SDK包版本:",
38+
content: (
39+
<Typography.Text className="text-xs text-[var(--vscode-textPreformat-foreground)]" copyable>
40+
{sdkDetail.last_version}
41+
</Typography.Text>
42+
),
43+
},
44+
{
45+
title: "SDK 包管理平台:",
46+
content: (
47+
<Typography.Text className="text-xs text-[var(--vscode-textPreformat-foreground)]" copyable>
48+
{sdkDetail.platform}
49+
</Typography.Text>
50+
),
51+
},
52+
// {
53+
// title: "相关链接:",
54+
// content: (
55+
// <a
56+
// href={`/api-tools/sdk/${product}?version=${version}&language=${
57+
// isOldSDK ? lanKey : `${lanKey}-tea`
58+
// }&tab=history-version&sdkReportVersion=${sdkDetail?.last_version}`}
59+
// target="_blank"
60+
// >
61+
// {I18N.main.explorer.SDKReport}
62+
// </a>
63+
// ),
64+
// },
65+
{
66+
title: "SDK 安装命令:",
67+
content: (
68+
<HighlightCode
69+
isShowCopyIcon
70+
source={getSdkInstall(sdkDetail?.install, lanKey)}
71+
language={lanKey === "java" ? "java" : "powershell"}
72+
otherTag={
73+
lanKey === "javascript" || lanKey === "typescript" ? (
74+
<Tooltip title={<span className="text-xs text-white">运行脚本</span>}>
75+
<div
76+
className="codicon codicon-debug-start mx-1 cursor-pointer"
77+
style={{
78+
fontSize: "14px",
79+
alignItems: lanKey?.includes("java") ? "baseline" : "center",
80+
marginLeft: "4px",
81+
display: "flex",
82+
}}
83+
onClick={() => {
84+
PontUIService.executeCli({
85+
code: getSdkInstall(sdkDetail?.install, lanKey),
86+
language: "node",
87+
});
88+
}}
89+
/>
90+
</Tooltip>
91+
) : null
92+
}
93+
></HighlightCode>
94+
),
95+
},
96+
];
97+
98+
const sdkInfoContent = (
99+
<div className="sdk-info-popover">
100+
{sdkDetail ? (
101+
<div className="sdk-demo-content-tip w-[full] text-xs">
102+
{items.map((item) => {
103+
return (
104+
<Row className="my-2 text-xs">
105+
<Col span={9} className="mb-1 text-xs">
106+
<span className="w-22 inline-block">{item.title}</span>
107+
</Col>
108+
<Col className="text-xs">{item.content}</Col>
109+
</Row>
110+
);
111+
})}
112+
<div className="text=[var(--vscode-editor-foreground)] mt-2 opacity-70">{I18N.main.explorer.syncDelay}</div>
113+
</div>
114+
) : null}
115+
</div>
116+
);
117+
118+
return sdkInfoContent;
119+
};
120+
121+
SDKInfo.defaultProps = new SDKInfoProps();

media/src/components/APIPage/TrySDK/TrySDK.tsx

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,26 @@ import { getVSCode } from "../../../utils/utils";
1010
import MonacoEditor from "../../common/MonacoEditor";
1111
import { APIPageContext } from "../context";
1212
import { DARA_SDK_LANGUAGES } from "./LanguageSwitcher";
13+
import { SDKInfo } from "./SDKInfo";
14+
import { Balloon } from "@alicloud/console-components";
15+
import { EditorLanguages } from "../../../types/EditorLanguages";
1316

1417
export class TrySDKProps {
1518
isExpand? = true;
1619
}
1720

1821
export const TrySDK: React.FC<TrySDKProps> = (props) => {
19-
// const daraSdkLannguages = SDKPublishInfo.getDaraLanguages(props.sdkInfos || [], product, version);
20-
const { theme, apiMeta, schemaForm, product, version, onDebug, changeMode, endpoints, regionId, mode } =
22+
const { sdkInfo, theme, apiMeta, schemaForm, product, version, endpoints, regionId, mode } =
2123
APIPageContext.useContainer();
22-
const [languageTab, setLanguageTab] = React.useState("Java");
24+
const [languageTab, setLanguageTab] = React.useState(EditorLanguages.TypeScript);
2325
const [sdkDemos, setSdkDemos] = React.useState(codes.demoSdk as any);
2426

2527
React.useEffect(() => {
2628
PontUIService.getLocalLanguage().then((res) => {
2729
if (res?.length) {
2830
setLanguageTab(res);
2931
} else {
30-
setLanguageTab("Java");
32+
setLanguageTab(EditorLanguages.Java);
3133
}
3234
});
3335
});
@@ -89,6 +91,8 @@ export const TrySDK: React.FC<TrySDKProps> = (props) => {
8991
return sdkDemos[languageTab?.toLocaleLowerCase()];
9092
}, [sdkDemos, languageTab]);
9193

94+
const sdkDetail = sdkInfo?.[`${languageTab.toLocaleLowerCase()}-tea`];
95+
9296
return React.useMemo(() => {
9397
return (
9498
<div className="sdk-demo-content h-[calc(100vh_-_194px)]">
@@ -98,9 +102,32 @@ export const TrySDK: React.FC<TrySDKProps> = (props) => {
98102
height={"100vh"}
99103
setLanguageTab={setLanguageTab}
100104
header={
101-
<div className="head-info">
102-
<Tag color="#3b5999">sdk | v2.0</Tag>
103-
</div>
105+
<>
106+
<div className="head-info">
107+
<Tag color="#3b5999">sdk | v2.0</Tag>
108+
</div>
109+
{sdkDetail ? (
110+
<Balloon
111+
align="b"
112+
triggerType="hover"
113+
style={{ maxWidth: "380px" }}
114+
closable={false}
115+
trigger={
116+
<span className="m-auto cursor-pointer text-xs text-[var(--vscode-textPreformat-foreground)]">
117+
SDK 安装信息
118+
</span>
119+
}
120+
>
121+
<SDKInfo
122+
sdkDetail={sdkDetail}
123+
theme={theme}
124+
lanKey={languageTab.toLocaleLowerCase()}
125+
product={product}
126+
version={version}
127+
></SDKInfo>
128+
</Balloon>
129+
) : null}
130+
</>
104131
}
105132
menuItems={[
106133
{

media/src/components/APIPage/context.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ import { createContainer } from "unstated-next";
55
import { SemixFormProps } from "../SemixFormRender";
66
import React from "react";
77
import { PontUIService } from "../../service/UIService";
8-
import { OpenAPIResponse, OpenAPIRequestResult } from "../../types/openAPI";
98
import { endpointsMocks } from "../../mocks/endpoints";
10-
import { getVSCode } from "../../utils/utils";
9+
import { lastSdkInfo } from "../../mocks/allSdkInfo";
1110

1211
export class APIPageState {
1312
/**
@@ -54,6 +53,7 @@ export class APIPageState {
5453
* vscode 主题
5554
*/
5655
theme?: string;
56+
sdkInfo?: any;
5757
}
5858

5959
export const useAPIPageContext = (initialState = {} as APIPageState): APIPageState => {
@@ -63,6 +63,7 @@ export const useAPIPageContext = (initialState = {} as APIPageState): APIPageSta
6363
const [regionId, setRegionId] = React.useState<string>("cn-hangzhou");
6464
const [profileInfo, setProfileInfo] = React.useState({});
6565
const [theme, setTheme] = React.useState("light");
66+
const [sdkInfo, setSdkInfo] = React.useState(lastSdkInfo);
6667

6768
React.useEffect(() => {
6869
PontUIService.getTheme()?.then((res) => {
@@ -77,7 +78,15 @@ export const useAPIPageContext = (initialState = {} as APIPageState): APIPageSta
7778
setEndpoints(res?.length ? res : endpointsMocks);
7879
});
7980
}
80-
}, [initialState.product]);
81+
if (initialState.product && initialState.version) {
82+
PontUIService.requestSDKInfo({
83+
product: initialState.product,
84+
version: initialState.version,
85+
}).then((res) => {
86+
setSdkInfo(res || lastSdkInfo);
87+
});
88+
}
89+
}, [initialState.product, initialState.version]);
8190

8291
React.useEffect(() => {
8392
PontUIService.requestProfiles().then((res) => {
@@ -105,6 +114,7 @@ export const useAPIPageContext = (initialState = {} as APIPageState): APIPageSta
105114
setRegionId,
106115
profileInfo,
107116
theme,
117+
sdkInfo,
108118
};
109119
};
110120

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/**
2+
* @author
3+
* @description 代码高亮组件
4+
*/
5+
6+
import { message, Tooltip } from "antd";
7+
import React, { useState } from "react";
8+
import SyntaxHighlighter from "react-syntax-highlighter";
9+
import { a11yLight, a11yDark } from "react-syntax-highlighter/dist/esm/styles/hljs";
10+
import { APIPageContext } from "../APIPage/context";
11+
import { getMonacoTheme } from "../utils";
12+
import { CheckOutlined, CopyOutlined } from "@ant-design/icons";
13+
14+
export interface HighlightCodeProps {
15+
language: string;
16+
source: string;
17+
otherTag?: any;
18+
hideCopyTag?: boolean;
19+
isShowCopyIcon?: boolean;
20+
}
21+
22+
export function copyToClipBoard(content: string, format: boolean = false): Promise<void> {
23+
return new Promise((resolve, reject) => {
24+
let inputEle = document.getElementById("clipboard") as HTMLTextAreaElement | HTMLInputElement;
25+
26+
const createElement = format ? "textarea" : "input";
27+
if (!inputEle) {
28+
inputEle = document.createElement(createElement);
29+
inputEle.id = "clipboard";
30+
document.body.appendChild(inputEle);
31+
}
32+
inputEle.value = content;
33+
inputEle.style.display = "block";
34+
35+
if (inputEle && inputEle.select) {
36+
inputEle.select();
37+
try {
38+
const isSuccessful = document.execCommand("copy");
39+
isSuccessful ? resolve() : reject();
40+
} catch (err) {
41+
reject(err);
42+
}
43+
}
44+
inputEle.style.display = "none";
45+
});
46+
}
47+
48+
const HighlightCode: React.FC<HighlightCodeProps> = (props) => {
49+
const [isCopy, setIsCopy] = useState(false);
50+
const { theme } = APIPageContext.useContainer();
51+
52+
return (
53+
<div
54+
className="workbench-code-copy flex"
55+
onMouseLeave={() => {
56+
setIsCopy(false);
57+
}}
58+
>
59+
<SyntaxHighlighter style={getMonacoTheme(theme) === "vs-dark" ? a11yDark : a11yLight} language={props?.language}>
60+
{props?.source}
61+
</SyntaxHighlighter>
62+
{props.otherTag ? props.otherTag : null}
63+
{props?.isShowCopyIcon && !isCopy ? (
64+
<Tooltip title={<span className="text-xs text-white">复制</span>}>
65+
<CopyOutlined
66+
style={{
67+
fontSize: "12px",
68+
alignItems: props.language?.includes("java") ? "baseline" : "center",
69+
marginLeft: "4px",
70+
}}
71+
onClick={() => {
72+
copyToClipBoard(props?.source, true);
73+
message.success("复制成功");
74+
setIsCopy(true);
75+
}}
76+
/>
77+
</Tooltip>
78+
) : (
79+
<CheckOutlined style={{ fontSize: "14px" }} />
80+
)}
81+
</div>
82+
);
83+
};
84+
85+
export default HighlightCode;

media/src/components/common/MonacoEditor.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
.left-area {
2323
display: flex;
2424
margin: auto 0;
25-
width: 200px;
25+
width: 300px;
2626
.head-info {
2727
margin: auto 8px;
2828
}

media/src/components/common/MonacoEditor.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,6 @@ export const MonacoEditor: React.FC<MonacoEditorProps> = (props) => {
9898
};
9999
}, []);
100100

101-
console.log(width);
102-
103101
return (
104102
<div className="editor-content">
105103
<div className="operations" ref={divRef}>
@@ -142,7 +140,7 @@ export const MonacoEditor: React.FC<MonacoEditorProps> = (props) => {
142140
) : null}
143141
{items?.length ? (
144142
<div className="menu-icon">
145-
{width < 400 ? (
143+
{width < 500 ? (
146144
<Dropdown menu={{ items }}>
147145
<Button onClick={(e) => e.preventDefault()}>
148146
<div className="codicon codicon-list-selection" />

media/src/main.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ html body {
7272
background-color: var(--vscode-editor-background);
7373
}
7474
}
75+
.anticon {
76+
color: var(--vscode-icon-foreground);
77+
}
7578
}
7679

7780
.pontx-ui-api {

0 commit comments

Comments
 (0)