|
1 | 1 | import * as vscode from 'vscode';
|
2 | 2 | import * as path from 'path';
|
3 | 3 | import * as fs from 'fs';
|
4 |
| -import { LogViewerProvider } from './logViewer'; |
| 4 | +import { LogViewerProvider, ReportViewerProvider, LogItem } from './logViewer'; |
5 | 5 |
|
6 | 6 | // Prompts the user to confirm if the current project is a Magento project.
|
7 | 7 | export function promptMagentoProjectSelection(config: vscode.WorkspaceConfiguration, context: vscode.ExtensionContext): void {
|
@@ -59,25 +59,36 @@ export function showErrorMessage(message: string): void {
|
59 | 59 | // Activates the extension by setting up the log viewer and file system watcher.
|
60 | 60 | export function activateExtension(context: vscode.ExtensionContext, magentoRoot: string): void {
|
61 | 61 | const logViewerProvider = new LogViewerProvider(magentoRoot);
|
62 |
| - const treeView = vscode.window.createTreeView('logFiles', { treeDataProvider: logViewerProvider }); |
| 62 | + const reportViewerProvider = new ReportViewerProvider(magentoRoot); |
63 | 63 |
|
64 |
| - registerCommands(context, logViewerProvider, magentoRoot); |
65 |
| - context.subscriptions.push(treeView); |
| 64 | + const logTreeView = vscode.window.createTreeView('logFiles', { treeDataProvider: logViewerProvider }); |
| 65 | + const reportTreeView = vscode.window.createTreeView('reportFiles', { treeDataProvider: reportViewerProvider }); |
66 | 66 |
|
67 |
| - updateBadge(treeView, logViewerProvider, magentoRoot); |
| 67 | + registerCommands(context, logViewerProvider, reportViewerProvider, magentoRoot); |
| 68 | + context.subscriptions.push(logTreeView, reportTreeView); |
| 69 | + |
| 70 | + updateBadge(logTreeView, logViewerProvider, reportViewerProvider, magentoRoot); |
68 | 71 |
|
69 | 72 | const logPath = path.join(magentoRoot, 'var', 'log');
|
70 |
| - const watcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(logPath, '*')); |
71 |
| - watcher.onDidChange(() => logViewerProvider.refresh()); |
72 |
| - watcher.onDidCreate(() => logViewerProvider.refresh()); |
73 |
| - watcher.onDidDelete(() => logViewerProvider.refresh()); |
| 73 | + const reportPath = path.join(magentoRoot, 'var', 'report'); |
| 74 | + |
| 75 | + const logWatcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(logPath, '*')); |
| 76 | + logWatcher.onDidChange(() => logViewerProvider.refresh()); |
| 77 | + logWatcher.onDidCreate(() => logViewerProvider.refresh()); |
| 78 | + logWatcher.onDidDelete(() => logViewerProvider.refresh()); |
| 79 | + |
| 80 | + const reportWatcher = vscode.workspace.createFileSystemWatcher(new vscode.RelativePattern(reportPath, '*')); |
| 81 | + reportWatcher.onDidChange(() => reportViewerProvider.refresh()); |
| 82 | + reportWatcher.onDidCreate(() => reportViewerProvider.refresh()); |
| 83 | + reportWatcher.onDidDelete(() => reportViewerProvider.refresh()); |
74 | 84 |
|
75 |
| - context.subscriptions.push(watcher); |
| 85 | + context.subscriptions.push(logWatcher, reportWatcher); |
76 | 86 | }
|
77 | 87 |
|
78 | 88 | // Registers commands for the extension.
|
79 |
| -export function registerCommands(context: vscode.ExtensionContext, logViewerProvider: LogViewerProvider, magentoRoot: string): void { |
| 89 | +export function registerCommands(context: vscode.ExtensionContext, logViewerProvider: LogViewerProvider, reportViewerProvider: ReportViewerProvider, magentoRoot: string): void { |
80 | 90 | vscode.commands.registerCommand('magento-log-viewer.refreshLogFiles', () => logViewerProvider.refresh());
|
| 91 | + vscode.commands.registerCommand('magento-log-viewer.refreshReportFiles', () => reportViewerProvider.refresh()); |
81 | 92 | vscode.commands.registerCommand('magento-log-viewer.openFile', (filePath: string, lineNumber?: number) => {
|
82 | 93 | openFile(filePath, lineNumber);
|
83 | 94 | });
|
@@ -117,21 +128,56 @@ export function clearAllLogFiles(logViewerProvider: LogViewerProvider, magentoRo
|
117 | 128 | }
|
118 | 129 |
|
119 | 130 | // Updates the badge count for the tree view based on the number of log entries.
|
120 |
| -export function updateBadge(treeView: vscode.TreeView<unknown>, logViewerProvider: LogViewerProvider, magentoRoot: string): void { |
121 |
| - const updateBadgeCount = () => { |
| 131 | +export function updateBadge(treeView: vscode.TreeView<unknown>, logViewerProvider: LogViewerProvider, reportViewerProvider: ReportViewerProvider, magentoRoot: string): void { |
| 132 | + const updateBadgeCount = () => { |
122 | 133 | const logFiles = logViewerProvider.getLogFilesWithoutUpdatingBadge(path.join(magentoRoot, 'var', 'log'));
|
123 |
| - const totalEntries = logFiles.reduce((count, file) => count + parseInt(file.description?.match(/\d+/)?.[0] || '0', 10), 0); |
124 |
| - treeView.badge = { value: totalEntries, tooltip: `${totalEntries} log entries` }; |
| 134 | + const reportFiles = getAllReportFiles(path.join(magentoRoot, 'var', 'report')); |
| 135 | + |
| 136 | + const totalLogEntries = logFiles.reduce((count, file) => count + parseInt(file.description?.match(/\d+/)?.[0] || '0', 10), 0); |
| 137 | + const totalReportFiles = reportFiles.length; |
| 138 | + |
| 139 | + const totalEntries = totalLogEntries + totalReportFiles; |
| 140 | + treeView.badge = { value: totalEntries, tooltip: `${totalEntries} log and report entries` }; |
125 | 141 |
|
126 | 142 | vscode.commands.executeCommand('setContext', 'magentoLogViewer.hasLogFiles', totalEntries > 0);
|
| 143 | + |
| 144 | + // Update status bar item |
| 145 | + const statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 100); |
| 146 | + statusBarItem.text = `Magento Log-Entries: ${totalEntries}`; |
| 147 | + statusBarItem.show(); |
127 | 148 | };
|
128 | 149 |
|
129 | 150 | logViewerProvider.onDidChangeTreeData(updateBadgeCount);
|
| 151 | + reportViewerProvider.onDidChangeTreeData(updateBadgeCount); |
130 | 152 | updateBadgeCount();
|
131 | 153 |
|
132 | 154 | vscode.commands.executeCommand('setContext', 'magentoLogViewerBadge', 0);
|
133 | 155 | }
|
134 | 156 |
|
| 157 | +function getAllReportFiles(dir: string): LogItem[] { |
| 158 | + if (!pathExists(dir)) { |
| 159 | + return []; |
| 160 | + } |
| 161 | + |
| 162 | + const items: LogItem[] = []; |
| 163 | + const files = fs.readdirSync(dir); |
| 164 | + |
| 165 | + files.forEach(file => { |
| 166 | + const filePath = path.join(dir, file); |
| 167 | + if (fs.lstatSync(filePath).isDirectory()) { |
| 168 | + items.push(...getAllReportFiles(filePath)); |
| 169 | + } else if (fs.lstatSync(filePath).isFile()) { |
| 170 | + items.push(new LogItem(file, vscode.TreeItemCollapsibleState.None, { |
| 171 | + command: 'magento-log-viewer.openFile', |
| 172 | + title: 'Open Log File', |
| 173 | + arguments: [filePath] |
| 174 | + })); |
| 175 | + } |
| 176 | + }); |
| 177 | + |
| 178 | + return items; |
| 179 | +} |
| 180 | + |
135 | 181 | // Checks if the given path is a valid directory.
|
136 | 182 | export function isValidPath(filePath: string): boolean {
|
137 | 183 | try {
|
@@ -167,3 +213,69 @@ export function getIconForLogLevel(level: string): vscode.ThemeIcon {
|
167 | 213 | default: return new vscode.ThemeIcon('circle-outline');
|
168 | 214 | }
|
169 | 215 | }
|
| 216 | + |
| 217 | +export function getLogItems(dir: string, parseTitle: (filePath: string) => string, getIcon: (filePath: string) => vscode.ThemeIcon): LogItem[] { |
| 218 | + if (!pathExists(dir)) { |
| 219 | + return []; |
| 220 | + } |
| 221 | + |
| 222 | + const items: LogItem[] = []; |
| 223 | + const files = fs.readdirSync(dir); |
| 224 | + |
| 225 | + files.forEach(file => { |
| 226 | + const filePath = path.join(dir, file); |
| 227 | + if (fs.lstatSync(filePath).isDirectory()) { |
| 228 | + const subItems = getLogItems(filePath, parseTitle, getIcon); |
| 229 | + if (subItems.length > 0) { |
| 230 | + items.push(...subItems); |
| 231 | + } |
| 232 | + } else if (fs.lstatSync(filePath).isFile()) { |
| 233 | + const title = parseTitle(filePath); |
| 234 | + const logFile = new LogItem(title, vscode.TreeItemCollapsibleState.None, { |
| 235 | + command: 'magento-log-viewer.openFile', |
| 236 | + title: 'Open Log File', |
| 237 | + arguments: [filePath] |
| 238 | + }); |
| 239 | + logFile.iconPath = getIcon(filePath); |
| 240 | + items.push(logFile); |
| 241 | + } |
| 242 | + }); |
| 243 | + |
| 244 | + return items; |
| 245 | +} |
| 246 | + |
| 247 | +export function parseReportTitle(filePath: string): string { |
| 248 | + try { |
| 249 | + const fileContent = fs.readFileSync(filePath, 'utf-8'); |
| 250 | + const report = JSON.parse(fileContent); |
| 251 | + |
| 252 | + if (filePath.includes('/api/')) { |
| 253 | + const folderName = path.basename(path.dirname(filePath)); |
| 254 | + const capitalizedFolderName = folderName.charAt(0).toUpperCase() + folderName.slice(1); |
| 255 | + return `${capitalizedFolderName}: ${report}`; |
| 256 | + } |
| 257 | + |
| 258 | + return report['0'] || path.basename(filePath); |
| 259 | + } catch (error) { |
| 260 | + return path.basename(filePath); |
| 261 | + } |
| 262 | +} |
| 263 | + |
| 264 | +export function getIconForReport(filePath: string): vscode.ThemeIcon { |
| 265 | + try { |
| 266 | + const fileContent = fs.readFileSync(filePath, 'utf-8'); |
| 267 | + const report = JSON.parse(fileContent); |
| 268 | + |
| 269 | + if (filePath.includes('/api/')) { |
| 270 | + return new vscode.ThemeIcon('warning'); |
| 271 | + } |
| 272 | + |
| 273 | + if (report['0'] && report['0'].toLowerCase().includes('error')) { |
| 274 | + return new vscode.ThemeIcon('error'); |
| 275 | + } |
| 276 | + |
| 277 | + return new vscode.ThemeIcon('file'); |
| 278 | + } catch (error) { |
| 279 | + return new vscode.ThemeIcon('file'); |
| 280 | + } |
| 281 | +} |
0 commit comments