UNPKG

mp-lens

Version:

微信小程序分析工具 (Unused Code, Dependencies, Visualization)

141 lines 8.56 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.App = App; const jsx_runtime_1 = require("preact/jsx-runtime"); const hooks_1 = require("preact/hooks"); const dependency_tree_processor_1 = require("../utils/dependency-tree-processor"); // UPDATED: Removed formatBytes const DependencyGraph_1 = require("./DependencyGraph"); const FileListView_1 = require("./FileListView"); const Header_1 = require("./Header"); // Import the new Header component const Layout_module_css_1 = __importDefault(require("./Layout.module.css")); // Import the Layout CSS module const NodeDetails_1 = require("./NodeDetails"); const Tabs_1 = require("./Tabs"); const TreeView_1 = require("./TreeView"); const UnusedFilesView_1 = require("./UnusedFilesView"); const emptyProjectStructure = { nodes: [], links: [], rootNodeId: null, miniappRoot: '', }; const emptyTreeNode = { id: 'loading', label: 'Loading tree...', type: 'Unknown', properties: { fileCount: 0, totalSize: 0 }, children: [], }; // Helper function to find a node in the tree by its ID function findTreeNodeById(treeNode, id) { if (!treeNode) { return null; } if (treeNode.id === id) { return treeNode; } if (treeNode.children) { for (const child of treeNode.children) { const found = findTreeNodeById(child, id); if (found) { return found; } } } return null; } function App(props) { // Accept props object directly // Log props to satisfy linter if AppProps is empty, can be removed if AppProps gets members if (Object.keys(props).length > 0) { console.log('[App] Props received:', props); } const fullGraphData = (0, hooks_1.useMemo)(() => window.__MP_LENS_GRAPH_DATA__ || emptyProjectStructure, []); // Build the tree structure AND calculate stats in one step const initialTreeData = (0, hooks_1.useMemo)(() => (0, dependency_tree_processor_1.buildTreeWithStats)(fullGraphData) || emptyTreeNode, [fullGraphData]); const [selectedNode, setSelectedNode] = (0, hooks_1.useState)(initialTreeData); const [currentMode, setCurrentMode] = (0, hooks_1.useState)('tree'); const [activeTabId, setActiveTabId] = (0, hooks_1.useState)('details'); // Default to details tab const handleNodeSelect = (node) => { setSelectedNode(node); }; const handleGraphNodeSelect = (nodeId) => { // Find the corresponding node within the constructed tree data const treeNode = findTreeNodeById(initialTreeData, nodeId); if (treeNode) { setSelectedNode(treeNode); // Set the found node from the tree setCurrentMode('tree'); } else { // Fallback or error handling if node not found in the tree // This might happen if graph data includes nodes not represented in the tree console.warn(`[App] TreeNode not found in initialTreeData for ID: ${nodeId}. Falling back to graph data.`); // Optional Fallback: use raw data like before, but be aware it might be incomplete for details view const nodeData = fullGraphData.nodes.find((n) => n.id === nodeId); if (nodeData) { setSelectedNode({ // This fallback node will lack children and accurate calculated stats id: nodeData.id, label: nodeData.label, type: nodeData.type, properties: nodeData.properties, }); setCurrentMode('tree'); } else { console.error(`[App] GraphNode also not found for ID: ${nodeId}`); } } }; const realUnusedFiles = (0, hooks_1.useMemo)(() => window.__MP_LENS_UNUSED_FILES__ || [], []); // Calculate root stats using the root of the built tree const rootStats = (0, hooks_1.useMemo)(() => { var _a, _b; const rootNodeForStats = initialTreeData; // Use the root of the built tree return { totalFiles: ((_a = rootNodeForStats.properties) === null || _a === void 0 ? void 0 : _a.fileCount) || 0, totalSize: ((_b = rootNodeForStats.properties) === null || _b === void 0 ? void 0 : _b.totalSize) || 0, unusedFileCount: realUnusedFiles.length, unusedFilesList: realUnusedFiles, }; }, [initialTreeData, realUnusedFiles]); const switchToUnusedFilesMode = () => setCurrentMode('unusedFiles'); const switchToTreeMode = () => setCurrentMode('tree'); // Handler for when a file is clicked in FileListView const handleFileSelect = (moduleId) => { handleGraphNodeSelect(moduleId); // Reuse existing logic to select the node setActiveTabId('graph'); // Switch to the graph tab }; // Handler for when a child node is clicked in NodeDetails view const handleChildNodeGraphJump = (nodeId) => { handleGraphNodeSelect(nodeId); setActiveTabId('graph'); }; if (initialTreeData.id === 'loading' || initialTreeData.id === 'empty' || initialTreeData.id === 'error_root') { return ((0, jsx_runtime_1.jsxs)("div", { className: Layout_module_css_1.default.appContainer, children: [(0, jsx_runtime_1.jsx)(Header_1.Header, { title: window.__MP_LENS_TITLE__ || '依赖可视化', totalFiles: 0, totalSize: 0, unusedFileCount: 0, onTreeModeClick: () => { }, onUnusedFilesClick: () => { } }), (0, jsx_runtime_1.jsx)("main", { className: Layout_module_css_1.default.mainContainer, children: (0, jsx_runtime_1.jsx)("section", { className: Layout_module_css_1.default.content, style: { display: 'flex', justifyContent: 'center', alignItems: 'center' }, children: (0, jsx_runtime_1.jsx)("p", { children: initialTreeData.label }) }) })] })); } // Create class name for main container with mode const mainContainerClassName = `${Layout_module_css_1.default.mainContainer} ${currentMode === 'unusedFiles' ? Layout_module_css_1.default.modeUnusedFiles : ''}`; return ((0, jsx_runtime_1.jsxs)("div", { className: Layout_module_css_1.default.appContainer, children: [(0, jsx_runtime_1.jsx)(Header_1.Header, { title: window.__MP_LENS_TITLE__ || '依赖可视化', totalFiles: rootStats.totalFiles, totalSize: rootStats.totalSize, unusedFileCount: rootStats.unusedFileCount, onTreeModeClick: switchToTreeMode, onUnusedFilesClick: switchToUnusedFilesMode }), (0, jsx_runtime_1.jsxs)("main", { className: mainContainerClassName, children: [currentMode === 'tree' && ((0, jsx_runtime_1.jsx)("aside", { className: Layout_module_css_1.default.sidebar, children: (0, jsx_runtime_1.jsx)(TreeView_1.TreeView, { data: initialTreeData, onNodeSelect: handleNodeSelect, selectedNodeId: selectedNode.id }) })), (0, jsx_runtime_1.jsx)("section", { className: Layout_module_css_1.default.content, children: currentMode === 'tree' ? ((0, jsx_runtime_1.jsx)(Tabs_1.Tabs, { tabs: [ { id: 'details', label: '节点详情', content: ((0, jsx_runtime_1.jsx)(NodeDetails_1.NodeDetails, { node: selectedNode, fullGraphData: fullGraphData, onChildNodeSelect: handleChildNodeGraphJump })), }, { id: 'graph', label: '依赖图', content: ((0, jsx_runtime_1.jsx)(DependencyGraph_1.DependencyGraph, { selectedNode: selectedNode, fullGraphData: fullGraphData, initialTreeData: initialTreeData, onNodeSelect: handleGraphNodeSelect })), }, { id: 'filelist', label: '文件列表', content: (0, jsx_runtime_1.jsx)(FileListView_1.FileListView, { node: selectedNode, onFileSelect: handleFileSelect }), // Pass handler }, ], activeTabId: activeTabId, onTabChange: setActiveTabId })) : ((0, jsx_runtime_1.jsx)(UnusedFilesView_1.UnusedFilesView, { unusedFiles: rootStats.unusedFilesList, onReturnToTree: switchToTreeMode })) })] })] })); } //# sourceMappingURL=App.js.map