This is an automated email from the ASF dual-hosted git repository.
liuhongyu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu-dashboard.git
The following commit(s) were added to refs/heads/master by this push:
new eed34ea0 Add a universal browser copying method (#569)
eed34ea0 is described below
commit eed34ea062203d4f3732f02eba157cde6290bf06
Author: renlu <[email protected]>
AuthorDate: Thu Feb 5 13:09:05 2026 +0800
Add a universal browser copying method (#569)
---
src/routes/Plugin/AiProxy/ApiKeys/index.js | 27 ++++++++-------------------
src/routes/Plugin/McpServer/JsonEditModal.js | 4 ++--
src/routes/Plugin/McpServer/McpConfigModal.js | 7 +++----
src/routes/Plugin/McpServer/ToolsModal.js | 4 ++--
src/utils/utils.js | 18 ++++++++++++++++++
5 files changed, 33 insertions(+), 27 deletions(-)
diff --git a/src/routes/Plugin/AiProxy/ApiKeys/index.js
b/src/routes/Plugin/AiProxy/ApiKeys/index.js
index d8812cca..2fe2b520 100644
--- a/src/routes/Plugin/AiProxy/ApiKeys/index.js
+++ b/src/routes/Plugin/AiProxy/ApiKeys/index.js
@@ -41,6 +41,7 @@ import {
batchDeleteAiProxyApiKeys,
batchEnableAiProxyApiKeys,
} from "../../../../services/api";
+import { clipboardCopy } from "../../../../utils/utils";
const { Search } = Input;
const { Title } = Typography;
@@ -308,25 +309,13 @@ function ApiKeysPage({
const newKey = res && res.data && res.data.proxyApiKey;
if (newKey) {
const copy = async (text) => {
- try {
- if (
- navigator &&
- navigator.clipboard &&
- navigator.clipboard.writeText
- ) {
- await navigator.clipboard.writeText(text);
- } else {
- const ta = document.createElement("textarea");
- ta.value = text;
- document.body.appendChild(ta);
- ta.select();
- document.execCommand("copy");
- document.body.removeChild(ta);
- }
- message.success(getIntlContent("SHENYU.COMMON.COPY") || "Copy");
- } catch (e) {
- message.warn("Copy failed");
- }
+ clipboardCopy(text)
+ .then(() => {
+ message.success(getIntlContent("SHENYU.COMMON.COPY") || "Copy");
+ })
+ .catch(() => {
+ message.warn("Copy failed");
+ });
};
Modal.success({
title: getIntlContent("APIPROXY.APIKEY.CREATE") || "Create API Key",
diff --git a/src/routes/Plugin/McpServer/JsonEditModal.js
b/src/routes/Plugin/McpServer/JsonEditModal.js
index 487942ff..361d7bc2 100644
--- a/src/routes/Plugin/McpServer/JsonEditModal.js
+++ b/src/routes/Plugin/McpServer/JsonEditModal.js
@@ -19,6 +19,7 @@ import React, { Component } from "react";
import { Button, Modal, message, Input, Tabs, Radio } from "antd";
import ReactJson from "react-json-view";
import { getIntlContent } from "../../../utils/IntlUtils";
+import { clipboardCopy } from "../../../utils/utils";
const { TextArea } = Input;
const { TabPane } = Tabs;
@@ -286,8 +287,7 @@ class JsonEditModal extends Component {
? this.state.flattenedText
: this.state.unifiedText;
- navigator.clipboard
- .writeText(textToCopy)
+ clipboardCopy(textToCopy)
.then(() => {
message.success(getIntlContent("SHENYU.MCP.JSON.EDIT.COPY.SUCCESS"));
})
diff --git a/src/routes/Plugin/McpServer/McpConfigModal.js
b/src/routes/Plugin/McpServer/McpConfigModal.js
index a0866519..a4b2abb3 100644
--- a/src/routes/Plugin/McpServer/McpConfigModal.js
+++ b/src/routes/Plugin/McpServer/McpConfigModal.js
@@ -19,6 +19,7 @@ import React, { Component } from "react";
import { Modal, Button, message, Typography, Divider, Input } from "antd";
import ReactJson from "react-json-view";
import { getIntlContent } from "../../../utils/IntlUtils";
+import { clipboardCopy } from "../../../utils/utils";
const { Title, Text } = Typography;
const { TextArea } = Input;
@@ -184,8 +185,7 @@ class McpConfigModal extends Component {
// 复制配置到剪贴板
handleCopyConfig = (config) => {
const configText = JSON.stringify(config, null, 2);
- navigator.clipboard
- .writeText(configText)
+ clipboardCopy(configText)
.then(() => {
message.success(getIntlContent("SHENYU.MCP.CONFIG.COPY.SUCCESS"));
})
@@ -196,8 +196,7 @@ class McpConfigModal extends Component {
// 复制JSON文本
copyJsonText = (text) => {
- navigator.clipboard
- .writeText(text)
+ clipboardCopy(text)
.then(() => {
message.success(getIntlContent("SHENYU.MCP.CONFIG.COPY.SUCCESS"));
})
diff --git a/src/routes/Plugin/McpServer/ToolsModal.js
b/src/routes/Plugin/McpServer/ToolsModal.js
index bc298598..421c9b2e 100644
--- a/src/routes/Plugin/McpServer/ToolsModal.js
+++ b/src/routes/Plugin/McpServer/ToolsModal.js
@@ -34,6 +34,7 @@ import TextArea from "antd/lib/input/TextArea";
import ReactJson from "react-json-view";
import styles from "../index.less";
import { getIntlContent } from "../../../utils/IntlUtils";
+import { clipboardCopy } from "../../../utils/utils";
const FormItem = Form.Item;
const { Option } = Select;
@@ -338,8 +339,7 @@ class AddModal extends Component {
};
handleCopyToClipboard = () => {
- navigator.clipboard
- .writeText(this.state.jsonText)
+ clipboardCopy(this.state.jsonText)
.then(() => {
message.success(getIntlContent("SHENYU.MCP.JSON.EDIT.COPY.SUCCESS"));
})
diff --git a/src/utils/utils.js b/src/utils/utils.js
index 7efb7153..75481a4b 100644
--- a/src/utils/utils.js
+++ b/src/utils/utils.js
@@ -243,3 +243,21 @@ export function formatTimeString(str) {
const f = formatTime(str);
return f ? f.format("HH:mm:ss") : "";
}
+
+export async function clipboardCopy(text) {
+ try {
+ if (navigator && navigator.clipboard && navigator.clipboard.writeText) {
+ await navigator.clipboard.writeText(text);
+ } else {
+ const ta = document.createElement("textarea");
+ ta.value = text;
+ document.body.appendChild(ta);
+ ta.select();
+ document.execCommand("copy");
+ document.body.removeChild(ta);
+ }
+ return true;
+ } catch (e) {
+ return false;
+ }
+}