Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: CI

on:
push:
branches: ["dev", "main"]
pull_request:
branches: ["dev", "main"]
workflow_dispatch:

jobs:
frontend:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "npm"

- name: Install dependencies
run: npm ci

- name: Lint
run: npm run lint

- name: Test
run: npm test

- name: Build
run: npm run build

backend:
runs-on: ubuntu-latest
defaults:
run:
working-directory: rf-engine
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.9"
cache: "pip"
cache-dependency-path: rf-engine/requirements.txt

- name: Install dependencies
run: pip install -r requirements.txt pytest

- name: Test
run: pytest tests/ -v
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added

- **Per-Node Coverage Visualization (P6-1)**: Multi-Site Analysis composite overlay now renders each selected node's coverage as a distinct color instead of one flat cyan mask, so overlapping/redundant sites are visually distinguishable. Simulation node markers and the Sites results table are color-matched to the same coverage patches.

### Changed

- **Backend**: Refactored `rf-engine/core/viewshed_proc.py` to share a single pixel-projection helper instead of three near-identical copies of the same coordinate-mapping logic.
- Added `eslint-plugin-react`'s `jsx-uses-vars` rule to `eslint.config.js` -- the previous config had no way to recognize JSX component usage, producing ~100 false-positive "unused import" warnings that were masking real ones.
- Added a `ci.yml` GitHub Actions workflow that runs frontend lint/test/build and the `rf-engine` pytest suite on every push and PR to `dev`/`main`.

### Fixed

- Dead `elevation` variable, unused caught SSE-parse error, and stale `eslint-disable` directives now flagged/cleaned up now that lint output is trustworthy again.
- `ROADMAP.md` had a duplicated P5-6/P5-7 section from a copy-paste error.
- `README.md` linked to `Documentation/pwa-guide.md`, which never existed; the guide has been written.
- Resolved all production `npm audit` findings (critical `fast-xml-parser` via `@loaders.gl/xml`, high-severity `lodash`, moderate `protocol-buffers-schema`) and the dev-tooling findings (`vite`, `vitest`, `brace-expansion`).

### Removed

- Dropped `itmlogic` from `rf-engine/requirements.txt` -- it was declared but never imported (tracked as ROADMAP P4-1; re-add when that's implemented).

## [1.16.1] - 2026-02-26

### Fixed
Expand Down
45 changes: 45 additions & 0 deletions Documentation/pwa-guide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Progressive Web App (PWA) Guide

meshRF ships as an installable **Progressive Web App**, so you can run it in its own window on desktop or add it to your home screen on mobile, without needing an app store.

## 1. Installing on Desktop (Chrome / Edge)

1. Open meshRF in your browser (e.g. `http://localhost`, or wherever your instance is hosted).
2. Look for the **install icon** (⊕ or a monitor-with-arrow icon) in the address bar.
3. Click it, then **Install**.

meshRF now runs in its own standalone window, separate from your regular browser tabs, with no address bar or browser chrome.

> [!TIP]
> If you don't see the install icon, open the browser menu (⋮) and look for **"Install meshRF..."** or **"Apps" → "Install this site as an app"**.

## 2. Installing on Mobile (iOS / Android)

**iOS (Safari):**

1. Open meshRF in Safari.
2. Tap the **Share** icon.
3. Select **"Add to Home Screen"**.

**Android (Chrome):**

1. Open meshRF in Chrome.
2. Tap the **⋮** menu.
3. Select **"Install app"** (or **"Add to Home screen"**).

## 3. Offline Behavior

meshRF pre-caches its application shell (UI, static assets, and the WASM propagation engine) so the app **loads instantly even without a network connection**.

- The map UI and offline-capable tools (Link Analysis, ITM/WASM calculations) work without a live connection to the `rf-engine` backend.
- Tools that require the backend (Viewshed, Site Optimization, elevation lookups) still need a network path to your `rf-engine` instance — offline mode covers the app shell, not backend-dependent physics.
- API requests (`/api/*`) are **not** cached; they always go to the network. If a request fails while offline, it is queued via background sync and retried automatically once connectivity returns.

## 4. Updates

New versions are detected automatically. When an update is available, meshRF shows an in-app prompt — accept it to reload with the latest version. This avoids silently serving a stale cached build.

## 5. Uninstalling

- **Desktop**: Open the app, click the **⋮** menu in its window title bar, and choose **"Uninstall meshRF"** (or remove it from `chrome://apps`).
- **iOS/Android**: Long-press the home screen icon and choose **Remove/Uninstall**, same as any other app.
22 changes: 7 additions & 15 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MeshRF Propagation Engine Roadmap

**Last Updated:** 2026-02-09
**Last Updated:** 2026-07-24

---

Expand Down Expand Up @@ -60,7 +60,7 @@ Allow CSV import to include optional per-node columns: antenna height, device ty

### P4-1: Server-Side ITM via itmlogic

`itmlogic` is listed in `requirements.txt` but never imported. Implement as a true Python ITM fallback for server-side batch processing and environments where WASM isn't available. Enables Celery workers to run ITM asynchronously.
`itmlogic` was previously listed in `requirements.txt` but never imported, so it was dropped as a dead dependency (2026-07). Re-add it when this is implemented as a true Python ITM fallback for server-side batch processing and environments where WASM isn't available. Enables Celery workers to run ITM asynchronously.

**Files:** `rf-engine/rf_physics.py`, `rf-engine/tasks/`

Expand Down Expand Up @@ -151,20 +151,12 @@ The ITM supports time/location/situation variability percentages (currently fixe

#### P5-7: Export Capabilities (Completed)

**Features:** Multi-Site Analysis now computes unique coverage per site and marginal gain contribution.

#### P5-6: Pareto Frontier Analysis

**Problem:** Single score hides trade-offs.
**Solution:** Compute and visualize the Pareto frontier for multi-objective optimization (Elevation vs Coverage vs Access).

#### P5-7: Export Capabilities (Completed)

**Status:** ✅ Implemented in Phase 5 (CSV/KML).

## Upcoming Features (v1.16.0)
## Recently Completed

### P6-1: Per-Node Coverage Visualization
### P6-1: Per-Node Coverage Visualization (Completed)

**Problem:** Multi-Site analysis shows a merged composite, making it hard to distinguish which node covers which area.
**Solution:** Refactor backend to return individual coverage masks or labeled bitmasks. Render individual node boundaries (dashed lines) or distinct color layers in the frontend to visualize exact per-node coverage.
**Status:** ✅ Implemented 2026-07-24.
**Problem:** Multi-Site analysis showed a single merged composite, making it hard to distinguish which node covers which area.
**Solution:** Backend (`rf-engine/core/viewshed_proc.py`) assigns each selected node a distinct evenly-spaced hue and renders per-node coverage as alpha-composited color layers instead of one flat overlay -- overlapping nodes blend naturally. Each result carries a `color` field. Frontend matches simulation node markers (`OptimizationLayerManager.jsx`) and the Sites results table (`SitesTab.jsx`) to the same color so a node's map marker, popup, and coverage patch are visually tied together.
12 changes: 10 additions & 2 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import js from '@eslint/js'
import globals from 'globals'
import react from 'eslint-plugin-react'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'

Expand All @@ -21,19 +22,26 @@ export default [
},
},
plugins: {
react,
'react-hooks': reactHooks,
'react-refresh': reactRefresh,
},
settings: {
react: { version: 'detect' },
},
rules: {
...js.configs.recommended.rules,
...reactHooks.configs.recommended.rules,
// Only the rule that marks JSX-referenced identifiers as "used" -- we don't
// want the rest of eslint-plugin-react's stylistic/prop-types rule set.
'react/jsx-uses-vars': 'error',
'react-refresh/only-export-components': [
'warn',
{ allowConstantExport: true },
],
'no-unused-vars': [
'warn',
{
'warn',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_|React',
caughtErrorsIgnorePattern: '^_'
Expand Down
Loading
Loading