improve MQTT error bubble up and massage communitymqtt + debug etc. for version management. Closes #70

This commit is contained in:
Jack Kingsman
2026-03-17 20:32:57 -07:00
parent 020acbda02
commit e33bc553f5
22 changed files with 344 additions and 155 deletions
+1 -2
View File
@@ -129,8 +129,7 @@ frontend/src/
│ │ └── RepeaterConsolePane.tsx # CLI console with history
│ └── ui/ # shadcn/ui primitives
├── types/
── d3-force-3d.d.ts # Type declarations for d3-force-3d
│ └── globals.d.ts # Global type declarations (__APP_VERSION__, __COMMIT_HASH__)
── d3-force-3d.d.ts # Type declarations for d3-force-3d
└── test/
├── setup.ts
├── fixtures/websocket_events.json
+3 -1
View File
@@ -275,7 +275,9 @@ export function SettingsModal(props: SettingsModalProps) {
{shouldRenderSection('about') && (
<section className={sectionWrapperClass}>
{renderSectionHeader('about')}
{isSectionVisible('about') && <SettingsAboutSection className={sectionContentClass} />}
{isSectionVisible('about') && (
<SettingsAboutSection health={health} className={sectionContentClass} />
)}
</section>
)}
</div>
@@ -1,10 +1,17 @@
import type { HealthStatus } from '../../types';
import { Separator } from '../ui/separator';
const GITHUB_URL = 'https://github.com/jkingsman/Remote-Terminal-for-MeshCore';
export function SettingsAboutSection({ className }: { className?: string }) {
const version = __APP_VERSION__;
const commit = __COMMIT_HASH__;
export function SettingsAboutSection({
health,
className,
}: {
health?: HealthStatus | null;
className?: string;
}) {
const version = health?.app_info?.version ?? 'unknown';
const commit = health?.app_info?.commit_hash;
return (
<div className={className}>
@@ -14,8 +21,14 @@ export function SettingsAboutSection({ className }: { className?: string }) {
<h3 className="text-lg font-semibold">RemoteTerm for MeshCore</h3>
<div className="text-sm text-muted-foreground">
v{version}
<span className="mx-1.5">·</span>
<span className="font-mono text-xs">{commit}</span>
{commit ? (
<>
<span className="mx-1.5">·</span>
<span className="font-mono text-xs" title={commit}>
{commit}
</span>
</>
) : null}
</div>
</div>
+19 -11
View File
@@ -1,20 +1,28 @@
import { render, screen } from '@testing-library/react';
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
import { describe, expect, it } from 'vitest';
import { SettingsAboutSection } from '../components/settings/SettingsAboutSection';
describe('SettingsAboutSection', () => {
beforeEach(() => {
vi.stubGlobal('__APP_VERSION__', '3.2.0-test');
vi.stubGlobal('__COMMIT_HASH__', 'deadbeef');
});
afterEach(() => {
vi.unstubAllGlobals();
});
it('renders the debug support snapshot link', () => {
render(<SettingsAboutSection />);
render(
<SettingsAboutSection
health={{
status: 'ok',
radio_connected: true,
radio_initializing: false,
connection_info: 'Serial: /dev/ttyUSB0',
app_info: {
version: '3.2.0-test',
commit_hash: 'deadbeef',
},
database_size_mb: 1.2,
oldest_undecrypted_timestamp: null,
fanout_statuses: {},
bots_disabled: false,
}}
/>
);
const link = screen.getByRole('link', { name: /Open debug support snapshot/i });
expect(link).toHaveAttribute('href', '/api/debug');
+6
View File
@@ -51,12 +51,18 @@ export interface FanoutStatusEntry {
status: string;
}
export interface AppInfo {
version: string;
commit_hash: string | null;
}
export interface HealthStatus {
status: string;
radio_connected: boolean;
radio_initializing: boolean;
radio_state?: 'connected' | 'initializing' | 'connecting' | 'disconnected' | 'paused';
connection_info: string | null;
app_info?: AppInfo | null;
radio_device_info?: {
model: string | null;
firmware_build: string | null;
-2
View File
@@ -1,2 +0,0 @@
declare const __APP_VERSION__: string;
declare const __COMMIT_HASH__: string;
-15
View File
@@ -1,24 +1,9 @@
import path from "path"
import { execSync } from "child_process"
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
function getCommitHash(): string {
// Docker builds pass VITE_COMMIT_HASH as an env var
if (process.env.VITE_COMMIT_HASH) return process.env.VITE_COMMIT_HASH;
try {
return execSync('git rev-parse --short HEAD', { encoding: 'utf-8' }).trim();
} catch {
return 'unknown';
}
}
export default defineConfig({
plugins: [react()],
define: {
__APP_VERSION__: JSON.stringify(process.env.npm_package_version ?? 'unknown'),
__COMMIT_HASH__: JSON.stringify(getCommitHash()),
},
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),