Skip to content

Commit df15c28

Browse files
authored
Merge pull request #8 from OpenForgeProject/add-reports-logger
feat: add support for refreshing report files and update badge count in LogViewer
2 parents 01ab3a3 + 7d32b6f commit df15c28

File tree

4 files changed

+270
-78
lines changed

4 files changed

+270
-78
lines changed

CHANGELOG.md

+14
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,20 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
66

77
## [Unreleased]
88

9+
## [1.6.0] - 2023-10-07
10+
11+
### Added
12+
13+
- Improved report file titles by parsing content for better readability.
14+
- Added icons for different report types based on content.
15+
- Included folder names in titles for files in the "api" subdirectory.
16+
- Refactored code to improve performance
17+
- Extend badge counter to include report files
18+
19+
### Fixed
20+
21+
- Fixed issue with empty directories being included in the report list.
22+
923
## [1.5.1] - 2024-12-05
1024

1125
### Fixed

package.json

+16-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "magento-log-viewer",
33
"displayName": "Magento Log Viewer",
44
"description": "A Visual Studio Code extension to view and manage Magento log files.",
5-
"version": "1.5.1",
5+
"version": "1.6.0",
66
"publisher": "MathiasElle",
77
"icon": "resources/logo.png",
88
"repository": {
@@ -34,6 +34,11 @@
3434
"command": "magento-log-viewer.refreshLogFiles",
3535
"title": "Refresh Log Files",
3636
"icon": "$(refresh)"
37+
},
38+
{
39+
"command": "magento-log-viewer.refreshReportFiles",
40+
"title": "Refresh Report Files",
41+
"icon": "$(refresh)"
3742
}
3843
],
3944
"configuration": {
@@ -83,6 +88,11 @@
8388
"group": "navigation"
8489
}
8590
]
91+
},
92+
{
93+
"id": "reportFiles",
94+
"name": "Report Files",
95+
"contextualTitle": "Magento Reports"
8696
}
8797
]
8898
},
@@ -97,6 +107,11 @@
97107
"command": "magento-log-viewer.refreshLogFiles",
98108
"when": "view == logFiles && magentoLogViewer.hasMagentoRoot",
99109
"group": "navigation"
110+
},
111+
{
112+
"command": "magento-log-viewer.refreshReportFiles",
113+
"when": "view == reportFiles && magentoLogViewer.hasMagentoRoot",
114+
"group": "navigation"
100115
}
101116
]
102117
}

src/helpers.ts

+127-15
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as vscode from 'vscode';
22
import * as path from 'path';
33
import * as fs from 'fs';
4-
import { LogViewerProvider } from './logViewer';
4+
import { LogViewerProvider, ReportViewerProvider, LogItem } from './logViewer';
55

66
// Prompts the user to confirm if the current project is a Magento project.
77
export function promptMagentoProjectSelection(config: vscode.WorkspaceConfiguration, context: vscode.ExtensionContext): void {
@@ -59,25 +59,36 @@ export function showErrorMessage(message: string): void {
5959
// Activates the extension by setting up the log viewer and file system watcher.
6060
export function activateExtension(context: vscode.ExtensionContext, magentoRoot: string): void {
6161
const logViewerProvider = new LogViewerProvider(magentoRoot);
62-
const treeView = vscode.window.createTreeView('logFiles', { treeDataProvider: logViewerProvider });
62+
const reportViewerProvider = new ReportViewerProvider(magentoRoot);
6363

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 });
6666

67-
updateBadge(treeView, logViewerProvider, magentoRoot);
67+
registerCommands(context, logViewerProvider, reportViewerProvider, magentoRoot);
68+
context.subscriptions.push(logTreeView, reportTreeView);
69+
70+
updateBadge(logTreeView, logViewerProvider, reportViewerProvider, magentoRoot);
6871

6972
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());
7484

75-
context.subscriptions.push(watcher);
85+
context.subscriptions.push(logWatcher, reportWatcher);
7686
}
7787

7888
// 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 {
8090
vscode.commands.registerCommand('magento-log-viewer.refreshLogFiles', () => logViewerProvider.refresh());
91+
vscode.commands.registerCommand('magento-log-viewer.refreshReportFiles', () => reportViewerProvider.refresh());
8192
vscode.commands.registerCommand('magento-log-viewer.openFile', (filePath: string, lineNumber?: number) => {
8293
openFile(filePath, lineNumber);
8394
});
@@ -117,21 +128,56 @@ export function clearAllLogFiles(logViewerProvider: LogViewerProvider, magentoRo
117128
}
118129

119130
// 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 = () => {
122133
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` };
125141

126142
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();
127148
};
128149

129150
logViewerProvider.onDidChangeTreeData(updateBadgeCount);
151+
reportViewerProvider.onDidChangeTreeData(updateBadgeCount);
130152
updateBadgeCount();
131153

132154
vscode.commands.executeCommand('setContext', 'magentoLogViewerBadge', 0);
133155
}
134156

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+
135181
// Checks if the given path is a valid directory.
136182
export function isValidPath(filePath: string): boolean {
137183
try {
@@ -167,3 +213,69 @@ export function getIconForLogLevel(level: string): vscode.ThemeIcon {
167213
default: return new vscode.ThemeIcon('circle-outline');
168214
}
169215
}
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

Comments
 (0)