UNPKG

mp-lens

Version:

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

147 lines 10.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.FileListView = FileListView; 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 import path const FileListView_module_css_1 = __importDefault(require("./FileListView.module.css")); // Import CSS Module // ADD HELPER: Get file extension from path function getFileExtension(path) { const match = path.match(/\.([^./\\]+)$/); return match ? match[1].toLowerCase() : ''; // Ensure lowercase extension } // ADD HELPER: Convert absolute path to relative path function toRelativePath(absPath, root) { if (!absPath || !root) return absPath; // Normalize path separators to forward slashes const normAbs = absPath.replace(/\\/g, '/'); const normRoot = root.replace(/\\/g, '/').replace(/\/$/, ''); // Ensure no trailing slash if (normAbs.startsWith(normRoot + '/')) { // Check if it starts with root + slash return normAbs.slice(normRoot.length + 1); // Remove root + leading slash } return absPath; // Return original if not under root } /** * A component that displays a list of all files in the current node */ function FileListView({ node, onFileSelect }) { var _a; // State for sorting: null means default sort (path), otherwise sort by the active column const [sizeOrder, setSizeOrder] = (0, hooks_1.useState)('desc'); const [dependencyCountOrder, setDependencyCountOrder] = (0, hooks_1.useState)(null); const [filterType, setFilterType] = (0, hooks_1.useState)(''); // '' means show all // Use full graph data if available const fullGraphData = window.__MP_LENS_GRAPH_DATA__ || { nodes: [], links: [], miniappRoot: '' }; const miniappRoot = fullGraphData.miniappRoot || ''; // Pre-calculate dependency counts for all nodes const dependencyCounts = (0, hooks_1.useMemo)(() => { const counts = new Map(); for (const link of fullGraphData.links) { counts.set(link.target, (counts.get(link.target) || 0) + 1); } return counts; }, [fullGraphData.links]); // Collect all reachable module files first const allFiles = (0, hooks_1.useMemo)(() => { var _a; const moduleIds = ((_a = node.properties) === null || _a === void 0 ? void 0 : _a.reachableModuleIds) || new Set(); const nodeMap = new Map(fullGraphData.nodes.map((n) => [n.id, n])); // Use GraphNode type const files = []; // Use FileDetail type let counter = 0; moduleIds.forEach((mid) => { var _a, _b; const m = nodeMap.get(mid); if (!m || m.type !== 'Module') return; const path = m.id; const relativePath = toRelativePath(path, miniappRoot); const size = ((_a = m.properties) === null || _a === void 0 ? void 0 : _a.fileSize) || 0; const ext = ((_b = m.properties) === null || _b === void 0 ? void 0 : _b.fileExt) || getFileExtension(path) || 'unknown'; const dependencyCount = dependencyCounts.get(mid) || 0; files.push({ id: ++counter, path, relativePath, size, type: ext, dependencyCount, }); }); return files.sort((a, b) => a.relativePath.localeCompare(b.relativePath)); }, [ node.id, (_a = node.properties) === null || _a === void 0 ? void 0 : _a.reachableModuleIds, fullGraphData.nodes, miniappRoot, dependencyCounts, ]); // Added dependencies // Get unique file types for filtering options const uniqueFileTypes = (0, hooks_1.useMemo)(() => { const types = new Set(allFiles.map((f) => f.type)); return Array.from(types).sort(); }, [allFiles]); // Calculate file counts for each type const fileCountsByType = (0, hooks_1.useMemo)(() => { const counts = {}; for (const file of allFiles) { counts[file.type] = (counts[file.type] || 0) + 1; } return counts; }, [allFiles]); // Filter and sort files based on state const displayedFiles = (0, hooks_1.useMemo)(() => { let files = allFiles; // Apply filter if (filterType) { files = files.filter((f) => f.type === filterType); } // Apply sorting based on which column header was clicked last files.sort((a, b) => { if (dependencyCountOrder) { // Sort by dependency count return dependencyCountOrder === 'asc' ? a.dependencyCount - b.dependencyCount : b.dependencyCount - a.dependencyCount; } else if (sizeOrder) { // Sort by size return sizeOrder === 'asc' ? a.size - b.size : b.size - a.size; } else { // Default sort by relative path if no column is active return a.relativePath.localeCompare(b.relativePath); } }); // Re-assign sequential IDs after filtering and sorting return files.map((f, idx) => ({ ...f, id: idx + 1 })); }, [allFiles, filterType, sizeOrder, dependencyCountOrder]); // Add dependencyCountOrder dependency // If no files are found *after filtering* (or initially), show a message if (displayedFiles.length === 0 && allFiles.length === 0) { return ((0, jsx_runtime_1.jsx)("div", { className: FileListView_module_css_1.default.fileListView, children: (0, jsx_runtime_1.jsx)("div", { className: FileListView_module_css_1.default.emptyState, children: (0, jsx_runtime_1.jsx)("p", { children: "\u6B64\u8282\u70B9\u6CA1\u6709\u76F4\u63A5\u5173\u8054\u7684\u6587\u4EF6\u3002" }) }) })); } // Sorting arrows - display only if the column is actively sorted const sizeArrow = sizeOrder ? (sizeOrder === 'asc' ? '↑' : '↓') : ''; const dependencyCountArrow = dependencyCountOrder ? dependencyCountOrder === 'asc' ? '↑' : '↓' : ''; const handleSizeSortClick = () => { const newOrder = sizeOrder === 'asc' ? 'desc' : 'asc'; setSizeOrder(newOrder); setDependencyCountOrder(null); // Reset other sort }; const handleDependencyCountSortClick = () => { const newOrder = dependencyCountOrder === 'asc' ? 'desc' : 'asc'; setDependencyCountOrder(newOrder); setSizeOrder(null); // Reset other sort }; return ((0, jsx_runtime_1.jsxs)("div", { className: FileListView_module_css_1.default.fileListView, children: [(0, jsx_runtime_1.jsx)("div", { className: FileListView_module_css_1.default.fileListHeader, children: miniappRoot && (0, jsx_runtime_1.jsxs)("div", { className: FileListView_module_css_1.default.rootPath, children: ["\u6839\u76EE\u5F55: ", miniappRoot] }) }), uniqueFileTypes.length > 1 && ( // Only show filters if there's more than one type (0, jsx_runtime_1.jsxs)("div", { className: FileListView_module_css_1.default.fileFilterControls, children: [(0, jsx_runtime_1.jsx)("span", { children: "\u7B5B\u9009:" }), (0, jsx_runtime_1.jsxs)("button", { onClick: () => setFilterType(''), className: `${FileListView_module_css_1.default.filterButton} ${filterType === '' ? FileListView_module_css_1.default.active : ''}`, children: ["All (", allFiles.length, ")"] }), uniqueFileTypes.map((type) => ((0, jsx_runtime_1.jsxs)("button", { onClick: () => setFilterType(type), className: `${FileListView_module_css_1.default.filterButton} ${filterType === type ? FileListView_module_css_1.default.active : ''}`, title: `.${type}`, children: [".", type, " (", fileCountsByType[type] || 0, ")"] }, type)))] })), (0, jsx_runtime_1.jsx)("div", { className: FileListView_module_css_1.default.fileTableContainer, children: displayedFiles.length > 0 ? ((0, jsx_runtime_1.jsxs)("table", { className: FileListView_module_css_1.default.fileTable, children: [(0, jsx_runtime_1.jsx)("thead", { children: (0, jsx_runtime_1.jsxs)("tr", { children: [(0, jsx_runtime_1.jsx)("th", { className: FileListView_module_css_1.default.sequenceColumn, children: "\u5E8F\u53F7" }), (0, jsx_runtime_1.jsx)("th", { className: FileListView_module_css_1.default.fileColumn, children: "\u6587\u4EF6" }), (0, jsx_runtime_1.jsxs)("th", { className: `${FileListView_module_css_1.default.refCountColumn} ${FileListView_module_css_1.default.sortable}`, style: { cursor: 'pointer' }, onClick: handleDependencyCountSortClick, title: "\u70B9\u51FB\u5207\u6362\u6392\u5E8F", children: ["\u88AB\u4F9D\u8D56\u6B21\u6570 ", dependencyCountArrow] }), (0, jsx_runtime_1.jsxs)("th", { className: `${FileListView_module_css_1.default.sizeColumn} ${FileListView_module_css_1.default.sortable}`, style: { cursor: 'pointer' }, onClick: handleSizeSortClick, title: "\u70B9\u51FB\u5207\u6362\u6392\u5E8F", children: ["\u5927\u5C0F ", sizeArrow] })] }) }), (0, jsx_runtime_1.jsx)("tbody", { children: displayedFiles.map((file) => ((0, jsx_runtime_1.jsxs)("tr", { onClick: () => onFileSelect(file.path), title: `点击跳转到依赖图: ${file.relativePath}`, style: { cursor: 'pointer' }, children: [(0, jsx_runtime_1.jsx)("td", { className: FileListView_module_css_1.default.sequenceColumn, children: file.id }), (0, jsx_runtime_1.jsx)("td", { className: FileListView_module_css_1.default.fileColumn, title: file.path, children: file.relativePath }), (0, jsx_runtime_1.jsx)("td", { className: FileListView_module_css_1.default.refCountColumn, children: file.dependencyCount }), (0, jsx_runtime_1.jsx)("td", { className: FileListView_module_css_1.default.sizeColumn, children: (0, dependency_tree_processor_1.formatBytes)(file.size) })] }, file.path))) })] })) : ((0, jsx_runtime_1.jsx)("div", { className: FileListView_module_css_1.default.emptyState, children: (0, jsx_runtime_1.jsx)("p", { children: "\u6CA1\u6709\u6587\u4EF6\u5339\u914D\u5F53\u524D\u7684\u7B5B\u9009\u6761\u4EF6\u3002" }) })) })] })); } //# sourceMappingURL=FileListView.js.map