@signalk/charts-plugin 3.6.2 → 3.8.0

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.
Files changed (60) hide show
  1. package/.prettierignore +1 -0
  2. package/CHANGELOG.md +109 -0
  3. package/README.md +72 -0
  4. package/docs/screenshots/1_overview.png +0 -0
  5. package/docs/screenshots/2_region.png +0 -0
  6. package/docs/screenshots/3_jobs.png +0 -0
  7. package/package.json +20 -12
  8. package/plugin/cacheLayout.d.ts +72 -0
  9. package/plugin/cacheLayout.d.ts.map +1 -0
  10. package/plugin/cacheLayout.js +243 -0
  11. package/plugin/cacheLayout.js.map +1 -0
  12. package/plugin/chartDownloader.d.ts +122 -29
  13. package/plugin/chartDownloader.d.ts.map +1 -1
  14. package/plugin/chartDownloader.js +488 -313
  15. package/plugin/chartDownloader.js.map +1 -1
  16. package/plugin/chartDownloaderMBTilesHelpers.d.ts +10 -0
  17. package/plugin/chartDownloaderMBTilesHelpers.d.ts.map +1 -0
  18. package/plugin/chartDownloaderMBTilesHelpers.js +235 -0
  19. package/plugin/chartDownloaderMBTilesHelpers.js.map +1 -0
  20. package/plugin/chartDownloaderTileHelpers.d.ts +30 -0
  21. package/plugin/chartDownloaderTileHelpers.d.ts.map +1 -0
  22. package/plugin/chartDownloaderTileHelpers.js +277 -0
  23. package/plugin/chartDownloaderTileHelpers.js.map +1 -0
  24. package/plugin/charts.d.ts.map +1 -1
  25. package/plugin/charts.js +23 -5
  26. package/plugin/charts.js.map +1 -1
  27. package/plugin/constants.d.ts.map +1 -1
  28. package/plugin/index.d.ts.map +1 -1
  29. package/plugin/index.js +561 -48
  30. package/plugin/index.js.map +1 -1
  31. package/plugin/pluginStatus.js.map +1 -1
  32. package/plugin/projection.js.map +1 -1
  33. package/plugin/tileServer.d.ts +4 -1
  34. package/plugin/tileServer.d.ts.map +1 -1
  35. package/plugin/tileServer.js +48 -10
  36. package/plugin/tileServer.js.map +1 -1
  37. package/plugin/tokenProvider.d.ts +63 -0
  38. package/plugin/tokenProvider.d.ts.map +1 -0
  39. package/plugin/tokenProvider.js +258 -0
  40. package/plugin/tokenProvider.js.map +1 -0
  41. package/plugin/types.d.ts +37 -2
  42. package/plugin/types.d.ts.map +1 -1
  43. package/public/images/jobs.png +0 -0
  44. package/public/images/overview.png +0 -0
  45. package/public/images/region.png +0 -0
  46. package/public/index.html +392 -113
  47. package/public/js/index.js +620 -0
  48. package/public/leaflet/images/downloads.png +0 -0
  49. package/public/leaflet/images/layers-2x.png +0 -0
  50. package/public/leaflet/images/layers.png +0 -0
  51. package/public/leaflet/images/lifebuoy.png +0 -0
  52. package/public/leaflet/images/spritesheet-2x.png +0 -0
  53. package/public/leaflet/images/spritesheet.svg +156 -0
  54. package/public/leaflet/leaflet.css +677 -0
  55. package/public/leaflet/leaflet.draw.css +253 -0
  56. package/public/leaflet/leaflet.draw.js +2957 -0
  57. package/public/leaflet/leaflet.js +7467 -0
  58. package/public/logo.svg +0 -2
  59. package/public/style.css +351 -37
  60. package/public/index.js +0 -349
package/public/logo.svg CHANGED
@@ -13,8 +13,6 @@
13
13
  </clipPath>
14
14
  </defs>
15
15
 
16
- <rect x="0" y="0" width="128" height="128" fill="#fff"/>
17
-
18
16
  <g clip-path="url(#card)">
19
17
  <rect width="128" height="128" fill="url(#sea)"/>
20
18
 
package/public/style.css CHANGED
@@ -1,26 +1,112 @@
1
- #activeJobsTable {
1
+ body {
2
+ padding: 0;
3
+ margin: 0;
4
+ }
5
+
6
+ html,
7
+ body,
8
+ #map {
9
+ height: 100%;
2
10
  width: 100%;
3
- border-collapse: collapse;
4
- font-family: Arial, sans-serif;
5
- margin-top: 8px;
11
+ z-index: 1;
12
+ position: relative;
6
13
  }
7
14
 
8
- #activeJobsTable th,
9
- #progressTable td {
10
- border: 1px solid #ddd;
11
- padding: 6px 8px;
12
- text-align: left;
13
- vertical-align: middle;
15
+ .map-status-control {
16
+ background: rgba(0, 0, 0, 0.75);
17
+ color: #fff;
18
+ padding: 6px 10px;
14
19
  font-size: 13px;
20
+ font-family: monospace;
21
+ border-radius: 6px;
22
+ pointer-events: none;
15
23
  }
16
24
 
17
- #activeJobsTable th {
18
- background: #f4f4f4;
19
- font-weight: 600;
25
+ .modal {
26
+ position: fixed;
27
+ top: 0;
28
+ left: 0;
29
+ width: 100%;
30
+ height: 100%;
31
+ background: rgba(0, 0, 0, 0.6);
32
+ z-index: 3000;
33
+ display: flex;
34
+ align-items: center;
35
+ justify-content: center;
36
+ }
37
+
38
+ .modal.hidden {
39
+ display: none;
40
+ }
41
+
42
+ .modal-content {
43
+ background: #fff;
44
+ color: #000;
45
+ width: 90%;
46
+ max-height: 100vh;
47
+ overflow-y: auto;
48
+ border-radius: 10px;
49
+ padding: 12px;
50
+ box-shadow: 0 0 20px #aaa;
51
+ }
52
+
53
+ .modal-header {
54
+ display: flex;
55
+ justify-content: space-between;
56
+ align-items: center;
57
+ margin-bottom: 10px;
58
+ }
59
+
60
+ /* Base size for all Leaflet buttons */
61
+ .leaflet-bar a,
62
+ .leaflet-bar a.leaflet-disabled {
63
+ width: 44px;
64
+ height: 44px;
65
+ line-height: 44px;
66
+ font-size: 16px;
67
+
68
+ display: flex;
69
+ align-items: center;
70
+ justify-content: center;
71
+
72
+ border-radius: 6px; /* optional, looks modern */
73
+ }
74
+
75
+ .leaflet-draw-toolbar a {
76
+ width: 44px;
77
+ height: 44px;
78
+ padding: 0;
79
+ }
80
+
81
+ .leaflet-draw-toolbar a::before {
82
+ margin: 0;
83
+ }
84
+
85
+ .leaflet-control-layers-toggle {
86
+ width: 44px !important;
87
+ height: 44px !important;
88
+ background-size: 20px 20px;
89
+ }
90
+
91
+ /* @media (pointer: coarse) {
92
+ .leaflet-bar a,
93
+ .leaflet-control-layers-toggle {
94
+ width: 44px !important;
95
+ height: 44px !important;
96
+ line-height: 44px;
97
+ }
98
+ } */
99
+
100
+ .job {
101
+ margin-bottom: 10px;
102
+ padding: 6px;
103
+ border: 1px solid #333;
104
+ border-radius: 6px;
105
+ height: 80%;
20
106
  }
21
107
 
22
108
  .progress-bar {
23
- width: 160px;
109
+ width: 75%;
24
110
  height: 18px;
25
111
  background: #eee;
26
112
  border-radius: 6px;
@@ -57,24 +143,20 @@
57
143
  align-items: center;
58
144
  }
59
145
 
60
- .btn {
146
+ .leaflet-button {
61
147
  display: flex;
62
148
  justify-content: center;
63
149
  align-items: center;
64
- width: 36px;
65
- height: 36px;
150
+ width: 48px;
151
+ height: 48px;
66
152
  border: none;
67
153
  border-radius: 8px;
68
- cursor: pointer;
69
- background-color: #444;
70
- transition:
71
- transform 0.15s ease,
72
- background-color 0.2s ease;
154
+ background-color: #fff;
73
155
  padding: 0;
74
156
  line-height: 0;
75
157
  }
76
158
 
77
- .btn:hover {
159
+ .leaflet-button:hover {
78
160
  transform: scale(1.1);
79
161
  }
80
162
 
@@ -89,30 +171,262 @@
89
171
  stroke-linejoin: round;
90
172
  }
91
173
 
92
- .startstop-btn {
93
- background-color: #27ae60;
174
+ .hidden {
175
+ display: none;
176
+ }
177
+
178
+ /* ---------- Modern Fieldset Styling ---------- */
179
+ fieldset {
180
+ /* max-width: 560px; */
181
+ padding: 1.5rem 1.75rem 1.75rem;
182
+ border: 1px solid #e5e7eb;
183
+ border-radius: 14px;
184
+ background: #ffffff;
185
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.06);
186
+ font-family:
187
+ system-ui,
188
+ -apple-system,
189
+ Segoe UI,
190
+ Roboto,
191
+ sans-serif;
192
+ margin-top: 0.5rem;
94
193
  }
95
194
 
96
- .startstop-btn.running {
97
- background-color: #c0392b;
195
+ legend {
196
+ padding: 0 0rem;
197
+ font-weight: 600;
198
+ font-size: 0.95rem;
199
+ color: #374151;
98
200
  }
99
201
 
100
- .delete-btn {
101
- background-color: #e74c3c;
202
+ /* Section headers */
203
+ fieldset strong {
204
+ /* display: block; */
205
+ margin-top: 0.5rem;
206
+ margin-bottom: 0.5rem;
207
+ padding: 0.3rem 0.3rem;
208
+ font-size: 0.9rem;
209
+ color: #6b7280;
210
+ text-transform: uppercase;
211
+ letter-spacing: 0.04em;
102
212
  }
103
213
 
104
- .delete-btn:hover {
105
- background-color: #c0392b;
214
+ /* Labels */
215
+ fieldset label {
216
+ font-size: 0.9rem;
217
+ color: #374151;
218
+ margin-right: 0.75rem;
219
+ margin-bottom: 0.5rem;
106
220
  }
107
221
 
108
- .remove-btn {
109
- background-color: #7f8c8d;
222
+ /* Inputs & Selects */
223
+ fieldset select,
224
+ fieldset input[type='text'],
225
+ fieldset input[type='number'] {
226
+ display: block;
227
+ width: 100%;
228
+ margin-top: 0.1rem;
229
+ margin-bottom: 0.1rem;
230
+ margin-left: 0.1rem;
231
+ margin-right: 0.1rem;
232
+ padding: 0.3rem 0.3rem;
233
+ border-radius: 8px;
234
+ border: 1px solid #d1d5db;
235
+ background: #f9fafb;
236
+ font-size: 0.9rem;
237
+ transition:
238
+ border 0.2s,
239
+ box-shadow 0.2s;
110
240
  }
111
241
 
112
- .remove-btn:hover {
113
- background-color: #95a5a6;
242
+ fieldset select:focus,
243
+ fieldset input:focus {
244
+ outline: none;
245
+ border-color: #3b82f6;
246
+ box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.15);
247
+ background: #ffffff;
114
248
  }
115
249
 
116
- .hidden {
117
- display: none;
250
+ /* Radio group */
251
+ fieldset input[type='checkbox'] {
252
+ margin-right: 0.35rem;
253
+ accent-color: #3b82f6;
254
+ }
255
+
256
+ /* Bounding box grid */
257
+ fieldset div {
258
+ display: grid;
259
+ grid-template-columns: repeat(1, 1fr);
260
+ gap: 1.6rem;
261
+ margin-top: 0.4rem;
262
+ }
263
+
264
+ /* Button */
265
+
266
+ .btn {
267
+ margin-top: 0.5rem;
268
+ padding: 0.65rem 1.2rem;
269
+ border-radius: 10px;
270
+ border: none;
271
+ color: #ffffff;
272
+ font-size: 0.9rem;
273
+ font-weight: 600;
274
+ cursor: pointer;
275
+ transition:
276
+ transform 0.15s,
277
+ box-shadow 0.15s,
278
+ opacity 0.15s;
279
+ }
280
+
281
+ .btn--primary {
282
+ background: linear-gradient(135deg, #3b82f6, #2563eb);
283
+ }
284
+
285
+ .btn--primary:hover {
286
+ transform: translateY(-1px);
287
+ box-shadow: 0 6px 16px rgba(37, 99, 235, 0.35);
288
+ opacity: 0.95;
289
+ }
290
+
291
+ .btn--primary:active {
292
+ transform: translateY(0);
293
+ box-shadow: 0 3px 8px rgba(37, 99, 235, 0.3);
294
+ }
295
+
296
+ .btn--primary:disabled {
297
+ background: #9ca3af; /* gray */
298
+ cursor: not-allowed;
299
+ opacity: 0.6;
300
+ box-shadow: none;
301
+ transform: none;
302
+ }
303
+
304
+ .btn--primary:disabled:hover {
305
+ transform: none;
306
+ box-shadow: none;
307
+ opacity: 0.6;
308
+ }
309
+
310
+ .btn--danger {
311
+ background: linear-gradient(135deg, #ef4444, #b91c1c);
312
+ }
313
+
314
+ .btn--danger:hover {
315
+ transform: translateY(-1px);
316
+ box-shadow: 0 6px 16px rgba(185, 28, 28, 0.35);
317
+ opacity: 0.96;
318
+ }
319
+
320
+ .btn--danger:active {
321
+ transform: translateY(0);
322
+ box-shadow: 0 3px 8px rgba(185, 28, 28, 0.3);
323
+ }
324
+
325
+ .btn--danger:disabled {
326
+ background: #9ca3af; /* gray */
327
+ cursor: not-allowed;
328
+ opacity: 0.6;
329
+ box-shadow: none;
330
+ transform: none;
331
+ }
332
+
333
+ .btn--danger:disabled:hover {
334
+ transform: none;
335
+ box-shadow: none;
336
+ opacity: 0.6;
337
+ }
338
+
339
+ #jobsScroll {
340
+ max-height: 75vh; /* modal scroll */
341
+ overflow-y: auto;
342
+ }
343
+
344
+ #jobsGrid {
345
+ display: grid;
346
+ grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
347
+ gap: 12px;
348
+ padding: 4px;
349
+ }
350
+
351
+ @media (min-width: 768px) {
352
+ #jobsGrid {
353
+ grid-template-columns: repeat(auto-fill, minmax(384px, 1fr));
354
+ }
355
+ }
356
+
357
+ .job-card-stats-actions {
358
+ display: flex;
359
+ justify-content: space-between; /* push stats left, actions right */
360
+ align-items: center; /* vertically center items */
361
+ gap: 1rem; /* spacing between elements */
362
+ }
363
+
364
+ .job-cards {
365
+ /* display: none; */
366
+ overflow-y: auto;
367
+ -webkit-overflow-scrolling: touch; /* smooth inertia on iOS */
368
+ }
369
+
370
+ .job-card {
371
+ border-radius: 10px;
372
+ margin: 8px;
373
+ padding: 12px;
374
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
375
+ }
376
+
377
+ .job-card-header {
378
+ display: flex;
379
+ justify-content: space-between;
380
+ align-items: center;
381
+ }
382
+
383
+ .jobs-badge {
384
+ position: absolute;
385
+ top: -4px;
386
+ right: -4px;
387
+ background: red;
388
+ color: white;
389
+ border-radius: 50%;
390
+ min-width: 16px;
391
+ height: 16px;
392
+ font-size: 11px;
393
+ display: flex;
394
+ align-items: center;
395
+ justify-content: center;
396
+ padding: 0 4px;
397
+ font-weight: bold;
398
+ }
399
+
400
+ .chart-name {
401
+ font-size: 0.8rem;
402
+ opacity: 0.7;
403
+ }
404
+
405
+ .job-card-actions {
406
+ display: flex;
407
+ gap: 8px;
408
+ margin-top: 8px;
409
+ }
410
+
411
+ .job-card-actions button {
412
+ flex: 1;
413
+ }
414
+
415
+ #help .modal-content {
416
+ font-family:
417
+ system-ui,
418
+ -apple-system,
419
+ BlinkMacSystemFont,
420
+ 'Segoe UI',
421
+ Roboto,
422
+ Helvetica,
423
+ Arial,
424
+ sans-serif;
425
+ }
426
+
427
+ .modal-image {
428
+ display: block;
429
+ width: auto;
430
+ height: auto;
431
+ object-fit: contain;
118
432
  }