Show current weather on the Overview
Add a weather card to the Web App Overview, wired like the OpenSky live-map
overlay and backed by the OpenWeather plugin.
- API Server: GET /api/integrations/openweather/current resolves the
caller's cascade, gates it (master/org/personal opt-in/key), and returns
trimmed current conditions for the configured or a supplied ?lat=&lon=
point; off/keyless returns {unavailable, detail} so the card degrades.
- BFF relay (forwards the location override) + route; api.js client.
- Dashboard: a Weather card stacked above Schedule showing an emoji
condition, temperature in the resolved unit, description, location, and a
feels-like/wind/humidity/cloud grid. Location follows the same cascade as
the map (drone -> phone -> browser -> default) without prompting for geo;
refreshes every 10 min while on Overview.
- validLatLon test; rebuilt embedded frontend.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
522fe450eb
commit
5960fb4806
@@ -344,6 +344,18 @@ func (a *App) handleOpenWeatherHealth(w http.ResponseWriter, r *http.Request) {
|
||||
a.doRelay(w, req)
|
||||
}
|
||||
|
||||
// GET /bff/integrations/openweather/current → API Server current conditions for the
|
||||
// Overview weather card. Forwards the optional ?lat=&lon= location override.
|
||||
func (a *App) handleOpenWeatherCurrent(w http.ResponseWriter, r *http.Request) {
|
||||
target := a.apiBaseFor(r) + "/api/integrations/openweather/current"
|
||||
if r.URL.RawQuery != "" {
|
||||
target += "?" + r.URL.RawQuery
|
||||
}
|
||||
req, _ := http.NewRequest(http.MethodGet, target, nil)
|
||||
req.Header.Set("Authorization", tokenOf(r))
|
||||
a.doRelay(w, req)
|
||||
}
|
||||
|
||||
// GET /bff/users → API Server /api/users (admin only, enforced upstream)
|
||||
func (a *App) handleListUsers(w http.ResponseWriter, r *http.Request) {
|
||||
req, _ := http.NewRequest(http.MethodGet, a.apiBaseFor(r)+"/api/users", nil)
|
||||
|
||||
-20
File diff suppressed because one or more lines are too long
+20
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+2
-2
@@ -35,8 +35,8 @@
|
||||
})()
|
||||
</script>
|
||||
<title>PilotVault — Control Panel</title>
|
||||
<script type="module" crossorigin src="./assets/index-B-DwId4e.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-Dr5W1RO_.css">
|
||||
<script type="module" crossorigin src="./assets/index-DWe3LEIB.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="./assets/index-buxVzOVb.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@@ -66,6 +66,7 @@ func main() {
|
||||
mux.HandleFunc("GET /bff/integrations/openweather", app.requireAuth(app.handleGetOpenWeather))
|
||||
mux.HandleFunc("PUT /bff/integrations/openweather", app.requireAuth(app.handlePutOpenWeather))
|
||||
mux.HandleFunc("POST /bff/integrations/openweather/health", app.requireAuth(app.handleOpenWeatherHealth))
|
||||
mux.HandleFunc("GET /bff/integrations/openweather/current", app.requireAuth(app.handleOpenWeatherCurrent))
|
||||
// User-management (role + org scoping enforced by the API Server)
|
||||
mux.HandleFunc("GET /bff/users", app.requireAuth(app.handleListUsers))
|
||||
mux.HandleFunc("POST /bff/users", app.requireAuth(app.handleCreateUser))
|
||||
|
||||
Reference in New Issue
Block a user