diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/package.json b/plugins/mindstudio-insight-plugins/ModelVis/app/package.json index 978913d203da8550ec5f4c35e347a76f480ded50..cc8b94ff53967dba94041d9006b9861e06a3b284 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/package.json +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/package.json @@ -24,6 +24,7 @@ "@tauri-apps/plugin-dialog": "^2.2.1", "gl-matrix": "^3.4.3", "jotai": "^2.12.4", + "lodash": "^4.17.21", "lucide-react": "^0.511.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -39,6 +40,7 @@ "@tailwindcss/postcss": "^4.1.7", "@tauri-apps/cli": "^2.5.0", "@types/bun": "^1.2.13", + "@types/lodash": "^4.17.20", "@types/node": "^22.15.19", "@types/react": "^18.3.21", "@types/react-dom": "^18.3.7", diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/App.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/App.tsx index a30014afc3bf807a2b4786d1cc8625b4f13dd862..54ee45b6a34ce0f34ca67209ae544c71d10d1b28 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/App.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/App.tsx @@ -13,20 +13,64 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { useAtomValue } from "jotai" +import { useAtom, useAtomValue } from "jotai" import { Toaster } from "sonner" -import { modelPathAtom } from "stores" +import { modelDataAtom, modelPathAtom, nodesEdgesAtom, currentGraphAtom, subgraphesAtom } from "stores" import FileUpload from "./FileUpload" import ModelStructure from "./ModelStructure" import { Toolbar } from "./features" import { Loading } from "./ui" import useWorkerMessage from "./useWorkerMessage" +import { useEffect } from "react"; +import { cloneDeep } from "lodash"; + +const SUBGRAPH_NODE_HEIGHT = 40 +const SUBGRAPH_NODE_WIDTH = 120 +const SUBGRAPH_NODE_SPACE = 30 +const SUBGRAPH_ROW_COUNT = 10 const App = () => { const modelPath = useAtomValue(modelPathAtom) + const [modelData, setModelData] = useAtom(modelDataAtom) + const [nodesEdges, setNodesEdges] = useAtom(nodesEdgesAtom) + const currentGraph = useAtomValue(currentGraphAtom) + const subgraphs = useAtomValue(subgraphesAtom) useWorkerMessage() + useEffect(() => { + if (!currentGraph) { + return + } + const currentGraphData = subgraphs[currentGraph.name] + if (currentGraphData) { + const maxY = currentGraphData.nodes.reduce((max: number, current: any) => { + return (current.y > max) ? current.y : max + }, 0) + currentGraph.children.forEach((subgraph, index) => { + const foundItem = currentGraphData.nodes.find(item => item.id === subgraph.name) + if (foundItem) { + foundItem.completed = Object.keys(subgraphs).includes(subgraph.name) + } else { + currentGraphData.nodes.push({ + id: subgraph.name, + x: (index % SUBGRAPH_ROW_COUNT) * (SUBGRAPH_NODE_WIDTH + SUBGRAPH_NODE_SPACE), + y: maxY + SUBGRAPH_NODE_SPACE + Math.floor(index / SUBGRAPH_ROW_COUNT) * (SUBGRAPH_NODE_HEIGHT + SUBGRAPH_NODE_SPACE), + height: SUBGRAPH_NODE_HEIGHT, + width: SUBGRAPH_NODE_WIDTH, + opType: `subgraph`, + dynamic: false, + completed: Object.keys(subgraphs).includes(subgraph.name) + }) + } + }) + if (!modelData || !nodesEdges || JSON.stringify(currentGraphData.nodes) !== JSON.stringify(nodesEdges.nodes)) { + setModelData(cloneDeep(currentGraphData.model)) + setNodesEdges({ nodes: cloneDeep(currentGraphData.nodes), edges: cloneDeep(currentGraphData.edges) }); + } + } + }, [currentGraph, JSON.stringify(subgraphs)]); + return
diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/FileUpload.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/FileUpload.tsx index 748ae3e119c901bce660fd99b7df4298786bf192..33704bf070c6bfcc5a4d5d09ad86ade6c66049ca 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/FileUpload.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/FileUpload.tsx @@ -15,25 +15,40 @@ import { useNewPathForLayout } from "hooks" import { openDialog } from "./libs" +import { useRecentProjectStorage } from "stores/useRecentProjectStorage"; +import { RecentProj } from "features/Project"; const FileUpload = () => { + const { recentProjectList } = useRecentProjectStorage(); const layoutNewPath = useNewPathForLayout() const handleUpload = async () => { const path = await openDialog() await layoutNewPath(path) } + const toggle = async (path: string) => { + await layoutNewPath(path) + } - return
- -
+ return <> +
+
+ +
+ {recentProjectList.map(p => ( + + ))} +
+
+
+ } export default FileUpload diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Control/FsgControl.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Control/FsgControl.tsx index 8bb21c1b7adfd6439a09568bfe6c317b8edeaf9c..31a1d347513f9313c69b63da64d31007c02bccf6 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Control/FsgControl.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Control/FsgControl.tsx @@ -30,7 +30,7 @@ const FsgControl = () => { setVisible(!visible) } - return - + {t('fsg.minRepeatTimes')} + handleInput(e, 'repeat')} + /> + {t('fsg.nodeInFsg')} + handleInput(e, 'min')} + /> + ~ + handleInput(e, 'max')} + /> + + +
} diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Fsg/index.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Fsg/index.tsx index 5982afb40436f88d161dbd21cbfa2cd206a30fa1..926aebb29d3f87b3465ad23f5bbf903cc8f67d59 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Fsg/index.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Fsg/index.tsx @@ -18,23 +18,34 @@ import { useAtomValue } from 'jotai' import { joinCls } from 'libs' import Filter from './Filter' import { - loadingAtom, modelPathAtom, fsgPanelVisibleAtom, fsgVisibleAtom, themeAtom, currentGraphAtom } from '../../stores' -import { useAtom, useSetAtom } from 'jotai/index' +import { useAtom } from 'jotai/index' import { invoke } from '@tauri-apps/api/core' import type { ColumnsType } from 'antd/es/table' -import { ConfigProvider, Table, theme } from 'antd' -import { useEffect, useState } from 'react' +import { ConfigProvider, message, Table, theme } from 'antd' +import { useEffect, useRef, useState } from 'react' import { workerInitFsgs, workerToggleFsgs } from '../../worker-apis' +import { Resizer, type ResizerType } from 'ui/Resizer' +import Pushpin from "icons/pushpin.svg?react" /** * The current algorithm is flawed, results returned are duplicated, * and there are differences only in order * @param graphs Array of NodeId array */ +let opDuration: OpDuration = {} +let fsgDataCach: FsgRet[] = [] + +const getOpStructAvgTime = (opStruct: string, type: TimeType): number => { + const opList = opStruct.split(',') + let avgTime = 0 + opList.forEach(op => (avgTime += opDuration[op]?.[type] ?? 0)) + return avgTime +} + const dedup = (graphs: FsgRet[]): FsgTableRow[] => { const seen = new Set() return graphs.map((item, index) => { @@ -46,13 +57,18 @@ const dedup = (graphs: FsgRet[]): FsgTableRow[] => { return seen.has(key) ? false : seen.add(key) && true }) + const meanDuration = getOpStructAvgTime(item.optype_struct, 'avg_duration_us') + const meanMteTime = getOpStructAvgTime(item.optype_struct, 'avg_memory_move_time_us') + return { - key: `${item.optype_struct}_${index}`, + key: `${item.optype_struct}_${index}_${meanDuration}_${meanMteTime}`, fsg: item.optype_struct, count: nodes.length, nodeCount: item.instances[0]?.node_num ?? 0, - meanDuration: 0, - totalDuration: 0, + meanDuration, + totalDuration: meanDuration * nodes.length, + meanMteTime, + totalMteTime: meanMteTime * nodes.length, nodes } }).filter(item => item.count > 0 && item.nodeCount > 0) @@ -68,38 +84,69 @@ const getColumns = (t: I18nFunc): ColumnsType => { { dataIndex: 'fsg', title: t('fsg.fsg'), - sorter: (a: FsgTableRow, b: FsgTableRow): number => a.fsg.localeCompare(b.fsg), - width: '50%', - ellipsis: true + width: 200, + ellipsis: true, + sorter: (a: FsgTableRow, b: FsgTableRow): number => a.fsg.localeCompare(b.fsg) }, { dataIndex: 'count', title: t('fsg.count'), + width: 90, + ellipsis: true, sorter: (a: FsgTableRow, b: FsgTableRow): number => a.count - b.count }, { dataIndex: 'nodeCount', title: t('fsg.nodeCount'), + width: 130, + ellipsis: true, sorter: (a: FsgTableRow, b: FsgTableRow): number => a.nodeCount - b.nodeCount }, { dataIndex: 'meanDuration', title: t('fsg.meanDuration'), - sorter: (a: FsgTableRow, b: FsgTableRow): number => a.meanDuration - b.meanDuration + width: 155, + ellipsis: true, + sorter: (a: FsgTableRow, b: FsgTableRow): number => a.meanDuration - b.meanDuration, + render: (value) => (value > 0 ? value : 'NA') }, { dataIndex: 'totalDuration', title: t('fsg.totalDuration'), - sorter: (a: FsgTableRow, b: FsgTableRow): number => a.totalDuration - b.totalDuration + width: 150, + ellipsis: true, + sorter: (a: FsgTableRow, b: FsgTableRow): number => a.totalDuration - b.totalDuration, + render: (value) => (value > 0 ? value : 'NA') + }, + { + dataIndex: 'meanMteTime', + title: t('fsg.meanMteTime'), + width: 165, + ellipsis: true, + sorter: (a: FsgTableRow, b: FsgTableRow): number => a.meanMteTime - b.meanMteTime, + render: (value) => (value > 0 ? value : 'NA') + }, + { + dataIndex: 'totalMteTime', + title: t('fsg.totalMteTime'), + width: 160, + ellipsis: true, + sorter: (a: FsgTableRow, b: FsgTableRow): number => a.totalMteTime - b.totalMteTime, + render: (value) => (value > 0 ? value : 'NA') } ] } const Fsg = () => { - const visible = useAtomValue(fsgPanelVisibleAtom) + const [visible, setVisible] = useAtom(fsgPanelVisibleAtom) const t = useI18n() - const setLoading = useSetAtom(loadingAtom) + const containerRef = useRef(null) + const [loading, setLoading] = useState(false) + const [width, setWidth] = useState(690) + const [top, setTop] = useState(5) + const [left, setLeft] = useState(10) + const [isLock, setIsLock] = useState(false) const [fsgVis, setFsgVis] = useAtom(fsgVisibleAtom) const path = useAtomValue(modelPathAtom) const [fsgData, setFsgData] = useState([]) @@ -111,11 +158,35 @@ const Fsg = () => { const queryFsg = async (repeat: number, min: number, max: number) => { setLoading(true) - const res = await invoke( - 'mine_fsg', - { path, minSup: repeat, min, max, name: currentGraph.name } - ) - const fsgs = dedup(sortedFsgs(res)) + try { + const res = await invoke( + 'mine_fsg', + { path, minSup: repeat, min, max, name: currentGraph.name } + ) + const fsgs = dedup(sortedFsgs(res)) + setFsgData(fsgs) + fsgDataCach = res + } catch (err) { + message.error({ + content: typeof err === 'string' ? err : JSON.stringify(err), + className: 'dark:text-white dark:[&_div]:!bg-dark-light', + }) + } + setLoading(false) + } + const exportOpDuration = async (path: string): Promise => { + setLoading(true) + try { + const res = await invoke('analyze_duration', { path }) + + opDuration = res + } catch (err) { + message.error({ + content: typeof err === 'string' ? err : JSON.stringify(err), + className: 'dark:text-white dark:[&_div]:!bg-dark-light', + }) + } + const fsgs = dedup(sortedFsgs(fsgDataCach)) setFsgData(fsgs) setLoading(false) } @@ -139,20 +210,84 @@ const Fsg = () => { } } + const changeWidth: ResizerType['callback'] = (value, _) => { + if (containerRef.current === null) { + return + } + setWidth(containerRef.current.offsetWidth + value) + } + + const moveContainer: ResizerType['callback'] = (moveX, moveY) => { + setLeft(oLeft => { + const newLeft = oLeft + moveX + if (newLeft > window.innerWidth - 80) { + return window.innerWidth - 80 + } + return newLeft > 0 ? newLeft : 0 + }) + setTop(oTop => { + const newTop = oTop + moveY + if (newTop > window.innerHeight - 80) { + return window.innerHeight - 80 + } + return newTop > 0 ? newTop : 0 + }) + } + + const mouseDown = (e: MouseEvent) => { + if (e === null) return + const isInside = containerRef.current?.contains(e.target as HTMLElement); + const isFsgControlBtn = document.getElementById("fsgControlBtn")?.contains(e.target as HTMLElement) + if (isFsgControlBtn) { + return + } + if (!isInside && !isLock) { + setVisible(false) + } + } + + useEffect(() => { + document.addEventListener('mousedown', mouseDown); + return () => { + document.removeEventListener('mousedown', mouseDown) + } + }, [isLock]) + useEffect(() => { setFsgData([]); + setLoading(false); setSelectedRow(undefined); - }, [path]); + opDuration = {} + fsgDataCach = [] + }, [path]) + + useEffect(() => { + moveContainer(0, 0) + }, [window.innerHeight, window.innerWidth]) return
- + +
+ setIsLock(oVal => !oVal)} + /> +
+ +
+
+ { > record.key === selectedRow?.key ? 'bg-blue-300' : ''} pagination={{ className: '!my-2', pageSizeOptions: ['10', '20', '50', '100'], total: fsgData.length, - showTotal: (total: number): string => t('fsg.paginationTotal', {total: total}), + showTotal: (total: number): string => t('fsg.paginationTotal', { total: total }), showSizeChanger: true, showQuickJumper: true }} 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 d322f8132a0fb9957bfc8562b05d20ce647d2d1b..a9fc53e65a66a66a748ae750bba624c7986c9b1b 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 @@ -46,7 +46,7 @@ const Properties = () => {
diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/index.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/index.tsx index 8fec5c4df6040bef716ba7eeee555216d7ec2d76..8ca4389cc502fa4722e7a5b37795afceadb2ebcb 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/index.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/index.tsx @@ -31,7 +31,8 @@ import { translateAtom, useZoom, currentGraphAtom, - allGraphAtom + allGraphAtom, + translateCacheAtom } from "stores" import { workerHitTest, @@ -45,13 +46,17 @@ import Control from "./Control" import Dynamic from "./Dynamic" import Properties from "./Properties" import Fsg from "./Fsg" +import { isEqual } from "lodash" const ModelStructureComp = ({ width, height }: WindowSize) => { const [isDragging, setIsDragging] = useState(false) + const isMoveRef = useRef(false) const [origin, setOrigin] = useState({ x: 0, y: 0 }) + const allGraphs = useAtomValue(allGraphAtom) const data = useAtomValue(nodesEdgesAtom) - + const currentGraph = useAtomValue(currentGraphAtom) const [translate, setTranslate] = useAtom(translateAtom) + const [translateCache, setTranslateCache] = useAtom(translateCacheAtom) const [zoom, zoomIn, zoomOut] = useZoom() const theme = useAtomValue(themeAtom) const fsgVis = useAtomValue(fsgVisibleAtom) @@ -76,21 +81,33 @@ const ModelStructureComp = ({ width, height }: WindowSize) => { const translateX = clientX + origin.x const translateY = clientY + origin.y - - setTranslate({ x: translateX, y: translateY }) + const newTranslate = { x: translateX, y: translateY } + setTranslate((oldTranslate) => { + if (!isEqual(newTranslate, oldTranslate)) { + isMoveRef.current = true + } + return newTranslate + }) } const handleMouseUpOrLeave = () => { - if (isDragging) setIsDragging(false) + setIsDragging(false) } const handleClick = ({ clientX, clientY }: MouseEvent) => { - if (isDragging) return + if (isDragging || isMoveRef.current) { + isMoveRef.current = false + return + } + setTranslateCache((oVal => { + oVal[currentGraph.name] = translate + return oVal + })) const px = (clientX - bbox.left - translate.x) / zoom const py = (clientY - bbox.top - translate.y) / zoom - workerHitTest(px, py) + workerHitTest(px, py, allGraphs, translateCache) } const handleWheel = debounce((ev: WheelEvent) => { @@ -174,22 +191,25 @@ const ModelStructureComp = ({ width, height }: WindowSize) => { const GraphPath = () => { const [currentGraph, setCurrentGraph] = useAtom(currentGraphAtom) const [translate, setTranslate] = useAtom(translateAtom) + const [translateCache, setTranslateCache] = useAtom(translateCacheAtom) const allGraphs = useAtomValue(allGraphAtom) if (!currentGraph || !allGraphs || currentGraph.paths.length < 1) return null const onClickPath = (graphName: string) => { const targetGraph = getSubgraph(allGraphs, graphName) if (targetGraph) { + setTranslateCache((oVal => { + oVal[currentGraph.name] = translate + return oVal + })) setCurrentGraph(targetGraph) - if (translate.x !== 0 || translate.y !== 0) { - setTranslate({ x: 0, y: 0 }) - } + setTranslate(translateCache[graphName] ?? { x: 0, y: 0 }) } } return
@@ -209,12 +229,12 @@ const ModelStructure = () => <> - - - - - - + + + + + + )} diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/bootstrap.ts b/plugins/mindstudio-insight-plugins/ModelVis/app/src/bootstrap.ts index cde8b2033ba04899c487c817c4f96522b83fe88e..c4954fbed9331933a46be4c2af85b78559b34258 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/bootstrap.ts +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/bootstrap.ts @@ -14,14 +14,8 @@ // limitations under the License. import { LogicalSize } from "@tauri-apps/api/dpi" -import { once } from "@tauri-apps/api/event" import { currentMonitor, type Monitor } from "@tauri-apps/api/window" import NativeWindow from "./native" -import { recentProjCache } from "./stores" - -await once("tauri://close-requested", () => { - localStorage.setItem("recentProj", JSON.stringify(recentProjCache.items)) -}) document.addEventListener( "wheel", @@ -29,7 +23,12 @@ document.addEventListener( { passive: false } ) document.addEventListener("contextmenu", e => e.preventDefault(), { passive: false }) -document.addEventListener("keydown", e => (e.ctrlKey || e.metaKey) && e.preventDefault(), { +document.addEventListener("keydown", e => { + if ((e.ctrlKey || e.metaKey) && ["c", "v"].includes(e.key.toLocaleLowerCase())) { + return + } + (e.ctrlKey || e.metaKey) && e.preventDefault() +}, { passive: false }) 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 d1c81cc5313339ae7b513abe43c504bee304acec..1fa426ba3c28b79fca51402a2609edc947ab4f49 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Project.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Project.tsx @@ -25,9 +25,12 @@ import TrashIcon from "icons/trash.svg?react" import XIcon from "icons/x.svg?react" import { useAtomValue, } from "jotai" import { joinCls, openDialog } from "libs" -import { modelPathAtom, recentProjCache, } from "stores" +import { useEffect } from "react" +import { modelPathAtom } from "stores" +import { useRecentProjectStorage } from "stores/useRecentProjectStorage" const Project = () => { + const { recentProjectList } = useRecentProjectStorage(); const { visible, open, close } = useVisible() const ref = useClickOutside(close) @@ -41,18 +44,16 @@ const Project = () => { const handleNewProject = async () => { const path = await openDialog() - - await layoutNewPath(path) - close() + await layoutNewPath(path) } const toggle = async (path: string) => { - await layoutNewPath(path) close() + await layoutNewPath(path) } - return
+ return
{visible &&
+ + + - - - -
- -

{t("project.recent")}

- {recentProjCache.items.map(p => ( - - ))} -
+ + {t("project.close")} + + +
+ +

{t("project.recent")}

+ {recentProjectList.map(p => ( + + ))} +
}
} @@ -108,25 +109,42 @@ type ProjectLineProps = { toggle: (newPath: string) => void } -const RecentProj = ({ path, toggle }: ProjectLineProps) => { +export const RecentProj = ({ path, toggle }: ProjectLineProps) => { + const { recentProjectList, recentProjCacheRemove } = useRecentProjectStorage() + const cleanup = useCleanup() + const handleNew = () => toggle(path) + const curPath = useAtomValue(modelPathAtom) + const deletePro = () => { + // 因为修改recentProjCache是异步操作,所以先判断之后的操作 + const wasLastItem = recentProjectList.length === 1 + const isCurrentPath = path === curPath + + recentProjCacheRemove(path) + if (wasLastItem) { + cleanup() + } else if (isCurrentPath) { + toggle(recentProjectList[0]) + } + } return
- +
} diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Search/SearchModal.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Search/SearchModal.tsx index 0d01e7b056f7c24e816d6a9c77cc62eb12eaeb40..d467c79789cca9a36b2c9177508b74157d891faf 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Search/SearchModal.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Search/SearchModal.tsx @@ -91,7 +91,7 @@ export const SearchModal = () => { ref={ref} className={joinCls( "-translate-x-1/2 fixed top-28 left-1/2 z-50 flex h-[55%]", - "w-full max-w-2xl select-none flex-col rounded-lg py-8 pr-3", + "w-full max-w-2xl flex-col rounded-lg py-8 pr-3", "bg-[#fcfcfc] pl-12 shadow-lg dark:bg-dark-secondary" )} > @@ -104,7 +104,7 @@ export const SearchModal = () => { placeholder={t("searchNodeEdge")} className={joinCls( "h-12 w-full pr-3 pl-9 text-sm lg:h-14 lg:pl-12 lg:text-base", - "select-none rounded-lg bg-white outline-none ring-1 ring-inset", + "rounded-lg bg-white outline-none ring-1 ring-inset", "ring-violet-300 transition-color duration-150 dark:ring-violet-50", "focus:bg-white focus:text-gray-600 dark:bg-dark-medium", "dark:focus:bg-dark-primary dark:focus:text-white" diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Search/index.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Search/index.tsx index ef5d498ad266a17268d0bc196872ebb13767786a..caaa8e6c549e4debdf1b422b5dbcd30ddd2917d5 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Search/index.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/features/Search/index.tsx @@ -38,7 +38,7 @@ const Search = () => { return