Skip to content

Commit 39e4c5a

Browse files
committed
Ausführung-08: Add logging output to TopoViewer
1 parent cceadd1 commit 39e4c5a

File tree

6 files changed

+134
-66
lines changed

6 files changed

+134
-66
lines changed

src/topoViewer/common/webview-ui/managerGroupManagement.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ export class ManagerGroupManagement {
472472
export class ManagerGroupManagemetn extends ManagerGroupManagement {
473473
constructor(...args: ConstructorParameters<typeof ManagerGroupManagement>) {
474474
// Warn at runtime when deprecated alias is used
475-
console.warn('ManagerGroupManagemetn is deprecated. Use ManagerGroupManagement instead.');
475+
log.warn('ManagerGroupManagemetn is deprecated. Use ManagerGroupManagement instead.');
476476
super(...args);
477477
}
478478
}

src/topoViewer/common/webview-ui/managerLayoutAlgo.ts

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import cytoscape from 'cytoscape';
22
import topoViewerState from './state';
3+
import { log } from '../logging/webviewLogger';
34

45
// Use globally registered style loader to avoid duplicating implementations
56
function loadCytoStyle(cy: cytoscape.Core, theme?: 'light' | 'dark'): void {
@@ -50,7 +51,7 @@ export class ManagerLayoutAlgo {
5051
// Just handle scaling, let cytoscape-leaflet handle positions
5152
const factor = this.calculateGeoScale();
5253
this.applyGeoScale(true, factor);
53-
console.debug('[GeoScale] zoom factor', factor, 'zoom', this.cytoscapeLeafletMap?.getZoom());
54+
log.debug(`[GeoScale] zoom factor ${factor} zoom ${this.cytoscapeLeafletMap?.getZoom()}`);
5455
this.zoomRaf = null;
5556
});
5657
};
@@ -62,7 +63,7 @@ export class ManagerLayoutAlgo {
6263
// Just handle scaling, let cytoscape-leaflet handle positions
6364
const factor = this.calculateGeoScale();
6465
this.applyGeoScale(true, factor);
65-
console.debug('[GeoScale] zoomend factor', factor, 'zoom', this.cytoscapeLeafletMap?.getZoom());
66+
log.debug(`[GeoScale] zoomend factor ${factor} zoom ${this.cytoscapeLeafletMap?.getZoom()}`);
6667
this.zoomEndTimeout = null;
6768
}, 300);
6869
};
@@ -80,7 +81,7 @@ export class ManagerLayoutAlgo {
8081
this.renderDebounceTimer = window.setTimeout(() => {
8182
const factor = this.calculateGeoScale();
8283
if (Math.abs(factor - this.lastGeoScale) > 0.001) {
83-
console.debug('[GeoScale] render factor', factor);
84+
log.debug(`[GeoScale] render factor ${factor}`);
8485
this.applyGeoScale(true, factor);
8586
}
8687
this.renderDebounceTimer = null;
@@ -112,7 +113,7 @@ export class ManagerLayoutAlgo {
112113
const cy = this.getCy();
113114
if (!cy) return;
114115

115-
console.debug('[GeoScale] apply', enable, 'factor', factor);
116+
log.debug(`[GeoScale] apply ${enable} factor ${factor}`);
116117

117118
if (enable) {
118119
cy.nodes().forEach((n) => {
@@ -439,13 +440,13 @@ export class ManagerLayoutAlgo {
439440
public viewportDrawerLayoutGeoMap(): void {
440441
const cy = this.getCy();
441442
if (!cy) {
442-
console.error('[GeoMap] No cytoscape instance found');
443+
log.error('[GeoMap] No cytoscape instance found');
443444
return;
444445
}
445446

446447
// If already initialized, just ensure it's visible
447448
if (this.isGeoMapInitialized) {
448-
console.log('[GeoMap] Geo-map already initialized, ensuring visibility');
449+
log.info('[GeoMap] Geo-map already initialized, ensuring visibility');
449450
const leafletContainer = document.getElementById('cy-leaflet');
450451
if (leafletContainer) {
451452
leafletContainer.classList.remove('hidden');
@@ -459,7 +460,7 @@ export class ManagerLayoutAlgo {
459460
return;
460461
}
461462

462-
console.log('[GeoMap] Initializing geo-positioning layout');
463+
log.info('[GeoMap] Initializing geo-positioning layout');
463464

464465
this.viewportDrawerDisableGeoMap();
465466

@@ -533,17 +534,19 @@ export class ManagerLayoutAlgo {
533534

534535
// Ensure the container has proper dimensions
535536
const containerRect = leafletContainer.getBoundingClientRect();
536-
console.log('[GeoMap] Leaflet container created/shown', {
537+
log.info({
538+
msg: '[GeoMap] Leaflet container created/shown',
537539
width: containerRect.width,
538540
height: containerRect.height,
539541
display: (leafletContainer as HTMLElement).style.display,
540542
className: leafletContainer.className
541543
});
542-
console.log('[GeoMap] Initializing cytoscape-leaflet plugin');
544+
log.info('[GeoMap] Initializing cytoscape-leaflet plugin');
543545
try {
544546
// Make sure cy is visible and has dimensions
545547
const cyRect = cy.container()?.getBoundingClientRect();
546-
console.log('[GeoMap] Cytoscape container dimensions:', {
548+
log.info({
549+
msg: '[GeoMap] Cytoscape container dimensions',
547550
width: cyRect?.width,
548551
height: cyRect?.height
549552
});
@@ -557,20 +560,21 @@ export class ManagerLayoutAlgo {
557560
this.cytoscapeLeafletLeaf.map.removeLayer(this.cytoscapeLeafletLeaf.defaultTileLayer);
558561
}
559562
this.cytoscapeLeafletMap = this.cytoscapeLeafletLeaf.map;
560-
console.log('[GeoMap] Cytoscape-leaflet initialized successfully', {
563+
log.info({
564+
msg: '[GeoMap] Cytoscape-leaflet initialized successfully',
561565
map: this.cytoscapeLeafletMap,
562566
leaf: this.cytoscapeLeafletLeaf
563567
});
564568
} catch (error) {
565-
console.error('[GeoMap] Error initializing cytoscape-leaflet:', error);
569+
log.error(`[GeoMap] Error initializing cytoscape-leaflet: ${error}`);
566570
return;
567571
}
568572
// add basic tile layer
569573
if (!window.L) {
570-
console.error('[GeoMap] Leaflet library (L) not available');
574+
log.error('[GeoMap] Leaflet library (L) not available');
571575
return;
572576
}
573-
console.log('[GeoMap] Adding tile layer');
577+
log.info('[GeoMap] Adding tile layer');
574578
window.L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager_labels_under/{z}/{x}/{y}{r}.png', {
575579
attribution: '&copy; OpenStreetMap contributors &copy; CARTO',
576580
subdomains: 'abcd',
@@ -602,7 +606,7 @@ export class ManagerLayoutAlgo {
602606
// We only need to handle scaling
603607
}
604608

605-
console.log('[GeoMap] Applying preset layout with geo positions');
609+
log.info('[GeoMap] Applying preset layout with geo positions');
606610

607611
// First, ensure all nodes have valid lat/lng before applying layout
608612
cy.nodes().forEach((node) => {
@@ -611,9 +615,9 @@ export class ManagerLayoutAlgo {
611615
const lat = parseFloat(data.lat);
612616
const lng = parseFloat(data.lng);
613617
if (isNaN(lat) || isNaN(lng)) {
614-
console.warn(`[GeoMap] Node ${node.id()} missing valid geo coordinates, will use defaults`);
618+
log.warn(`[GeoMap] Node ${node.id()} missing valid geo coordinates, will use defaults`);
615619
} else {
616-
console.log(`[GeoMap] Node ${node.id()} has coordinates: lat=${lat}, lng=${lng}`);
620+
log.info(`[GeoMap] Node ${node.id()} has coordinates: lat=${lat}, lng=${lng}`);
617621
}
618622
});
619623

@@ -633,24 +637,24 @@ export class ManagerLayoutAlgo {
633637
}
634638

635639
// This should not happen as assignMissingLatLng was called earlier
636-
console.error(`[GeoMap] Node ${node.id()} still missing geo coordinates during layout`);
640+
log.error(`[GeoMap] Node ${node.id()} still missing geo coordinates during layout`);
637641
// Keep current position to avoid jumping to ocean
638642
return { x: node.position().x, y: node.position().y };
639643
}
640644
} as any).run();
641645

642-
console.log('[GeoMap] Layout applied, fitting map');
646+
log.info('[GeoMap] Layout applied, fitting map');
643647

644648
// Give the map time to render before fitting
645649
setTimeout(() => {
646650
if (this.cytoscapeLeafletLeaf && this.cytoscapeLeafletLeaf.fit) {
647651
this.cytoscapeLeafletLeaf.fit();
648-
console.log('[GeoMap] Map fitted to nodes');
652+
log.info('[GeoMap] Map fitted to nodes');
649653
}
650654

651655
const factor = this.calculateGeoScale();
652656
this.applyGeoScale(true, factor);
653-
console.log('[GeoMap] Scale applied with factor:', factor);
657+
log.info(`[GeoMap] Scale applied with factor: ${factor}`);
654658
}, 100);
655659

656660
cy.on('add', this.onElementAddedBound);
@@ -660,14 +664,14 @@ export class ManagerLayoutAlgo {
660664
geoMapButtons[i].classList.remove('hidden');
661665
}
662666

663-
console.log('[GeoMap] Geo-positioning layout initialization complete');
667+
log.info('[GeoMap] Geo-positioning layout initialization complete');
664668
}
665669

666670
public viewportDrawerDisableGeoMap(): void {
667671
const cy = this.getCy();
668672
if (!cy || !this.isGeoMapInitialized) return;
669673

670-
console.log('[GeoMap] Disabling geo-positioning layout');
674+
log.info('[GeoMap] Disabling geo-positioning layout');
671675

672676
// Remove the leaflet-active class and restore background
673677
cy.container()?.classList.remove('leaflet-active');
@@ -899,9 +903,9 @@ export class ManagerLayoutAlgo {
899903
* Nodes become non-editable and the Leaflet map receives pointer events.
900904
*/
901905
public viewportButtonsGeoMapPan(): void {
902-
console.log('[GeoMap] Switching to pan mode');
906+
log.info('[GeoMap] Switching to pan mode');
903907
if (!this.cytoscapeLeafletLeaf) {
904-
console.error('[GeoMap] Cytoscape-leaflet not initialized');
908+
log.error('[GeoMap] Cytoscape-leaflet not initialized');
905909
return;
906910
}
907911
// Switch pointer events to the map
@@ -916,17 +920,17 @@ export class ManagerLayoutAlgo {
916920

917921
this.cytoscapeLeafletLeaf.setZoomControlOpacity('');
918922
this.cytoscapeLeafletLeaf.map.dragging.enable();
919-
console.log('[GeoMap] Pan mode enabled');
923+
log.info('[GeoMap] Pan mode enabled');
920924
}
921925

922926
/**
923927
* Enables node editing mode for the GeoMap layout.
924928
* Pointer events are forwarded to Cytoscape while map dragging is disabled.
925929
*/
926930
public viewportButtonsGeoMapEdit(): void {
927-
console.log('[GeoMap] Switching to edit mode');
931+
log.info('[GeoMap] Switching to edit mode');
928932
if (!this.cytoscapeLeafletLeaf) {
929-
console.error('[GeoMap] Cytoscape-leaflet not initialized');
933+
log.error('[GeoMap] Cytoscape-leaflet not initialized');
930934
return;
931935
}
932936
// Switch pointer events back to cytoscape
@@ -940,7 +944,7 @@ export class ManagerLayoutAlgo {
940944

941945
this.cytoscapeLeafletLeaf.setZoomControlOpacity(0.5);
942946
this.cytoscapeLeafletLeaf.map.dragging.disable();
943-
console.log('[GeoMap] Edit mode enabled');
947+
log.info('[GeoMap] Edit mode enabled');
944948
}
945949

946950
/**

src/topoViewer/common/webview-ui/managerVscodeWebview.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
11
// file: managerVscodeWebview.ts
22

3+
import { log } from '../logging/webviewLogger';
4+
35
// This function is typically provided by the VS Code environment.
46
declare function acquireVsCodeApi(): any;
57

8+
// Acquire VS Code API once and expose it on the window for shared logging
9+
const vscodeApi: any = (() => {
10+
try {
11+
return (window as any).vscode ?? acquireVsCodeApi?.();
12+
} catch {
13+
return undefined;
14+
}
15+
})();
16+
17+
if (vscodeApi) {
18+
(window as any).vscode = vscodeApi;
19+
}
20+
621
/* eslint-disable no-unused-vars */
722
export interface LoggerLike {
823
warn: (...args: any[]) => void;
@@ -22,13 +37,13 @@ export class VscodeMessageSender {
2237
/**
2338
* Creates an instance of VscodeMessageSender.
2439
* Initializes the VS Code API and sets up a listener for messages from the extension host.
25-
* @param logger - Optional logger implementing a warn method. Defaults to console.
40+
* @param logger - Optional logger implementing a warn method. Defaults to log.
2641
* @throws Will throw an error if the VS Code API is not available in this environment.
2742
*/
28-
constructor(logger: LoggerLike = console) {
43+
constructor(logger: LoggerLike = log) {
2944
this.logger = logger;
30-
if (typeof acquireVsCodeApi === "function") {
31-
this.vsCode = acquireVsCodeApi();
45+
if (vscodeApi) {
46+
this.vsCode = vscodeApi;
3247
} else {
3348
throw new Error("VS Code API is not available in this environment.");
3449
}

src/topoViewer/edit/providers/topoViewerEditorWebUiFacade.ts

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -408,32 +408,55 @@ topology:
408408
* Interface for messages received from the webview.
409409
*/
410410
interface WebviewMessage {
411-
type: string;
411+
type?: string;
412412
requestId?: string;
413413
endpointName?: string;
414414
payload?: string;
415+
command?: string;
416+
level?: string;
417+
message?: string;
418+
fileLine?: string;
415419
}
416420

417421
// Listen for incoming messages from the webview.
418422
panel.webview.onDidReceiveMessage(async (msg: WebviewMessage) => {
419-
log.info(`Received POST message from frontEnd: ${JSON.stringify(msg, null, 2)}`);
420-
421-
const payloadObj = JSON.parse(msg.payload as string);
422-
log.info(`Received POST message from frontEnd Pretty Payload:\n${JSON.stringify(payloadObj, null, 2)}`);
423-
424-
// Validate that the message is an object.
425423
if (!msg || typeof msg !== 'object') {
426424
log.error('Invalid message received.');
427425
return;
428426
}
429427

428+
if (msg.command === 'topoViewerLog') {
429+
const { level, message, fileLine } = msg;
430+
const text = fileLine ? `${fileLine} - ${message}` : message;
431+
switch (level) {
432+
case 'error':
433+
log.error(text);
434+
break;
435+
case 'warn':
436+
log.warn(text);
437+
break;
438+
case 'debug':
439+
log.debug(text);
440+
break;
441+
default:
442+
log.info(text);
443+
}
444+
return;
445+
}
446+
447+
log.info(`Received POST message from frontEnd: ${JSON.stringify(msg, null, 2)}`);
448+
430449
// Process only messages of type 'POST'.
431450
if (msg.type !== 'POST') {
432451
log.warn(`Unrecognized message type: ${msg.type}`);
433452
return;
434453
}
435454

436455
const { requestId, endpointName, payload } = msg;
456+
const payloadObj = payload ? JSON.parse(payload) : undefined;
457+
if (payloadObj !== undefined) {
458+
log.info(`Received POST message from frontEnd Pretty Payload:\n${JSON.stringify(payloadObj, null, 2)}`);
459+
}
437460
if (!requestId || !endpointName) {
438461
const missingFields = [];
439462
if (!requestId) missingFields.push('requestId');

src/topoViewer/view/providers/topoViewerPanel.ts

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,35 @@ export async function createTopoViewerPanel(options: PanelOptions): Promise<vsco
8585
viewerParams
8686
);
8787

88-
panel.webview.onDidReceiveMessage(async msg => {
89-
if (!msg || typeof msg !== 'object' || msg.type !== 'POST') {
90-
return;
91-
}
88+
panel.webview.onDidReceiveMessage(async msg => {
89+
if (!msg || typeof msg !== 'object') {
90+
return;
91+
}
92+
93+
if (msg.command === 'topoViewerLog') {
94+
const { level, message, fileLine } = msg as any;
95+
const text = fileLine ? `${fileLine} - ${message}` : message;
96+
switch (level) {
97+
case 'error':
98+
log.error(text);
99+
break;
100+
case 'warn':
101+
log.warn(text);
102+
break;
103+
case 'debug':
104+
log.debug(text);
105+
break;
106+
default:
107+
log.info(text);
108+
}
109+
return;
110+
}
111+
112+
if (msg.type !== 'POST') {
113+
return;
114+
}
92115

93-
const { requestId, endpointName, payload } = msg;
116+
const { requestId, endpointName, payload } = msg;
94117
let result: unknown = null;
95118
let error: string | undefined;
96119

0 commit comments

Comments
 (0)