diff --git a/packages/react-components/src/components/trace-context-component.tsx b/packages/react-components/src/components/trace-context-component.tsx index 2136e8a96..bc8059f7c 100644 --- a/packages/react-components/src/components/trace-context-component.tsx +++ b/packages/react-components/src/components/trace-context-component.tsx @@ -48,6 +48,7 @@ export interface TraceContextProps { removeResizeHandler: (handler: () => void) => void; backgroundTheme: string; persistedState?: PersistedState; + serverStatus?: boolean; } export interface TraceContextState { @@ -491,20 +492,29 @@ export class TraceContextComponent extends React.Component 0 && (this.props.outputs.length || this.props.overviewDescriptor); return ( -
this.onContextMenu(event)} - onKeyDown={event => this.onKeyDown(event)} - onKeyUp={event => this.onKeyUp(event)} - ref={this.traceContextContainer} - > - - - {shouldRenderOutputs ? this.renderOutputs() : this.renderPlaceHolder()} -
+ <> + {/* Render the grey-out overlay if the server is down */} + {serverStatus === false && ( +
+
Please start the server to resume using the application.
+
+ )} +
this.onContextMenu(event)} + onKeyDown={event => this.onKeyDown(event)} + onKeyUp={event => this.onKeyUp(event)} + ref={this.traceContextContainer} + > + + + {shouldRenderOutputs ? this.renderOutputs() : this.renderPlaceHolder()} +
+ ); } diff --git a/packages/react-components/style/trace-viewer.css b/packages/react-components/style/trace-viewer.css index 00f0b8067..b9d795379 100644 --- a/packages/react-components/style/trace-viewer.css +++ b/packages/react-components/style/trace-viewer.css @@ -13,4 +13,24 @@ div { .trace-viewer-container { margin: 0px 5px 0px 5px; height: 100%; +} + +/* Grey out container */ +.overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); /* Semi-transparent black */ + display: flex; + justify-content: center; + align-items: center; + z-index: 999; /* Ensure the overlay appears on top */ +} + +.warning-text { + color: white; /* Color of the warning text */ + text-align: center; + font-size: 24px; } \ No newline at end of file diff --git a/theia-extensions/viewer-prototype/src/browser/trace-explorer/trace-explorer-sub-widgets/trace-explorer-server-status-widget.tsx b/theia-extensions/viewer-prototype/src/browser/trace-explorer/trace-explorer-sub-widgets/trace-explorer-server-status-widget.tsx index 313a8625d..9f1307b43 100644 --- a/theia-extensions/viewer-prototype/src/browser/trace-explorer/trace-explorer-sub-widgets/trace-explorer-server-status-widget.tsx +++ b/theia-extensions/viewer-prototype/src/browser/trace-explorer/trace-explorer-sub-widgets/trace-explorer-server-status-widget.tsx @@ -25,30 +25,27 @@ export class TraceExplorerServerStatusWidget extends ReactWidget { render(): React.ReactNode { - if (this.serverOn) { - return ( -
- Server Status - -
- ); - } else { - return ( -
- Server Status - + Server Status + -
- ); - } + + ); + } } diff --git a/theia-extensions/viewer-prototype/src/browser/trace-viewer/trace-viewer.tsx b/theia-extensions/viewer-prototype/src/browser/trace-viewer/trace-viewer.tsx index 416ebcf59..f480b41f0 100644 --- a/theia-extensions/viewer-prototype/src/browser/trace-viewer/trace-viewer.tsx +++ b/theia-extensions/viewer-prototype/src/browser/trace-viewer/trace-viewer.tsx @@ -11,6 +11,7 @@ import { TraceContextComponent, PersistedState } from 'traceviewer-react-components/lib/components/trace-context-component'; +import { TraceServerConnectionStatusClient } from '../../common/trace-server-connection-status'; import { Experiment } from 'tsp-typescript-client/lib/models/experiment'; import { TheiaMessageManager } from '../theia-message-manager'; import { ThemeService } from '@theia/core/lib/browser/theming'; @@ -56,6 +57,7 @@ export class TraceViewerWidget extends ReactWidget implements StatefulWidget { protected traceContextComponent: React.RefObject; protected persistedState?: PersistedState; protected loadTraceOverview = true; + protected serverStatus: boolean; protected resizeHandlers: (() => void)[] = []; protected readonly addResizeHandler = (h: () => void): void => { @@ -105,6 +107,7 @@ export class TraceViewerWidget extends ReactWidget implements StatefulWidget { @inject(ThemeService) protected readonly themeService: ThemeService; @inject(OverviewPreferences) protected overviewPreferences: OverviewPreferences; @inject(FileDialogService) protected readonly fileDialogService: FileDialogService; + @inject(TraceServerConnectionStatusClient) protected readonly connectionStatusService: TraceServerConnectionStatusClient; @postConstruct() protected init(): void { @@ -118,6 +121,7 @@ export class TraceViewerWidget extends ReactWidget implements StatefulWidget { this.title.closable = true; this.addClass('theia-trace-open'); this.backgroundTheme = this.themeService.getCurrentTheme().type; + this.serverStatus = this.connectionStatusService.status; this.toDispose.push(this.themeService.onDidColorThemeChange(() => this.updateBackgroundTheme())); if (!this.options.traceUUID) { this.initialize(); @@ -160,6 +164,7 @@ export class TraceViewerWidget extends ReactWidget implements StatefulWidget { if (this.loadTraceOverview) { this.doHandleTraceOverviewOpenedSignal(this.openedExperiment?.UUID); } + } protected readonly toDisposeOnNewExplorer = new DisposableCollection(); @@ -173,6 +178,7 @@ export class TraceViewerWidget extends ReactWidget implements StatefulWidget { signalManager().on(Signals.OPEN_OVERVIEW_OUTPUT, this.onTraceOverviewOpened); signalManager().on(Signals.OVERVIEW_OUTPUT_SELECTED, this.onTraceOverviewOutputSelected); signalManager().on(Signals.SAVE_AS_CSV, this.onSaveAsCSV); + this.connectionStatusService.addServerStatusChangeListener(this.onServerStatusChange); } protected updateBackgroundTheme(): void { @@ -188,6 +194,8 @@ export class TraceViewerWidget extends ReactWidget implements StatefulWidget { signalManager().off(Signals.OPEN_OVERVIEW_OUTPUT, this.onTraceOverviewOpened); signalManager().off(Signals.OVERVIEW_OUTPUT_SELECTED, this.onTraceOverviewOutputSelected); signalManager().off(Signals.SAVE_AS_CSV, this.onSaveAsCSV); + this.connectionStatusService.removeServerStatusChangeListener(this.onServerStatusChange); + } async initialize(): Promise { @@ -336,6 +344,11 @@ export class TraceViewerWidget extends ReactWidget implements StatefulWidget { this.loadTraceOverview = false; } + private onServerStatusChange = (status: boolean): void => { + this.serverStatus = status; + this.update(); + }; + private async fetchMarkerSets(expUUID: string) { const markers = await this.tspClient.fetchMarkerSets(expUUID); const markersResponse = markers.getModel(); @@ -390,6 +403,7 @@ export class TraceViewerWidget extends ReactWidget implements StatefulWidget { backgroundTheme={this.backgroundTheme} persistedState={this.persistedState} messageManager={this._signalHandler} + serverStatus={this.serverStatus} /> ) : ( 'Trace is loading...'