Merge remote-tracking branch 'upstream/main' into core-rb2

# Conflicts:
#	CHANGELOG.md
#	build/vite.js
#	scripts/package-boundaries.json
#	server/standalone/vite.config.js
#	src/app/scene.js
#	src/layers/vessels/queries.js
#	src/standalone/application.js
#	src/tooling/viteBuild.test.mjs
#	src/ui/cockpitInstruments.js
#	src/ui/layerPanel.js
#	src/ui/panelPositionControls.js
This commit is contained in:
Meir Michanie committed 2026-10-10 23:15:54 +02:00
commit 71f7a58169
475 files changed
+67826 -4965

No files matched your search

+17 -6
View File
@@ -76,7 +76,7 @@ const PANEL_GROUPS = [
},
{
label: 'Cameras',
ids: ['cctv', 'recent-imagery'],
ids: ['cctv', 'recent-imagery', 'street-level'],
},
{
label: 'Infrastructure',
@@ -117,6 +117,7 @@ const PANEL_LABELS = {
'ais-live-vessels': 'Live Vessels',
bikeshare: 'Bike Share',
cctv: 'Cameras',
'street-level': 'Street Level',
'alpr-cameras': 'Mapped ALPR Cameras',
'local-datacenters': 'Data Centers',
'local-firms': 'Active Fires',
@@ -673,7 +674,12 @@ export class LayerPanel {
}
_syncToggleButton(button, layer) {
const feedState = layer.enabled ? layerFeedState(layer.stats) : 'off';
const unavailable = layer.stats?.sourceUnavailable === true;
const feedState = unavailable
? 'unavailable'
: layer.enabled
? layerFeedState(layer.stats)
: 'off';
const transitioning =
layer.lifecycleState === 'enabling' ||
layer.lifecycleState === 'disabling';
@@ -686,7 +692,7 @@ export class LayerPanel {
for (const state of Object.keys(FEED_STATE_LABELS)) {
button.classList.toggle(
`feed-${state}`,
layer.enabled && !uncertain && feedState === state,
(layer.enabled || unavailable) && !uncertain && feedState === state,
);
}
button.dataset.feedState = transitioning
@@ -698,16 +704,21 @@ export class LayerPanel {
// click guard above prevents repeat activation without the focus loss caused
// by native `disabled`.
button.disabled = false;
button.setAttribute('aria-disabled', String(transitioning));
button.setAttribute(
'aria-disabled',
String(transitioning || (unavailable && !layer.enabled)),
);
button.setAttribute('aria-busy', String(transitioning));
button.textContent = transitioning
? lifecycleStateLabel(layer.lifecycleState)
: uncertain
? t('layers.status.uncertain')
: layer.enabled
: layer.enabled || unavailable
? t(FEED_STATE_LABEL_KEYS[feedState])
: t('layers.status.off');
const keyGuidance = layerKeyRequirementTooltip(layer);
const keyGuidance = unavailable
? String(layer.stats.error || t('layers.meta.dataSourceUnavailable'))
: layerKeyRequirementTooltip(layer);
// Name the missing key on the control itself: a row reading KEY REQUIRED
// without saying WHICH key leaves a dead control and no next step. Empty
// when the layer needs no key, or already has one.