signalk-czone 0.3.0-beta.16 → 0.3.0-beta.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0-beta.17
4
+
5
+ - Prompts for Signal K login when CZone circuit requests are unauthorized, returning to the webapp after sign-in (#34).
6
+ - Shows permission and circuit-loading errors with a retry option instead of waiting indefinitely for Signal K.
7
+
3
8
  ## 0.3.0-beta.16
4
9
 
5
10
  - Adds an opt-in Victron GX switch pane for CZone circuits on the GX, Remote Console and VRM (#33).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "signalk-czone",
3
- "version": "0.3.0-beta.16",
3
+ "version": "0.3.0-beta.17",
4
4
  "description": "BETA: Signal K CZone monitoring and control using dynamically parsed ZCF configuration and NMEA 2000",
5
5
  "main": "index.js",
6
6
  "keywords": [
@@ -42,7 +42,7 @@
42
42
  "icon.png"
43
43
  ],
44
44
  "scripts": {
45
- "test": "node test/zcf.test.js && node test/zcf-fixtures.test.js && node test/circuit-state.test.js && node test/czone.test.js && node test/nmea2000.test.js && node test/control-x-plus.test.js && node test/signalk.test.js && node test/write.test.js && node test/circuit-status.test.js && node test/status-mapping-regression.test.js && node test/state.test.js && node test/config-network.test.js && node test/config-namespace.test.js && node test/monitoring.test.js && node test/confirm-off.test.js && node test/webapp-current.test.js && node test/bridge.test.js && node test/victron-switches.test.js && node test/victron-label-steady.test.js && node test/switch-pane-plugin.test.js && node test/trends.test.js && node test/inputs.test.js && node --require ./test/helpers/gx-low-space.cjs test/trends.test.js"
45
+ "test": "node test/zcf.test.js && node test/zcf-fixtures.test.js && node test/circuit-state.test.js && node test/czone.test.js && node test/nmea2000.test.js && node test/control-x-plus.test.js && node test/signalk.test.js && node test/write.test.js && node test/circuit-status.test.js && node test/status-mapping-regression.test.js && node test/state.test.js && node test/config-network.test.js && node test/config-namespace.test.js && node test/monitoring.test.js && node test/confirm-off.test.js && node test/webapp-current.test.js && node test/webapp-auth.test.js && node test/bridge.test.js && node test/victron-switches.test.js && node test/victron-label-steady.test.js && node test/switch-pane-plugin.test.js && node test/trends.test.js && node test/inputs.test.js && node --require ./test/helpers/gx-low-space.cjs test/trends.test.js"
46
46
  },
47
47
  "dependencies": {
48
48
  "signalk-czone-zcf": "0.1.0-beta.2"
package/public/index.html CHANGED
@@ -353,7 +353,7 @@
353
353
  <div class="connection" id="connection"><i></i><span>Connecting to Signal K…</span></div>
354
354
  <section class="hero">
355
355
  <h1 id="heroTitle">Your Boat, Your Circuits</h1>
356
- <p>Monitor and control your boat's electrical systems.</p><div id="writeGate" style="display:none;margin-top:12px;padding:10px 12px;border:1px solid rgba(255,195,77,.35);border-radius:10px;background:rgba(255,195,77,.08);color:#ffd98a;font-size:12px;line-height:1.5"></div>
356
+ <p>Monitor and control your boat's electrical systems.</p><div id="loadError" role="alert" hidden style="position:relative;z-index:1;margin-top:12px;padding:12px;border:1px solid var(--amber);border-radius:10px;background:var(--panel);line-height:1.5"></div><div id="writeGate" style="display:none;margin-top:12px;padding:10px 12px;border:1px solid rgba(255,195,77,.35);border-radius:10px;background:rgba(255,195,77,.08);color:#ffd98a;font-size:12px;line-height:1.5"></div>
357
357
  </section>
358
358
  <section class="section trend-panel" id="trendPanel">
359
359
  <div class="section-head"><span>📈</span><div><h2 id="trendTitle"></h2><span class="subtle" id="trendSub"></span></div><button type="button" class="sort trend-close" onclick="closeTrend()" aria-label="Close trend">✕ Close</button></div>
@@ -700,10 +700,45 @@
700
700
  if (Array.isArray(data.modes)) modes = data.modes;
701
701
  if (data.activeMode) activeMode = data.activeMode;
702
702
  }
703
+ function showLoadError(message, signIn) {
704
+ const el = document.querySelector('#loadError');
705
+ el.textContent = message + ' ';
706
+ const link = document.createElement('a');
707
+ link.style.color = 'var(--cyan)';
708
+ if (signIn) {
709
+ const here = window.location.pathname + window.location.search + window.location.hash;
710
+ link.href = '/admin/#/login?redirect=' + encodeURIComponent(here);
711
+ link.textContent = 'Sign in';
712
+ } else {
713
+ link.href = window.location.href;
714
+ link.textContent = 'Retry';
715
+ link.onclick = event => { event.preventDefault(); window.location.reload(); };
716
+ }
717
+ el.appendChild(link);
718
+ el.hidden = false;
719
+ }
720
+
721
+ async function showCircuitRequestError(response) {
722
+ let signIn = response.status === 401;
723
+ if (response.status === 403) {
724
+ try {
725
+ const r = await fetch('/skServer/loginStatus', { cache:'no-store', credentials:'include' });
726
+ if (r.ok) signIn = (await r.json()).status === 'notLoggedIn';
727
+ } catch (_) { /* Keep the permission error if login status cannot be checked. */ }
728
+ }
729
+ const message = signIn
730
+ ? 'Sign in to Signal K to load CZone circuits.'
731
+ : response.status === 403
732
+ ? 'Signal K denied access to CZone circuits. Your account may not have the required permissions.'
733
+ : 'Could not load CZone circuits (HTTP ' + response.status + '). Check the Signal K server and CZone plugin.';
734
+ showLoadError(message, signIn);
735
+ updateSocketIndicator(signIn ? 'Sign in required' : 'Unable to load CZone circuits', false);
736
+ }
737
+
703
738
  async function refreshOnce(reason = 'manual') {
704
739
  try {
705
740
  const r = await fetch(`${API}/circuits`, { cache:'no-store', credentials:'include' });
706
- if (!r.ok) throw new Error('Signal K plugin unavailable (HTTP ' + r.status + ')');
741
+ if (!r.ok) { await showCircuitRequestError(r); return false; }
707
742
  const data = await r.json();
708
743
  const incoming = Array.isArray(data.circuits) ? data.circuits : [];
709
744
  console.debug('[CZone UI] REST refresh', reason, { circuits: incoming.length, modes: Array.isArray(data.modes) ? data.modes.length : 0, sendingEnabled: data.sendingEnabled === true, nmeaReady: data.nmeaReady === true });
@@ -719,12 +754,14 @@
719
754
  : socketEverOpen
720
755
  ? `<i></i><span>Live updates lost · reconnecting… (circuits as of ${new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit', second: '2-digit' })})</span>`
721
756
  : '<i></i><span>Circuits loaded · connecting live updates…</span>';
757
+ document.querySelector('#loadError').hidden = true;
722
758
  render();
723
759
  return true;
724
760
  } catch (e) {
725
761
  console.warn('[CZone UI] REST refresh failed', reason, e);
726
762
  document.querySelector('#connection').classList.remove('ok');
727
- document.querySelector('#connection').innerHTML = '<i></i><span>Waiting for Signal K…</span>';
763
+ showLoadError('Could not load CZone circuits. Check the Signal K connection and CZone plugin. ' + e.message, false);
764
+ updateSocketIndicator('Unable to load CZone circuits', false);
728
765
  return false;
729
766
  }
730
767
  }
@@ -1334,7 +1371,8 @@
1334
1371
  }
1335
1372
 
1336
1373
  refreshVesselName();
1337
- refreshOnce('initial-load').then(() => {
1374
+ refreshOnce('initial-load').then(loaded => {
1375
+ if (!loaded) return;
1338
1376
  if (circuits.length) {
1339
1377
  connectSocket();
1340
1378
  sendSubscriptions();