From 91e2dc13cb834843c79533d750152e12a75377fc Mon Sep 17 00:00:00 2001 From: heiheihei <1395202740@qq.com> Date: Tue, 2 Sep 2025 12:50:52 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=E4=B8=B4=E6=97=B6=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E8=99=9A=E6=8B=9F=E6=BB=9A=E5=8A=A8=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ModelVis/app/src/ModelStructure/Properties/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/index.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/index.tsx index 464585055..21cf04aa0 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/index.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/index.tsx @@ -59,7 +59,7 @@ const Properties = () => { useEffect(() => { initProperties() - }, [model, current, t]) + }, [model, current]) return
Date: Tue, 2 Sep 2025 12:57:52 +0800 Subject: [PATCH 2/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=99=9A=E6=8B=9F?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E5=BC=82=E5=B8=B8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ModelVis/app/src/ModelStructure/Properties/index.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/index.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/index.tsx index 21cf04aa0..db3a0e2e3 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/index.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/index.tsx @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { useI18n } from "hooks" +import { useI18n, useLanguage } from "hooks" import { useAtomValue } from "jotai" import { joinCls } from "libs" import { @@ -33,7 +33,8 @@ const Properties = () => { const [isShow, setIsShow] = useState(false) const [propertyContent, setPropertyContent] = useState() const [contextValue, setContextValue] = useState({ nodes: {}, parameters: {}, t }) - + const [appLanguage] = useLanguage() + const initProperties = () => { if (!current || !model) { setIsShow(false) @@ -59,7 +60,7 @@ const Properties = () => { useEffect(() => { initProperties() - }, [model, current]) + }, [model, current, appLanguage.code]) return
Date: Tue, 2 Sep 2025 14:58:24 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E6=BC=94=E7=A4=BA=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ModelVis/app/src/ModelStructure/Fsg/FsgTable.tsx | 2 +- .../ModelVis/app/src/hooks/useNewPathForLayout.ts | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Fsg/FsgTable.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Fsg/FsgTable.tsx index 8a96e7959..654dda428 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Fsg/FsgTable.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Fsg/FsgTable.tsx @@ -240,7 +240,7 @@ export const FsgTable = () => { } setSelectedRow(record) jumpFsg(record) - workerInitFsgs([record.nodes[record.fsgIndex]]) + workerInitFsgs(isFullDisplay ? record.nodes : [record.nodes[record.fsgIndex]]) } } } diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/hooks/useNewPathForLayout.ts b/plugins/mindstudio-insight-plugins/ModelVis/app/src/hooks/useNewPathForLayout.ts index 6c33986ae..016ea2e31 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/hooks/useNewPathForLayout.ts +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/hooks/useNewPathForLayout.ts @@ -54,6 +54,12 @@ export const useNewPathForLayout = (): LayoutNewPath => { const start = performance.now() setLoading(true) + history.clear() + setSubgraphs({}) + setCurrentGraphAtom({ children: [], name: '', paths: [] }) + setAllGraphAtom({ children: [], name: '', paths: [] }) + setDynamicVisible(false) + setFsgsVisible(false) let res try { res = await invoke("layout_bin", { path }) @@ -69,12 +75,9 @@ export const useNewPathForLayout = (): LayoutNewPath => { }) if (res) { - history.clear() - setSubgraphs({}) setCurrentGraphAtom(res) setAllGraphAtom(res) - setDynamicVisible(false) - setFsgsVisible(false) + if (translate.x !== 0 || translate.y !== 0) setTranslate({ x: 0, y: 0 -- Gitee From b191a4a9b3c0c6b2d3ec0b2fc56d65c230db8d25 Mon Sep 17 00:00:00 2001 From: heiheihei <1395202740@qq.com> Date: Tue, 2 Sep 2025 15:39:41 +0800 Subject: [PATCH 4/6] =?UTF-8?q?=E6=BC=94=E7=A4=BA=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ModelVis/app/src/ModelStructure/Fsg/FsgTable.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Fsg/FsgTable.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Fsg/FsgTable.tsx index 654dda428..4768a5c07 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Fsg/FsgTable.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Fsg/FsgTable.tsx @@ -274,6 +274,7 @@ export const FsgTable = () => { }} > Date: Tue, 2 Sep 2025 17:19:39 +0800 Subject: [PATCH 5/6] =?UTF-8?q?=E6=BC=94=E7=A4=BA=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ModelVis/app/src/features/Project.tsx | 5 +- .../ModelVis/app/src/features/Toolbar.tsx | 8 +- .../ModelVis/app/src/ui/VirtualScroll.tsx | 112 +++++++++--------- 3 files changed, 68 insertions(+), 57 deletions(-) diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Project.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Project.tsx index e3459551c..3169fc4b9 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Project.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Project.tsx @@ -129,6 +129,9 @@ export const RecentProj = ({ path, toggle }: ProjectLineProps) => { toggle(recentProjectList[0]) } } + const getFileType = (path:string)=> { + return path.split(".").pop()?.[0].toUpperCase() ?? "A" + } return
diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Toolbar.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Toolbar.tsx index 7b2bec969..907bb6a59 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Toolbar.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Toolbar.tsx @@ -27,9 +27,11 @@ export const Toolbar = () =>
-
- - +
+
+
+ +
diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ui/VirtualScroll.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ui/VirtualScroll.tsx index 0ae68c818..8d0a53976 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ui/VirtualScroll.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ui/VirtualScroll.tsx @@ -36,30 +36,37 @@ type ItemSize = { measured: boolean // 是否已测量 } -const ESTIMATED_ITEM_HEIGHT = 20; +const ESTIMATED_ITEM_HEIGHT = 20 export const VirtualScroll = ({ items, containerHeight, buffer = 10, className = '' }: VirtualScrollProps) => { const containerRef = useRef(null) const itemElementsRef = useRef<(HTMLDivElement | null)[]>([]) const sizesRef = useRef(items.map(() => ({ size: ESTIMATED_ITEM_HEIGHT, measured: false }))) const [height, setHeight] = useState(containerHeight ?? 400) + const [totalHeight, setTotalHeight] = useState(0) const [visibleRange, setVisibleRange] = useState({ start: 0, end: Math.min(items.length, Math.ceil(height / ESTIMATED_ITEM_HEIGHT) + buffer * 2) }) // 获取累计偏移量(用于 transform 和定位) - const getOffset = (index: number): number => { - let offset = 0; + const getOffset = useCallback((index: number): number => { + let offset = 0 for (let i = 0; i < index; i++) { - offset += sizesRef.current[i]?.size ?? ESTIMATED_ITEM_HEIGHT; + offset += sizesRef.current[i]?.size ?? ESTIMATED_ITEM_HEIGHT } - return offset; - } + return offset + }, []) // 总高度 = 所有 item 高度之和 - const getTotalHeight = useCallback((): number => { - return getOffset(items.length) + const updateTotalHeight = useCallback(() => { + const newTotal = getOffset(items.length) + setTotalHeight(prev => { + if (Math.abs(newTotal - prev) > 0.1) { + return newTotal + } + return prev + }) }, [items, getOffset]) // 二分查找:找到第一个 `offset >= target` 的索引 @@ -67,8 +74,8 @@ export const VirtualScroll = ({ items, containerHeight, buffer = 10, className = let start = 0 let end = items.length while (start < end) { - const mid = Math.floor((start + end) / 2); - const midOffset = getOffset(mid); + const mid = Math.floor((start + end) / 2) + const midOffset = getOffset(mid) if (midOffset < target) { start = mid + 1 } else { @@ -76,24 +83,26 @@ export const VirtualScroll = ({ items, containerHeight, buffer = 10, className = } } return start - }, [items, getOffset]) + }, + [items, getOffset] + ) // 测量指定索引的元素高度 - const measureItem = (index: number) => { - if (index >= sizesRef.current.length) { + const measureItem = useCallback((index: number): boolean => { + if (index < 0 || index >= items.length) { return false } const ele = itemElementsRef.current[index] if (ele) { const actualHeight = ele.offsetHeight const current = sizesRef.current[index] - if (!current.measured || current.size !== actualHeight) { // 高度变化 + if (!current.measured || Math.abs(current.size - actualHeight) > 0.1) { sizesRef.current[index] = { size: actualHeight, measured: true } return true } } return false - } + }, [items]) // 更新可见范围 const updateVisibleRange = useCallback(() => { @@ -105,19 +114,15 @@ export const VirtualScroll = ({ items, containerHeight, buffer = 10, className = const scrollTop = container.scrollTop const containerHeight = container.clientHeight - // 找到第一个在视口内的项 const start = Math.max(0, findIndex(scrollTop) - buffer) - // 找到最后一个在视口内的项 const end = Math.min(items.length, findIndex(scrollTop + containerHeight) + buffer) - setVisibleRange({ start, end }) + setVisibleRange(prev => (prev.start !== start || prev.end !== end ? { start, end } : prev)) }, [items, buffer, findIndex]) // 滚动处理 const handleScroll = useCallback(() => { - requestAnimationFrame(() => { - updateVisibleRange() - }) + requestAnimationFrame(updateVisibleRange) }, [updateVisibleRange]) // 初始渲染 & 滚动监听 @@ -135,7 +140,8 @@ export const VirtualScroll = ({ items, containerHeight, buffer = 10, className = // 如果有高度更新,重新计算可见范围 if (didUpdate) { - updateVisibleRange() + updateTotalHeight() + requestAnimationFrame(updateVisibleRange) } container.addEventListener('scroll', handleScroll, { passive: true }) @@ -145,30 +151,21 @@ export const VirtualScroll = ({ items, containerHeight, buffer = 10, className = return () => { container.removeEventListener('scroll', handleScroll) } - }, [visibleRange.start, visibleRange.end, handleScroll, updateVisibleRange]) - - // 动态设置 ref 并测量 - const setItemRef = useCallback((el: HTMLDivElement | null, index: number) => { - if (el === null) { - return - } - itemElementsRef.current[index] = el - }, []) + }, [visibleRange, handleScroll, measureItem, updateTotalHeight, updateVisibleRange]) + // 监听父容器尺寸变化 useLayoutEffect(() => { const parent = containerRef.current?.parentElement if (parent === undefined || parent === null) { return } - const resizeObserver = new ResizeObserver((entries) => { - for (let entry of entries) { + const resizeObserver = new ResizeObserver(entries => { + for (const entry of entries) { const newHeight = entry.contentRect.height - if (newHeight !== height) { + if (Math.abs(newHeight - height) > 1) { setHeight(newHeight) - requestAnimationFrame(() => { - updateVisibleRange() - }) + requestAnimationFrame(updateVisibleRange) } } }) @@ -183,15 +180,27 @@ export const VirtualScroll = ({ items, containerHeight, buffer = 10, className = } }, [updateVisibleRange]) + // items 变化时重置测量数据 useEffect(() => { - const container = containerRef.current - if (!container) { - return - } + // 重置尺寸测量 + sizesRef.current = items.map(() => ({ size: ESTIMATED_ITEM_HEIGHT, measured: false })) + updateTotalHeight() + + // 重置可见范围 + setVisibleRange({ + start: 0, + end: Math.min(items.length, Math.ceil(height / ESTIMATED_ITEM_HEIGHT) + buffer * 2), + }) // 滚动到顶部 - container.scrollTop = 0 - }, [items]) + const container = containerRef.current + if (container) container.scrollTop = 0 + }, [items, height, buffer, updateTotalHeight]) + + // 设置 ref + const setItemRef = useCallback((el: HTMLDivElement | null, index: number) => { + itemElementsRef.current[index] = el + }, []) const { start, end } = visibleRange const visibleItems = items.slice(start, end) @@ -200,37 +209,34 @@ export const VirtualScroll = ({ items, containerHeight, buffer = 10, className = return (
{/* 占位,撑起总高度 */} -
+
{/* 可见项容器 */}
{visibleItems.map((item, index) => { - const globalIndex = start + index; + const globalIndex = start + index return (
setItemRef(el, globalIndex)} - style={{ - contain: 'layout', - overflowAnchor: 'none', - }} + style={{ contain: "layout" }} > {item}
- ); + ) })}
-- Gitee From eeb0f88f030e50f6a618bb0e30cde82486e8c074 Mon Sep 17 00:00:00 2001 From: heiheihei <1395202740@qq.com> Date: Tue, 2 Sep 2025 19:55:33 +0800 Subject: [PATCH 6/6] =?UTF-8?q?=E5=B1=9E=E6=80=A7=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E7=82=B9=E5=87=BB=E5=A4=8D=E5=88=B6=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Properties/Node/Attributes/Attribute.tsx | 16 ++++---- .../Properties/Node/Initializer.tsx | 2 +- .../Properties/Node/InputOutput.tsx | 6 ++- .../Properties/Node/Metadata.tsx | 2 +- .../src/ModelStructure/Properties/index.tsx | 13 ++++++- .../ModelVis/app/src/hooks/index.ts | 1 + .../app/src/hooks/useCopyToClipboard.ts | 38 +++++++++++++++++++ .../ModelVis/app/src/locales/en.json | 4 ++ .../ModelVis/app/src/locales/zh-CN.json | 4 ++ 9 files changed, 72 insertions(+), 14 deletions(-) create mode 100644 plugins/mindstudio-insight-plugins/ModelVis/app/src/hooks/useCopyToClipboard.ts diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/Attributes/Attribute.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/Attributes/Attribute.tsx index 5f277b651..88bcd8f6a 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/Attributes/Attribute.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/Attributes/Attribute.tsx @@ -44,7 +44,7 @@ const StringLike = ({ name, value }: StringLikeProps) => { const nameLabelStyle = joinCls( "font-mono text-sm font-medium text-blue-600 dark:text-blue-400", - "truncate max-w-[120px]" + "truncate max-w-[120px] copy cursor-pointer" ) const valueLabelStyle = joinCls( @@ -52,7 +52,7 @@ const StringLike = ({ name, value }: StringLikeProps) => { "truncate min-w-[180px] max-w-[180px] px-2 py-1 rounded-lg", "bg-gradient-to-r from-purple-200/70 to-violet-200/70", "dark:from-purple-900/40 dark:to-violet-900/40", - "transition-opacity duration-200" + "transition-opacity duration-200 copy cursor-pointer" ) return
@@ -81,11 +81,11 @@ const StringLike = ({ name, value }: StringLikeProps) => { const StringLikeArray = ({ name, value }: AttrProps<"string-like-array">) =>
-
+
{name}
-
+
{value.map((str, i) =>
{str}
)} @@ -94,11 +94,11 @@ const StringLikeArray = ({ name, value }: AttrProps<"string-like-array">) => const TensorVals = ({ name, value }: AttrProps<"tensor-vals">) =>
-
+
{name}
-
+
{value.map((Tensor, i) =>
{Tensor}
)} @@ -107,11 +107,11 @@ const TensorVals = ({ name, value }: AttrProps<"tensor-vals">) =>
) =>
-
+
{name}
-
+
{value.map((tensors, i) =>
diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/Initializer.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/Initializer.tsx index be1eb2a93..47c7854c4 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/Initializer.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/Initializer.tsx @@ -20,5 +20,5 @@ export const getInitializer = (data: Tensor[], renderList: JSX.Element[]) => { return } renderList.push(,
Initializer
) - data.forEach((t, i) => renderList.push(
【{t.category}】{t.repr}
)) + data.forEach((t, i) => renderList.push(
【{t.category}】{t.repr}
)) } diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/InputOutput.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/InputOutput.tsx index 4685f4b37..5058f014d 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/InputOutput.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/InputOutput.tsx @@ -57,7 +57,8 @@ const IoItem = ({ id }: IoItemProps) => { const idStyle = joinCls( "font-mono text-xs text-blue-600 dark:text-blue-400", "truncate max-w-[140px] transition-colors", - "group-hover:text-blue-800 dark:group-hover:text-blue-300" + "group-hover:text-blue-800 dark:group-hover:text-blue-300", + "copy cursor-pointer" ) const contentStyle = joinCls( @@ -66,7 +67,8 @@ const IoItem = ({ id }: IoItemProps) => { "bg-gradient-to-r from-purple-200/70 to-violet-200/70", "dark:from-purple-900/40 dark:to-violet-900/40", "group-hover:from-purple-300 group-hover:to-violet-300", - "dark:group-hover:from-purple-800 dark:group-hover:to-violet-800" + "dark:group-hover:from-purple-800 dark:group-hover:to-violet-800", + "copy cursor-pointer" ) return
diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/Metadata.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/Metadata.tsx index aaee6f9a4..360b69e72 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/Metadata.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/Node/Metadata.tsx @@ -30,7 +30,7 @@ const MetadataItem = ({ i18nKey, value, tooltip }: MetadataItemProps) => { const valueLabel =
{value}
diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/index.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/index.tsx index db3a0e2e3..06f42254c 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/index.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Properties/index.tsx @@ -13,7 +13,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { useI18n, useLanguage } from "hooks" +import { useCopyToClipboard, useI18n, useLanguage } from "hooks" import { useAtomValue } from "jotai" import { joinCls } from "libs" import { @@ -30,11 +30,12 @@ const Properties = () => { const model = useAtomValue(modelDataAtom) const current = useAtomValue(selectionAtom) const t = useI18n() + const { copyToClipboard } = useCopyToClipboard() const [isShow, setIsShow] = useState(false) const [propertyContent, setPropertyContent] = useState() const [contextValue, setContextValue] = useState({ nodes: {}, parameters: {}, t }) const [appLanguage] = useLanguage() - + const initProperties = () => { if (!current || !model) { setIsShow(false) @@ -58,6 +59,13 @@ const Properties = () => { setIsShow(true) } + const clickHandle = async (e: React.MouseEvent) => { + const dom = e.target as HTMLElement + if (dom.classList.contains('copy')) { + copyToClipboard(dom.innerText.trim()) + } + } + useEffect(() => { initProperties() }, [model, current, appLanguage.code]) @@ -70,6 +78,7 @@ const Properties = () => { "glass-effect border border-white/20 dark:border-slate-700/50", )} style={{ display: isShow ? '' : 'none' }} + onClick={clickHandle} >
{propertyContent} diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/hooks/index.ts b/plugins/mindstudio-insight-plugins/ModelVis/app/src/hooks/index.ts index 8d1aabb61..d2b9d6922 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/hooks/index.ts +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/hooks/index.ts @@ -20,3 +20,4 @@ export * from "./useNewPathForLayout" export * from "./useAnimatedTranslate" export * from "./useCleanup" export * from "./useMessage" +export * from "./useCopyToClipboard" diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/hooks/useCopyToClipboard.ts b/plugins/mindstudio-insight-plugins/ModelVis/app/src/hooks/useCopyToClipboard.ts new file mode 100644 index 000000000..1b5d013e7 --- /dev/null +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/hooks/useCopyToClipboard.ts @@ -0,0 +1,38 @@ +// Copyright (c) 2025, Huawei Technologies Co., Ltd. +// All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import { message } from "antd" +import { useI18n } from "./useI18n" + +export const useCopyToClipboard = () => { + const t = useI18n() + + const copyToClipboard = async (text: string) => { + try { + await navigator.clipboard.writeText(typeof text === 'string' ? text : JSON.stringify(text)) + message.success({ + content: t('copy.success'), + className: 'dark:text-white dark:[&_div]:!bg-dark-light', + }) + } catch (err) { + message.error({ + content: `${t('copy.error')}: ${String(err)}`, + className: 'dark:text-white dark:[&_div]:!bg-dark-light', + }) + } + } + + return { copyToClipboard } +} \ No newline at end of file diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/locales/en.json b/plugins/mindstudio-insight-plugins/ModelVis/app/src/locales/en.json index dbe0df9df..e0055d72c 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/locales/en.json +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/locales/en.json @@ -50,5 +50,9 @@ "totalMteTime": "Total Mte Time(us)", "importCSV": "Import CSV", "allStructures": "All Structures" + }, + "copy": { + "success": "Copy Successful!", + "error": "Copy Failed" } } \ No newline at end of file diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/locales/zh-CN.json b/plugins/mindstudio-insight-plugins/ModelVis/app/src/locales/zh-CN.json index 6300c8d18..06b327d8d 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/locales/zh-CN.json +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/locales/zh-CN.json @@ -50,5 +50,9 @@ "totalMteTime": "Mte总时间(us)", "importCSV": "导入CSV", "allStructures": "全部结构" + }, + "copy": { + "success": "复制成功!", + "error": "复制失败" } } \ No newline at end of file -- Gitee