124 lines
5.1 KiB
Markdown
124 lines
5.1 KiB
Markdown
# HiveOps Browser — System Info Footer Status Bar
|
|
|
|
## Context
|
|
The HiveOps Browser (Electron 28) currently loads `https://incident.bcos.cloud` directly in the main `BrowserWindow`. The user wants a persistent footer status bar — native to the browser chrome like a menu/status bar — showing: logged-in user, memory usage, CPU usage, and service health. This replaces the fragile approach of having the Svelte frontend call `electronAPI.getUserProfile()`.
|
|
|
|
## Architecture Change
|
|
|
|
**Current**: `BrowserWindow` → `loadURL('https://incident.bcos.cloud')` (fills full window)
|
|
|
|
**New**: `BrowserWindow` (no content) →
|
|
- `WebContentsView` (top, full width, `height - 32px`) → `loadURL('https://incident.bcos.cloud')`
|
|
- `WebContentsView` (bottom, full width, `32px`) → `loadFile('src/renderer/statusbar.html')`
|
|
|
|
Electron 28's `WebContentsView` API is used (replaces deprecated `BrowserView`).
|
|
|
|
---
|
|
|
|
## Files to Modify / Create
|
|
|
|
### 1. `src/main/preload.js` — Add 2 new IPC bindings
|
|
```javascript
|
|
getSystemInfo: () => ipcRenderer.invoke('get-system-info'),
|
|
getServiceStatus: () => ipcRenderer.invoke('get-service-status'),
|
|
```
|
|
|
|
### 2. `src/main/main.js` — Major changes
|
|
- Import `WebContentsView` from electron
|
|
- Create `incidentView` (WebContentsView with preload) and `statusbarView` (WebContentsView with preload)
|
|
- Replace `mainWindow.loadURL(allowedUrl)` with:
|
|
- `mainWindow.contentView.addChildView(incidentView)` → `incidentView.webContents.loadURL(allowedUrl)`
|
|
- `mainWindow.contentView.addChildView(statusbarView)` → `statusbarView.webContents.loadFile('statusbar.html')`
|
|
- Migrate all `mainWindow.webContents.*` event listeners to `incidentView.webContents.*`:
|
|
- `did-finish-load`, `dom-ready`, `console-message`, `did-fail-load`, `page-title-updated`, `will-navigate`
|
|
- Move session header injection to `incidentView.webContents.session.webRequest.onBeforeSendHeaders`
|
|
- Add `mainWindow.on('resize', updateBounds)` to keep views sized correctly
|
|
- Add `updateBounds()` helper: sets incidentView to `{x:0, y:0, w, h-32}` and statusbarView to `{x:0, y:h-32, w, h:32}`
|
|
- Add new IPC handlers:
|
|
- `get-system-info` → uses Node `os` module: `{ memory: {used, total, percent}, cpu: {load}, user: authManager.getUserInfo() }`
|
|
- `get-service-status` → pings health endpoints with `net.request()`, returns array of `{name, status: 'up'|'down'|'checking'}`
|
|
|
|
### 3. `src/renderer/statusbar.html` — New file
|
|
Compact 32px dark status bar with 3 sections:
|
|
|
|
```
|
|
[ 👤 John Doe ADMIN ] ──── [ RAM 52% ████░░ 4.2/8GB ] [ CPU 23% ] ──── [ ● Auth ● Incident ● Config ] ──── [ v2.0.40 ]
|
|
```
|
|
|
|
- Dark background `#0f0f1a` with subtle top border `rgba(255,255,255,0.08)`
|
|
- White/muted text, monospace for metrics
|
|
- Service dots: green `●` = up, red `●` = down, yellow `●` = checking
|
|
- Uses `window.electronAPI.getSystemInfo()` + `getServiceStatus()` on load and every 5s
|
|
- Memory: inline bar visualization
|
|
- No external dependencies (pure HTML/CSS/JS)
|
|
|
|
### Service Health Endpoints (defaults, from known architecture)
|
|
```javascript
|
|
const SERVICE_ENDPOINTS = [
|
|
{ name: 'Auth', url: `${authServerUrl}/actuator/health` },
|
|
{ name: 'Incident', url: `${allowedUrl}/actuator/health` },
|
|
{ name: 'Config', url: `${apiBaseUrl.replace('/api/v1','')}/actuator/health` },
|
|
];
|
|
```
|
|
These use the existing config values. Timeout: 3s. Returns up/down per service.
|
|
|
|
---
|
|
|
|
## Key Technical Details
|
|
|
|
### WebContentsView bounds management
|
|
```javascript
|
|
function updateBounds() {
|
|
const STATUS_BAR_H = 32;
|
|
const [w, h] = mainWindow.getContentSize();
|
|
incidentView.setBounds({ x: 0, y: 0, width: w, height: h - STATUS_BAR_H });
|
|
statusbarView.setBounds({ x: 0, y: h - STATUS_BAR_H, width: w, height: STATUS_BAR_H });
|
|
}
|
|
mainWindow.on('resize', updateBounds);
|
|
```
|
|
|
|
### Header injection moves to incidentView's session
|
|
```javascript
|
|
incidentView.webContents.session.webRequest.onBeforeSendHeaders(...)
|
|
```
|
|
|
|
### System info IPC handler
|
|
```javascript
|
|
const os = require('os');
|
|
ipcMain.handle('get-system-info', () => {
|
|
const total = os.totalmem();
|
|
const free = os.freemem();
|
|
const used = total - free;
|
|
const [load1] = os.loadavg(); // Linux/Mac; 0 on Windows
|
|
return {
|
|
memory: { used, total, percent: Math.round((used / total) * 100) },
|
|
cpu: { load: Math.min(100, Math.round(load1 * 100 / os.cpus().length)) },
|
|
user: authManager.getUserInfo(),
|
|
version: app.getVersion(),
|
|
};
|
|
});
|
|
```
|
|
|
|
### Service status uses electron net module
|
|
```javascript
|
|
const { net } = require('electron');
|
|
// HEAD request with 3s timeout per service
|
|
```
|
|
|
|
---
|
|
|
|
## Cleanup
|
|
- Remove `getUserProfile` call from `hiveops-incident/frontend/src/App.svelte` (the sidebar-user block) since user info is now shown in the browser's own status bar.
|
|
|
|
---
|
|
|
|
## Build & Verify
|
|
1. `cd /source/hiveops-src/hiveops-browser && npm start` — dev test
|
|
2. Confirm status bar appears at bottom of window
|
|
3. Confirm incident app fills remaining space and works normally
|
|
4. Confirm user name/role shows (must be logged in)
|
|
5. Confirm memory/CPU metrics update every 5s
|
|
6. Confirm service dots show correct status
|
|
7. `npm run build:linux` — build production package
|
|
8. Test with `dist/linux-unpacked/hiveops-browser --no-sandbox`
|