Skip to content

Commit 7100c99

Browse files
committed
feat: add loading when saving settings and fix backend panic
1 parent b832fc4 commit 7100c99

8 files changed

Lines changed: 56 additions & 39 deletions

File tree

README.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Hyperloop Control Station H11
2-
![Testing View](https://raw.githubusercontent.com/Hyperloop-UPV/webpage/5c1c827d82d380689856ee61af43da30da22e0fc/src/assets/backgrounds/testing-view.png)
2+
3+
![Testing View](https://raw.githubusercontent.com/Hyperloop-UPV/webpage/5c1c827d82d380689856ee61af43da30da22e0fc/src/assets/backgrounds/testing-view.png)
34

45
## Monorepo usage
56

@@ -20,17 +21,17 @@ Before starting, ensure you have the following installed:
2021

2122
Our `pnpm-workspace.yaml` defines the following workspaces:
2223

23-
| Workspace | Language | Description |
24-
| :----------------------------- | :------- | :--------------------------------------------- |
25-
| `testing-view` | TS/React | Web interface for telemetry testing |
26-
| `competition-view` | TS/React | UI for the competition |
27-
| `backend` | Go | Data ingestion and pod communication server |
28-
| `packet-sender` | Rust | Utility for simulating vehicle packets |
29-
| `electron-app` | JS | The main Control Station desktop application |
30-
| `@workspace/ui` | TS/React | Shared UI component library (frontend-kit) |
31-
| `@workspace/core` | TS | Shared business logic and types (frontend-kit) |
32-
| `@workspace/eslint-config` | ESLint | Common ESLint configuration (frontend-kit) |
33-
| `@workspace/typescript-config` | TS | Common TypeScript configuration (frontend-kit) |
24+
| Workspace | Language | Description |
25+
| :----------------------------- | :------- | :---------------------------------------------------- |
26+
| `testing-view` | TS/React | Web interface for telemetry testing |
27+
| `competition-view` | TS/React | UI for the competition |
28+
| `backend` | Go | Data ingestion and pod communication server |
29+
| `packet-sender` | Rust | Utility for simulating vehicle packets |
30+
| `hyperloop-control-station` | JS | The main Control Station electron desktop application |
31+
| `@workspace/ui` | TS/React | Shared UI component library (frontend-kit) |
32+
| `@workspace/core` | TS | Shared business logic and types (frontend-kit) |
33+
| `@workspace/eslint-config` | ESLint | Common ESLint configuration (frontend-kit) |
34+
| `@workspace/typescript-config` | TS | Common TypeScript configuration (frontend-kit) |
3435

3536
---
3637

electron-app/build.mjs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,10 @@ logger.header("Hyperloop Control Station Build");
254254

255255
if (frontendBuilt && !process.env.CI) {
256256
logger.info("Finalizing Electron...");
257-
run("pnpm --filter electron-app install --frozen-lockfile", __dirname);
257+
run(
258+
"pnpm --filter hyperloop-control-station install --frozen-lockfile",
259+
__dirname
260+
);
258261
}
259262

260263
if (allSuccess) {

electron-app/main.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ if (process.platform === "linux") {
3636
// Setup IPC handlers for renderer process communication
3737
setupIpcHandlers();
3838

39-
app.setName("hyperloop-control-station");
40-
4139
// App lifecycle: wait for Electron to be ready
4240
app.whenReady().then(async () => {
4341
// Get the screen width and height

electron-app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"name": "electron-app",
2+
"name": "hyperloop-control-station",
33
"version": "1.0.0",
44
"description": "Hyperloop UPV Control Station",
55
"main": "main.js",

electron-app/src/processes/backend.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,6 @@ async function startBackend(logWindow = null) {
108108
return reject(new Error(`Failed to start backend: ${error.message}`));
109109
});
110110

111-
// If the backend didn't fail in this period of time, resolve the promise
112-
setTimeout(() => {
113-
resolve(backendProcess);
114-
}, 2000);
115-
116111
// Handle process exit
117112
backendProcess.on("close", (code) => {
118113
logger.backend.info(`Backend process exited with code ${code}`);
@@ -131,7 +126,14 @@ async function startBackend(logWindow = null) {
131126
// Clear error message after showing
132127
lastBackendError = null;
133128
}
129+
130+
backendProcess = null;
134131
});
132+
133+
// If the backend didn't fail in this period of time, resolve the promise
134+
setTimeout(() => {
135+
resolve(backendProcess);
136+
}, 2000);
135137
});
136138
}
137139

frontend/testing-view/src/components/settings/SettingsDialog.tsx

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import {
77
DialogHeader,
88
DialogTitle,
99
} from "@workspace/ui/components/shadcn/dialog";
10-
import { useEffect, useState } from "react";
10+
import { Loader2 } from "@workspace/ui/icons";
11+
import { useEffect, useState, useTransition } from "react";
1112
import {
1213
AlertTriangle,
1314
CheckCircle2,
@@ -24,6 +25,7 @@ export const SettingsDialog = () => {
2425
const setRestarting = useStore((s) => s.setRestarting);
2526
const [localConfig, setLocalConfig] = useState<ConfigData | null>(null);
2627
const [isSynced, setIsSynced] = useState(false);
28+
const [isSaving, startSaving] = useTransition();
2729

2830
const loadConfig = async () => {
2931
if (window.electronAPI) {
@@ -54,24 +56,26 @@ export const SettingsDialog = () => {
5456
}, [isSettingsOpen]);
5557

5658
const handleSave = async () => {
57-
if (window.electronAPI) {
58-
await window.electronAPI.saveConfig(localConfig);
59-
} else {
60-
console.log("Electron API not available. Using default config.");
61-
}
59+
startSaving(async () => {
60+
if (window.electronAPI) {
61+
await window.electronAPI.saveConfig(localConfig);
62+
} else {
63+
console.log("Electron API not available. Using default config.");
64+
}
6265

63-
setRestarting(true);
66+
setRestarting(true);
6467

65-
setTimeout(() => {
66-
socketService.connect();
67-
setSettingsOpen(false);
68-
setRestarting(false);
69-
}, config.SETTINGS_RESPONSE_TIMEOUT);
68+
setTimeout(() => {
69+
socketService.connect();
70+
setSettingsOpen(false);
71+
setRestarting(false);
72+
}, config.SETTINGS_RESPONSE_TIMEOUT);
73+
});
7074
};
7175

7276
return (
7377
<Dialog open={isSettingsOpen} onOpenChange={setSettingsOpen}>
74-
<DialogContent className="flex max-h-[85vh] max-w-2xl min-w-[800px] flex-col">
78+
<DialogContent className="flex max-h-[85vh] min-w-[800px] max-w-2xl flex-col">
7579
<DialogHeader className="pr-5">
7680
<div className="flex items-center justify-between">
7781
<DialogTitle>System Configuration</DialogTitle>
@@ -101,7 +105,15 @@ export const SettingsDialog = () => {
101105
<Button variant="ghost" onClick={() => setSettingsOpen(false)}>
102106
Cancel
103107
</Button>
104-
<Button onClick={handleSave}>Save Changes</Button>
108+
<Button onClick={handleSave} disabled={isSaving}>
109+
{isSaving ? (
110+
<>
111+
<Loader2 className="h-4 w-4 animate-spin" /> Saving...
112+
</>
113+
) : (
114+
"Save Changes"
115+
)}
116+
</Button>
105117
</DialogFooter>
106118
</DialogContent>
107119
</Dialog>

frontend/testing-view/src/components/settings/SettingsForm.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export const SettingsForm = ({ config, onChange }: SettingsFormProps) => {
101101
<div className="space-y-8">
102102
{schema.map((section) => (
103103
<section key={section.title} className="space-y-4">
104-
<h3 className="text-muted-foreground border-b pb-1 text-sm font-bold tracking-wider uppercase">
104+
<h3 className="text-muted-foreground border-b pb-1 text-sm font-bold uppercase tracking-wider">
105105
{section.title}
106106
</h3>
107107
<div className="grid gap-4">

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
"dev": "turbo dev",
66
"dev:main": "turbo dev:main",
77
"build": "turbo build",
8-
"build:win": "pnpm --filter electron-app build:win",
9-
"build:linux": "pnpm --filter electron-app build:linux",
10-
"build:mac": "pnpm --filter electron-app build:mac",
8+
"build:win": "pnpm --filter hyperloop-control-station build:win",
9+
"build:linux": "pnpm --filter hyperloop-control-station build:linux",
10+
"build:mac": "pnpm --filter hyperloop-control-station build:mac",
11+
"start": "pnpm --filter hyperloop-control-station start",
1112
"lint": "turbo lint",
1213
"preview": "turbo preview",
1314
"test": "turbo test",

0 commit comments

Comments
 (0)