@mxtommy/kip 3.9.0-beta.3 → 3.9.0-beta.31

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 (178) hide show
  1. package/.github/copilot-instructions.md +1 -1
  2. package/.github/instructions/angular.instructions.md +46 -0
  3. package/README.md +49 -12
  4. package/package.json +2 -4
  5. package/public/3rdpartylicenses.txt +77 -77
  6. package/public/app-help.component.css.map +7 -0
  7. package/public/app.component.css.map +7 -0
  8. package/public/assets/help-docs/configuration.md +4 -4
  9. package/public/assets/help-docs/dashboards.md +4 -2
  10. package/public/assets/svg/icons.svg +1 -1
  11. package/public/boolean-control-config.component.css.map +7 -0
  12. package/public/boolean-multicontrol-options.component.css.map +7 -0
  13. package/public/chunk-2IRAP774.js +89 -0
  14. package/public/chunk-2IRAP774.js.map +7 -0
  15. package/public/chunk-3VR3EA35.js +1022 -0
  16. package/public/chunk-3VR3EA35.js.map +1 -0
  17. package/public/chunk-5NYGXVMX.js +13727 -0
  18. package/public/chunk-5NYGXVMX.js.map +1 -0
  19. package/public/chunk-63ILPRXC.js +2091 -0
  20. package/public/chunk-63ILPRXC.js.map +1 -0
  21. package/public/chunk-65ZWQBS6.js +3102 -0
  22. package/public/chunk-65ZWQBS6.js.map +1 -0
  23. package/public/chunk-B3LKEWZP.js +4950 -0
  24. package/public/chunk-B3LKEWZP.js.map +1 -0
  25. package/public/chunk-BIBIW64D.js +16773 -0
  26. package/public/chunk-BIBIW64D.js.map +1 -0
  27. package/public/chunk-BM53SC5N.js +77 -0
  28. package/public/chunk-BM53SC5N.js.map +7 -0
  29. package/public/chunk-D7ILNFDM.js +3059 -0
  30. package/public/chunk-D7ILNFDM.js.map +1 -0
  31. package/public/chunk-E24UNLSJ.js +2228 -0
  32. package/public/chunk-E24UNLSJ.js.map +1 -0
  33. package/public/chunk-HR2WMF3Q.js +5237 -0
  34. package/public/chunk-HR2WMF3Q.js.map +1 -0
  35. package/public/chunk-J42S2ELC.js +5927 -0
  36. package/public/chunk-J42S2ELC.js.map +1 -0
  37. package/public/chunk-KC22A6VH.js +17 -0
  38. package/public/chunk-KC22A6VH.js.map +7 -0
  39. package/public/chunk-MCEJWZB2.js +116 -0
  40. package/public/chunk-MCEJWZB2.js.map +1 -0
  41. package/public/chunk-MMVERQLK.js +4752 -0
  42. package/public/chunk-MMVERQLK.js.map +1 -0
  43. package/public/chunk-OFG4OEIS.js +343 -0
  44. package/public/chunk-OFG4OEIS.js.map +7 -0
  45. package/public/chunk-SDOP6T56.js +42377 -0
  46. package/public/chunk-SDOP6T56.js.map +1 -0
  47. package/public/chunk-U2DCSTRY.js +159 -0
  48. package/public/chunk-U2DCSTRY.js.map +7 -0
  49. package/public/chunk-UQYTD5AC.js +2723 -0
  50. package/public/chunk-UQYTD5AC.js.map +1 -0
  51. package/public/chunk-XSABJ5NZ.js +272 -0
  52. package/public/chunk-XSABJ5NZ.js.map +7 -0
  53. package/public/chunk-Y6N6O2IP.js +19852 -0
  54. package/public/chunk-Y6N6O2IP.js.map +1 -0
  55. package/public/chunk-YGJLBLOX.js +2708 -0
  56. package/public/chunk-YGJLBLOX.js.map +1 -0
  57. package/public/chunk-YT33DHC3.js +591 -0
  58. package/public/chunk-YT33DHC3.js.map +7 -0
  59. package/public/chunk-YZXYVP72.js +4934 -0
  60. package/public/chunk-YZXYVP72.js.map +1 -0
  61. package/public/config.component.css.map +7 -0
  62. package/public/dashboard-scroller.component.css.map +7 -0
  63. package/public/dashboard.component.css.map +7 -0
  64. package/public/dashboards-editor.component.css.map +7 -0
  65. package/public/data-inspector-row.component.css.map +7 -0
  66. package/public/data-inspector.component.css.map +7 -0
  67. package/public/dataset-chart-options.component.css.map +7 -0
  68. package/public/datasets.component.css.map +7 -0
  69. package/public/dialog-confirmation.component.css.map +7 -0
  70. package/public/dialog-dashboard-page-editor.component.css.map +7 -0
  71. package/public/dialog-frame.component.css.map +7 -0
  72. package/public/dialog-name.component.css.map +7 -0
  73. package/public/display-chart-options.component.css.map +7 -0
  74. package/public/display.component.css.map +7 -0
  75. package/public/gauge-steel.component.css.map +7 -0
  76. package/public/home.component.css.map +7 -0
  77. package/public/index.html +19 -17
  78. package/public/main.js +36423 -0
  79. package/public/main.js.map +1 -0
  80. package/public/menu-actions.component.css.map +7 -0
  81. package/public/menu-notifications.component.css.map +7 -0
  82. package/public/minichart.component.css.map +7 -0
  83. package/public/modal-user-credential.component.css.map +7 -0
  84. package/public/modal-widget-config.component.css.map +7 -0
  85. package/public/notification-badge.component.css.map +7 -0
  86. package/public/page-header.component.css.map +7 -0
  87. package/public/path-control-config.component.css.map +7 -0
  88. package/public/paths-options.component.css.map +7 -0
  89. package/public/polyfills.js +4422 -0
  90. package/public/polyfills.js.map +1 -0
  91. package/public/select-autopilot.component.css.map +7 -0
  92. package/public/select-icon.component.css.map +7 -0
  93. package/public/settings.component.css.map +7 -0
  94. package/public/signalk.component.css.map +7 -0
  95. package/public/styles.css +1651 -0
  96. package/public/styles.css.map +7 -0
  97. package/public/svg-autopilot.component.css.map +7 -0
  98. package/public/svg-racesteer.component.css.map +7 -0
  99. package/public/svg-simple-linear-gauge.component.css.map +7 -0
  100. package/public/svg-windsteer.component.css.map +7 -0
  101. package/public/tile-large-icon.component.css.map +7 -0
  102. package/public/units.component.css.map +7 -0
  103. package/public/upgrade-config.component.css.map +7 -0
  104. package/public/widget-autopilot.component.css.map +7 -0
  105. package/public/widget-boolean-switch.component.css.map +7 -0
  106. package/public/widget-datetime.component.css.map +7 -0
  107. package/public/widget-freeboardsk.component.css.map +7 -0
  108. package/public/widget-gauge-ng-compass.component.css.map +7 -0
  109. package/public/widget-gauge-ng-linear.component.css.map +7 -0
  110. package/public/widget-gauge-ng-radial.component.css.map +7 -0
  111. package/public/widget-gauge-steel.component.css.map +7 -0
  112. package/public/widget-horizon.component.css.map +7 -0
  113. package/public/widget-host.component.css.map +7 -0
  114. package/public/widget-iframe.component.css.map +7 -0
  115. package/public/widget-label.component.css.map +7 -0
  116. package/public/widget-list-card.component.css.map +7 -0
  117. package/public/widget-numeric.component.css.map +7 -0
  118. package/public/widget-position.component.css.map +7 -0
  119. package/public/widget-race-timer.component.css.map +7 -0
  120. package/public/widget-racer-line.component.css.map +7 -0
  121. package/public/widget-racer-timer.component.css.map +7 -0
  122. package/public/widget-simple-linear.component.css.map +7 -0
  123. package/public/widget-slider.component.css.map +7 -0
  124. package/public/widget-text.component.css.map +7 -0
  125. package/public/widget-title.component.css.map +7 -0
  126. package/public/widget-tutorial.component.css.map +7 -0
  127. package/public/widgets-list.component.css.map +7 -0
  128. package/public/assets/hammer.min.js +0 -7
  129. package/public/chunk-2YVW3TBK.js +0 -2
  130. package/public/chunk-35L7BBBD.js +0 -15
  131. package/public/chunk-3LEMFOCV.js +0 -3
  132. package/public/chunk-4JJLPUET.js +0 -60
  133. package/public/chunk-5I4RHHVN.js +0 -11
  134. package/public/chunk-CBUY7NMR.js +0 -2
  135. package/public/chunk-CQXWGD3T.js +0 -2
  136. package/public/chunk-HCXH72CD.js +0 -5
  137. package/public/chunk-JY3WVS7C.js +0 -2
  138. package/public/chunk-K22CSA3Y.js +0 -1
  139. package/public/chunk-KTDDP73O.js +0 -2
  140. package/public/chunk-NMEZOCU2.js +0 -1
  141. package/public/chunk-NS2FPVWM.js +0 -4
  142. package/public/chunk-PKNLASTF.js +0 -4
  143. package/public/chunk-Q2Y75POI.js +0 -1
  144. package/public/chunk-QJ7KN34C.js +0 -1
  145. package/public/chunk-RRTCHHRC.js +0 -3
  146. package/public/chunk-S3HDPCXO.js +0 -1
  147. package/public/chunk-TA4GACKT.js +0 -4
  148. package/public/chunk-TXPLRBW5.js +0 -2
  149. package/public/chunk-VHFBF47T.js +0 -1
  150. package/public/chunk-VYUMZVH2.js +0 -2
  151. package/public/chunk-YP4L5CLU.js +0 -6
  152. package/public/chunk-YRM4OGRD.js +0 -2
  153. package/public/chunk-ZBCOJLI4.js +0 -6
  154. package/public/main-Z53UATGE.js +0 -64
  155. package/public/polyfills-KH22MU6U.js +0 -2
  156. package/public/styles-RECKN66R.css +0 -1
  157. /package/public/media/{KFOlCnqEu92Fr1MmEU9fABc4AMP6lbBP-ILKS6RVC.woff2 → KFOlCnqEu92Fr1MmEU9fABc4AMP6lbBP.woff2} +0 -0
  158. /package/public/media/{KFOlCnqEu92Fr1MmEU9fBBc4AMP6lQ-MJ3CERJ6.woff2 → KFOlCnqEu92Fr1MmEU9fBBc4AMP6lQ.woff2} +0 -0
  159. /package/public/media/{KFOlCnqEu92Fr1MmEU9fBxc4AMP6lbBP-UW3XWY7P.woff2 → KFOlCnqEu92Fr1MmEU9fBxc4AMP6lbBP.woff2} +0 -0
  160. /package/public/media/{KFOlCnqEu92Fr1MmEU9fCBc4AMP6lbBP-U3JTBV4H.woff2 → KFOlCnqEu92Fr1MmEU9fCBc4AMP6lbBP.woff2} +0 -0
  161. /package/public/media/{KFOlCnqEu92Fr1MmEU9fCRc4AMP6lbBP-36ULTGLY.woff2 → KFOlCnqEu92Fr1MmEU9fCRc4AMP6lbBP.woff2} +0 -0
  162. /package/public/media/{KFOlCnqEu92Fr1MmEU9fChc4AMP6lbBP-5NJLO2HW.woff2 → KFOlCnqEu92Fr1MmEU9fChc4AMP6lbBP.woff2} +0 -0
  163. /package/public/media/{KFOlCnqEu92Fr1MmEU9fCxc4AMP6lbBP-2EL65J2O.woff2 → KFOlCnqEu92Fr1MmEU9fCxc4AMP6lbBP.woff2} +0 -0
  164. /package/public/media/{KFOlCnqEu92Fr1MmSU5fABc4AMP6lbBP-XWLWMQVU.woff2 → KFOlCnqEu92Fr1MmSU5fABc4AMP6lbBP.woff2} +0 -0
  165. /package/public/media/{KFOlCnqEu92Fr1MmSU5fBBc4AMP6lQ-PWGJWDFE.woff2 → KFOlCnqEu92Fr1MmSU5fBBc4AMP6lQ.woff2} +0 -0
  166. /package/public/media/{KFOlCnqEu92Fr1MmSU5fBxc4AMP6lbBP-ITB7NUJC.woff2 → KFOlCnqEu92Fr1MmSU5fBxc4AMP6lbBP.woff2} +0 -0
  167. /package/public/media/{KFOlCnqEu92Fr1MmSU5fCBc4AMP6lbBP-32PLHKPQ.woff2 → KFOlCnqEu92Fr1MmSU5fCBc4AMP6lbBP.woff2} +0 -0
  168. /package/public/media/{KFOlCnqEu92Fr1MmSU5fCRc4AMP6lbBP-QPSNQEDD.woff2 → KFOlCnqEu92Fr1MmSU5fCRc4AMP6lbBP.woff2} +0 -0
  169. /package/public/media/{KFOlCnqEu92Fr1MmSU5fChc4AMP6lbBP-JKBSJZY3.woff2 → KFOlCnqEu92Fr1MmSU5fChc4AMP6lbBP.woff2} +0 -0
  170. /package/public/media/{KFOlCnqEu92Fr1MmSU5fCxc4AMP6lbBP-OG5AHRIX.woff2 → KFOlCnqEu92Fr1MmSU5fCxc4AMP6lbBP.woff2} +0 -0
  171. /package/public/media/{KFOmCnqEu92Fr1Mu4WxKKTU1Kvnz-PPTELUJT.woff2 → KFOmCnqEu92Fr1Mu4WxKKTU1Kvnz.woff2} +0 -0
  172. /package/public/media/{KFOmCnqEu92Fr1Mu4mxKKTU1Kg-SNGEW7FX.woff2 → KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2} +0 -0
  173. /package/public/media/{KFOmCnqEu92Fr1Mu5mxKKTU1Kvnz-DRL4U32S.woff2 → KFOmCnqEu92Fr1Mu5mxKKTU1Kvnz.woff2} +0 -0
  174. /package/public/media/{KFOmCnqEu92Fr1Mu72xKKTU1Kvnz-PRJ7OQMU.woff2 → KFOmCnqEu92Fr1Mu72xKKTU1Kvnz.woff2} +0 -0
  175. /package/public/media/{KFOmCnqEu92Fr1Mu7GxKKTU1Kvnz-HW6RMPJ3.woff2 → KFOmCnqEu92Fr1Mu7GxKKTU1Kvnz.woff2} +0 -0
  176. /package/public/media/{KFOmCnqEu92Fr1Mu7WxKKTU1Kvnz-KZD6JQRT.woff2 → KFOmCnqEu92Fr1Mu7WxKKTU1Kvnz.woff2} +0 -0
  177. /package/public/media/{KFOmCnqEu92Fr1Mu7mxKKTU1Kvnz-Z72STTMG.woff2 → KFOmCnqEu92Fr1Mu7mxKKTU1Kvnz.woff2} +0 -0
  178. /package/public/media/{flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ-CN2J7AYH.woff2 → flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2} +0 -0
@@ -57,7 +57,7 @@ Use this quick-start map to be productive in this repo. Prefer these concrete pa
57
57
 
58
58
  ## Project specifics & gotchas
59
59
  - Always respect serve path /@mxtommy/kip/ (dev/prod). Assets and routing assume this base.
60
- - CommonJS deps are explicitly allowed (howler, hammerjs, js-quantities). Avoid introducing new CJS without adding to allowedCommonJsDependencies.
60
+ - CommonJS deps are explicitly allowed (howler, js-quantities). Avoid introducing new CJS without adding to allowedCommonJsDependencies.
61
61
  - Use standalone components, signals, @if/@for; follow .github/instructions/angular.instructions.md for style.
62
62
  - Widget config UIs live under src/app/widget-config; path controls use custom validators (no Validators.required). Respect isPathConfigurable and pathRequired.
63
63
 
@@ -54,6 +54,10 @@ https://angular.dev/essentials/components
54
54
  https://angular.dev/essentials/signals
55
55
  https://angular.dev/essentials/templates
56
56
  https://angular.dev/essentials/dependency-injection
57
+ https://angular.dev/guide/components/queries
58
+
59
+ viewChild('tileContainer', { static: false }) tileContainer!: ElementRef<HTMLDivElement>;
60
+ viewChildren('tile', { read: ElementRef }) tiles!: QueryList<ElementRef<HTMLElement>>;
57
61
 
58
62
  ## Best practices & Style guide
59
63
  Here are the best practices and the style guide information.
@@ -100,6 +104,15 @@ Here is a link to the most recent Angular style guide https://angular.dev/style-
100
104
  - Use the `providedIn: 'root'` option for singleton services
101
105
  - Use the `inject()` function instead of constructor injection
102
106
 
107
+ ### Dashboards
108
+ - Dashboards are managed via `DashboardService` and support custom names and icons for easy identification
109
+ - Use `DashboardService.add(name, configuration, icon?)` to create dashboards with optional icons
110
+ - Use `DashboardService.update(index, name, icon?)` to modify existing dashboards
111
+ - Use `DashboardService.duplicate(index, newName, newIcon?)` to duplicate dashboards with optional icon override
112
+ - Icons are Material Icons (e.g., 'dashboard', 'navigation') and can be selected via the `select-icon` component
113
+ - The `select-icon` component loads SVG icons from configurable files (default: 'assets/svg/icons.svg'), displays them in a grid, and outputs the selected icon name
114
+ - Integrate icon selection in dialogs by including `<select-icon [iconFile]="'assets/svg/icons.svg'" (selectedIcon)="onIconSelected($event)"></select-icon>`
115
+
103
116
  ---
104
117
 
105
118
  ## Cross-Reference Instructions
@@ -118,3 +131,36 @@ Here is a link to the most recent Angular style guide https://angular.dev/style-
118
131
  - Use signals, standalone components, and modern control flow from this file within the KIP architecture from `COPILOT.md`
119
132
  - For theming and colors, always use the KIP theme system described in `COPILOT.md`, not generic CSS approaches
120
133
  - All services should follow both the Angular DI patterns here AND the KIP service architecture in `COPILOT.md`
134
+
135
+ ## Referencing component children with queries (Angular 17+)
136
+
137
+ Use the modern signal-based query API for referencing elements, components, or directives in your template:
138
+
139
+ - Use `viewChild()` and `viewChildren()` from `@angular/core` (not the old decorators).
140
+ - These return signals or arrays, not QueryList.
141
+ - Example usage:
142
+
143
+ ```typescript
144
+ import { viewChild, viewChildren, ElementRef } from '@angular/core';
145
+
146
+ // In your component class:
147
+ tileContainer = viewChild('tileContainer')();
148
+ tiles = viewChildren('tile', { read: ElementRef });
149
+ ```
150
+
151
+ - In your template, add template reference variables:
152
+
153
+ ```html
154
+ <div #tileContainer>
155
+ @for (item of items; let i = $index) {
156
+ <tile-large-icon #tile ...></tile-large-icon>
157
+ }
158
+ </div>
159
+ ```
160
+
161
+ - Access the element/component directly via the property (e.g., `this.tileContainer`, `this.tiles[0]`).
162
+ - `viewChildren()` returns a readonly array that updates automatically as the view changes.
163
+ - No need for `ngAfterViewInit` to access queries; they are available as soon as the view is rendered.
164
+
165
+ **Summary:**
166
+ Use `viewChild()` and `viewChildren()` for modern, reactive, and type-safe access to elements/components in your template. Avoid the legacy `@ViewChild`/`@ViewChildren` decorators and `QueryList` in new code.
package/README.md CHANGED
@@ -16,20 +16,9 @@ Key features include:
16
16
  - **Multiple User Profiles**: Tailor configurations for different roles, devices, or use cases.
17
17
  - **Cross-Device Compatibility**: Access KIP remotely on any device by navigating to `http://<Signal K Server URL>:<port>/@mxtommy/kip`.
18
18
 
19
- Typical complementary components you may install (many are often bundled with Signal K distributions):
20
-
21
- **Navigation & Charting**
22
- - **Freeboard‑SK** – Multi‑station, web chart plotter dedicated to Signal K: routes, waypoints, charts, alarms, weather layers, and instrument overlays.
23
-
24
- **Visual Flow / Automation**
25
- - **Node‑RED** – Low‑code, flow‑based wiring of devices, APIs, online services, and custom logic (alert escalation, device control automation, data enrichment, protocol bridging).
26
-
27
- **Data Storage & Analytics**
28
- - **InfluxDB / other TSDB** – High‑resolution historical storage of sensor & performance metrics beyond what lightweight widget charts should retain.
29
- - **Grafana** – Rich exploratory / comparative dashboards, ad‑hoc queries, alert rules on stored metrics, correlation across heterogeneous data sources.
30
-
31
19
  KIP is open-source under the MIT license, built by the community and 100% free. Join the community on Discord or contribute to the project on GitHub!
32
20
 
21
+ ## Read the Help introduction How-to
33
22
  ## Read the Help introduction How-to
34
23
  Read the [Introduction](https://github.com/mxtommy/Kip/blob/master/src/assets/help-docs/welcome.md) help file.
35
24
 
@@ -134,6 +123,32 @@ For example, Signal K will notify KIP when a water depth or temperature sensor r
134
123
  ## Multiple User Profiles
135
124
  If you have different roles on board: captain, skipper, tactician, navigator, engineer—or simply different people with different needs, each can tailor KIP as they wish. The use of profiles also allows you to tie specific configuration arrangements to use cases or device form factors.
136
125
 
126
+ ## Complementary Components
127
+ Typical complementary components you may install (many are often bundled with Signal K distributions):
128
+
129
+ **Navigation & Charting**
130
+ - **Freeboard‑SK** – Multi‑station, web chart plotter dedicated to Signal K: routes, waypoints, charts, alarms, weather layers, and instrument overlays.
131
+
132
+ **Visual Flow / Automation**
133
+ - **Node‑RED** – Low‑code, flow‑based wiring of devices, APIs, online services, and custom logic (alert escalation, device control automation, data enrichment, protocol bridging).
134
+
135
+ **Data Storage & Analytics**
136
+ - **InfluxDB / other TSDB** – High‑resolution historical storage of sensor & performance metrics beyond what lightweight widget charts should retain.
137
+ - **Grafana** – Rich exploratory / comparative dashboards, ad‑hoc queries, alert rules on stored metrics, correlation across heterogeneous data sources.
138
+
139
+ ## Complementary Components
140
+ Typical complementary components you may install (many are often bundled with Signal K distributions):
141
+
142
+ **Navigation & Charting**
143
+ - **Freeboard‑SK** – Multi‑station, web chart plotter dedicated to Signal K: routes, waypoints, charts, alarms, weather layers, and instrument overlays.
144
+
145
+ **Visual Flow / Automation**
146
+ - **Node‑RED** – Low‑code, flow‑based wiring of devices, APIs, online services, and custom logic (alert escalation, device control automation, data enrichment, protocol bridging).
147
+
148
+ **Data Storage & Analytics**
149
+ - **InfluxDB / other TSDB** – High‑resolution historical storage of sensor & performance metrics beyond what lightweight widget charts should retain.
150
+ - **Grafana** – Rich exploratory / comparative dashboards, ad‑hoc queries, alert rules on stored metrics, correlation across heterogeneous data sources.
151
+
137
152
  # Connect, Share, and Support
138
153
  KIP has its own Discord Signal K channel for getting in touch. Join us at https://discord.gg/AMDYT2DQga
139
154
 
@@ -166,6 +181,28 @@ Keeping KIP focused preserves responsiveness (lower CPU / memory), reduces UI cl
166
181
 
167
182
  In short: use KIP to see & act on live sailing information; use the complementary tools to store it long‑term, analyze it deeply, automate decisions, or build advanced integrations.
168
183
 
184
+ ## Project Scope
185
+ What KIP IS about:
186
+ - Real‑time presentation of vessel & environment data (navigation, performance, systems) pulled from Signal K.
187
+ - Fast, legible, touchscreen‑friendly dashboards for underway decision making.
188
+ - Configurable widgets (gauges, charts, timers, controls) tuned for sailing operations.
189
+
190
+ What KIP deliberately IS NOT trying to become:
191
+ - A full data lake / long‑term time‑series historian.
192
+ - A general purpose automation / rules / orchestration engine.
193
+ - A universal external web‑app embedding or mash‑up framework.
194
+ - A low‑code integration hub for arbitrarily wiring protocols and services.
195
+
196
+ Those domains already have excellent, specialized open‑source tools. Instead of re‑implementing them, KIP plays nicely alongside them within a Signal K based onboard stack.
197
+
198
+ **Processing & Extensions**
199
+ - **Signal K Plugins** – Domain‑specific enrichment (polars, performance calculations, derived environmental data, routing aids) published directly into the Signal K data model that KIP can then display.
200
+
201
+ **Why this separation matters**
202
+ Keeping KIP focused preserves responsiveness (lower CPU / memory), reduces UI clutter, and accelerates iteration on core sailing UX. Heavy analytics, complex workflow logic, and broad third‑party embedding stay where they are strongest—outside—but still feed KIP through the common Signal K data fabric.
203
+
204
+ In short: use KIP to see & act on live sailing information; use the complementary tools to store it long‑term, analyze it deeply, automate decisions, or build advanced integrations.
205
+
169
206
  **Tools**
170
207
  Linux, Mac, RPi, or Windows dev platform supported
171
208
  1. Install the latest Node version (v16+, v18 recommended)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mxtommy/kip",
3
- "version": "3.9.0-beta.3",
3
+ "version": "3.9.0-beta.31",
4
4
  "description": "An advanced and versatile marine instrumentation package to display Signal K data.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -63,13 +63,13 @@
63
63
  "@godind/ng-canvas-gauges": "^6.2.1",
64
64
  "@robloche/chartjs-plugin-streaming": "^3.1.0",
65
65
  "@types/canvas-gauges": "^2.1.8",
66
- "@types/hammerjs": "^2.0.45",
67
66
  "@types/howler": "^2.2.10",
68
67
  "@types/jasmine": "~3.6.0",
69
68
  "@types/jasminewd2": "^2.0.9",
70
69
  "@types/js-quantities": "^1.6.6",
71
70
  "@types/lodash-es": "^4.17.9",
72
71
  "@types/node": "^24.1.0",
72
+ "@zakj/no-sleep": "^0.13.5",
73
73
  "angular-eslint": "20.1.1",
74
74
  "chart.js": "^4.4.9",
75
75
  "chartjs-adapter-date-fns": "^3.0.0",
@@ -80,7 +80,6 @@
80
80
  "date-fns": "^2.30.0",
81
81
  "eslint": "^9.29.0",
82
82
  "gridstack": "^11.4.0",
83
- "hammerjs": "^2.0.8",
84
83
  "howler": "^2.2.4",
85
84
  "jasmine-core": "~4.0.1",
86
85
  "jasmine-spec-reporter": "~5.0.0",
@@ -100,7 +99,6 @@
100
99
  "rxjs": "^7.8.2",
101
100
  "sass": "^1.49.9",
102
101
  "screenfull": "^6.0.2",
103
- "@zakj/no-sleep": "^0.13.5",
104
102
  "steelseries": "^2.0.9",
105
103
  "ts-node": "^10.9.2",
106
104
  "tslib": "^2.6.2",
@@ -1,28 +1,4 @@
1
1
 
2
- --------------------------------------------------------------------------------
3
- Package: howler
4
- License: "MIT"
5
-
6
- Copyright (c) 2013-2020 James Simpson and GoldFire Studios, Inc.
7
-
8
- Permission is hereby granted, free of charge, to any person obtaining
9
- a copy of this software and associated documentation files (the
10
- "Software"), to deal in the Software without restriction, including
11
- without limitation the rights to use, copy, modify, merge, publish,
12
- distribute, sublicense, and/or sell copies of the Software, and to
13
- permit persons to whom the Software is furnished to do so, subject to
14
- the following conditions:
15
-
16
- The above copyright notice and this permission notice shall be
17
- included in all copies or substantial portions of the Software.
18
-
19
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
2
  --------------------------------------------------------------------------------
27
3
  Package: @godind/canvas-gauges
28
4
  License: "MIT"
@@ -49,6 +25,30 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
49
25
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
50
26
  SOFTWARE.
51
27
 
28
+ --------------------------------------------------------------------------------
29
+ Package: howler
30
+ License: "MIT"
31
+
32
+ Copyright (c) 2013-2020 James Simpson and GoldFire Studios, Inc.
33
+
34
+ Permission is hereby granted, free of charge, to any person obtaining
35
+ a copy of this software and associated documentation files (the
36
+ "Software"), to deal in the Software without restriction, including
37
+ without limitation the rights to use, copy, modify, merge, publish,
38
+ distribute, sublicense, and/or sell copies of the Software, and to
39
+ permit persons to whom the Software is furnished to do so, subject to
40
+ the following conditions:
41
+
42
+ The above copyright notice and this permission notice shall be
43
+ included in all copies or substantial portions of the Software.
44
+
45
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
46
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
47
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
48
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
49
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
50
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
51
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
52
52
  --------------------------------------------------------------------------------
53
53
  Package: gridstack
54
54
  License: "MIT"
@@ -102,12 +102,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
102
102
  THE SOFTWARE.
103
103
 
104
104
  --------------------------------------------------------------------------------
105
- Package: @angular/material
105
+ Package: ngx-resize-observer
106
106
  License: "MIT"
107
107
 
108
- The MIT License
109
-
110
- Copyright (c) 2025 Google LLC.
108
+ Copyright (c) 2017 Tyler Akins
111
109
 
112
110
  Permission is hereby granted, free of charge, to any person obtaining a copy
113
111
  of this software and associated documentation files (the "Software"), to deal
@@ -116,22 +114,24 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
116
114
  copies of the Software, and to permit persons to whom the Software is
117
115
  furnished to do so, subject to the following conditions:
118
116
 
119
- The above copyright notice and this permission notice shall be included in
120
- all copies or substantial portions of the Software.
117
+ The above copyright notice and this permission notice shall be included in all
118
+ copies or substantial portions of the Software.
121
119
 
122
120
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
123
121
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
124
122
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
125
123
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
126
124
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
127
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
128
- THE SOFTWARE.
125
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
126
+ SOFTWARE.
129
127
 
130
128
  --------------------------------------------------------------------------------
131
- Package: ngx-resize-observer
129
+ Package: @angular/material
132
130
  License: "MIT"
133
131
 
134
- Copyright (c) 2017 Tyler Akins
132
+ The MIT License
133
+
134
+ Copyright (c) 2025 Google LLC.
135
135
 
136
136
  Permission is hereby granted, free of charge, to any person obtaining a copy
137
137
  of this software and associated documentation files (the "Software"), to deal
@@ -140,16 +140,16 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
140
140
  copies of the Software, and to permit persons to whom the Software is
141
141
  furnished to do so, subject to the following conditions:
142
142
 
143
- The above copyright notice and this permission notice shall be included in all
144
- copies or substantial portions of the Software.
143
+ The above copyright notice and this permission notice shall be included in
144
+ all copies or substantial portions of the Software.
145
145
 
146
146
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
147
147
  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
148
148
  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
149
149
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
150
150
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
151
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
152
- SOFTWARE.
151
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
152
+ THE SOFTWARE.
153
153
 
154
154
  --------------------------------------------------------------------------------
155
155
  Package: chartjs-plugin-annotation
@@ -243,6 +243,45 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
243
243
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
244
244
  THE SOFTWARE.
245
245
 
246
+ --------------------------------------------------------------------------------
247
+ Package: screenfull
248
+ License: "MIT"
249
+
250
+ MIT License
251
+
252
+ Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
253
+
254
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
255
+
256
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
257
+
258
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
259
+
260
+ --------------------------------------------------------------------------------
261
+ Package: @zakj/no-sleep
262
+ License: "MIT"
263
+
264
+ The MIT License (MIT)
265
+
266
+ Copyright (c) Zak Johnson Copyright (c) 2015-2020 Rich Tibbett
267
+
268
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
269
+ this software and associated documentation files (the "Software"), to deal in
270
+ the Software without restriction, including without limitation the rights to
271
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
272
+ the Software, and to permit persons to whom the Software is furnished to do so,
273
+ subject to the following conditions:
274
+
275
+ The above copyright notice and this permission notice shall be included in all
276
+ copies or substantial portions of the Software.
277
+
278
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
279
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
280
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
281
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
282
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
283
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
284
+
246
285
  --------------------------------------------------------------------------------
247
286
  Package: chart.js
248
287
  License: "MIT"
@@ -413,45 +452,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
413
452
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
414
453
  SOFTWARE.
415
454
 
416
- --------------------------------------------------------------------------------
417
- Package: screenfull
418
- License: "MIT"
419
-
420
- MIT License
421
-
422
- Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
423
-
424
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
425
-
426
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
427
-
428
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
429
-
430
- --------------------------------------------------------------------------------
431
- Package: @zakj/no-sleep
432
- License: "MIT"
433
-
434
- The MIT License (MIT)
435
-
436
- Copyright (c) Zak Johnson Copyright (c) 2015-2020 Rich Tibbett
437
-
438
- Permission is hereby granted, free of charge, to any person obtaining a copy of
439
- this software and associated documentation files (the "Software"), to deal in
440
- the Software without restriction, including without limitation the rights to
441
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
442
- the Software, and to permit persons to whom the Software is furnished to do so,
443
- subject to the following conditions:
444
-
445
- The above copyright notice and this permission notice shall be included in all
446
- copies or substantial portions of the Software.
447
-
448
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
449
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
450
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
451
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
452
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
453
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
454
-
455
455
  --------------------------------------------------------------------------------
456
456
  Package: js-quantities
457
457
  License: "MIT"
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["src/app/core/components/app-help/app-help.component.scss"],
4
+ "sourcesContent": [".fullpage-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n}\n\n.fullpage-header-title {\n margin-block-start: 0px;\n margin-block-end: 0px;\n padding: 18px 24px 13px 24px;\n color: var(--mat-dialog-subhead-color, var(--mat-sys-on-surface, rgba(0, 0, 0, 0.87)));\n font-family: var(--mat-dialog-subhead-font, var(--mat-sys-headline-small-font, inherit));\n line-height: var(--mat-dialog-subhead-line-height, var(--mat-sys-headline-small-line-height, 1.5rem));\n font-size: var(--mat-dialog-subhead-size, var(--mat-sys-headline-small-size, 1rem));\n font-weight: var(--mat-dialog-subhead-weight, var(--mat-sys-headline-small-weight, 400));\n letter-spacing: var(--mat-dialog-subhead-tracking, var(--mat-sys-headline-small-tracking, 0.03125em));\n}\n\n.mat-mdc-dialog-content {\n max-height: max-content;\n}\n\n.markdown-content {\n display: block;\n height: calc(100% - 75px);\n width: 100%;\n overflow-x: scroll;\n padding: 25px;\n}\n\n.dialog-close-icon {\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n gap: 5px;\n padding-right: 15px;\n}\n"],
5
+ "mappings": ";AAAA,CAAA;AACE,WAAA;AACA,mBAAA;AACA,eAAA;;AAGF,CAAA;AACE,sBAAA;AACA,oBAAA;AACA,WAAA,KAAA,KAAA,KAAA;AACA,SAAA,IAAA,0BAAA,EAAA,IAAA,oBAAA,EAAA,KAAA,CAAA,EAAA,CAAA,EAAA,CAAA,EAAA;AACA,eAAA,IAAA,yBAAA,EAAA,IAAA,6BAAA,EAAA;AACA,eAAA,IAAA,gCAAA,EAAA,IAAA,oCAAA,EAAA;AACA,aAAA,IAAA,yBAAA,EAAA,IAAA,6BAAA,EAAA;AACA,eAAA,IAAA,2BAAA,EAAA,IAAA,+BAAA,EAAA;AACA,kBAAA,IAAA,6BAAA,EAAA,IAAA,iCAAA,EAAA;;AAGF,CAAA;AACE,cAAA;;AAGF,CAAA;AACE,WAAA;AACA,UAAA,KAAA,KAAA,EAAA;AACA,SAAA;AACA,cAAA;AACA,WAAA;;AAGF,CAAA;AACE,WAAA;AACA,kBAAA;AACA,aAAA;AACA,OAAA;AACA,iBAAA;;",
6
+ "names": []
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["src/app/app.component.scss"],
4
+ "sourcesContent": [".sidenav-container {\n height: 100%;\n width: 100%;\n}\n\nmat-sidenav-content {\n overflow-y: hidden;\n overflow-x: hidden;\n}\n\nmat-sidenav.sidenav-notifications {\n width: 230px;\n z-index: 1200; // ensure sidenav sits above the notification overlay panel\n}\n\nmat-sidenav.sidenav-actions {\n width: 135px;\n z-index: 1200; // ensure actions sidenav stacks above overlay\n overflow-x: hidden; // Ensure action sidenav content doesn't overflow horizontally\n}\n"],
5
+ "mappings": ";AAAA,CAAA;AACE,UAAA;AACA,SAAA;;AAGF;AACC,cAAA;AACA,cAAA;;AAGD,WAAA,CAAA;AACE,SAAA;AACA,WAAA;;AAGF,WAAA,CAAA;AACE,SAAA;AACA,WAAA;AACA,cAAA;;",
6
+ "names": []
7
+ }
@@ -1,9 +1,9 @@
1
1
  # Configuration Management
2
2
 
3
- KIP provides a "Login to Server" option that determines where your configuration is stored. It is **strongly recommended** to enable server login in the **Settings** under the **Connectivity** tab. This ensures your configurations are stored remotely on the Signal K server. See the "Creating a Signal K user" section below for details.
3
+ KIP provides a "Login to Server" option that determines where your configuration is stored. It is **strongly recommended** to enable server login in the **Settings** under the **Connectivity** tab. This ensures your configurations are stored remotely on the Signal K server and allows automatic loading of configuration from any device. See the "Creating a Signal K user" section below for information on how to create a user.
4
4
 
5
- - **Login to Server Enabled** (recommended setting): Configuration is stored remotely on the Signal K server.
6
- - **Login to Server Disabled** (default value): Configuration is saved locally in the browser's private storage.
5
+ - **Login to Server Enabled** (recommended setting): Configuration is stored remotely on the Signal K server. This mode allow automatic loading of your configuration from any device (also known as configuration sharing).
6
+ - **Login to Server Disabled** (default value): Configuration is saved on your computer/device, in the browser's private storage. In this mode, the configuration is per browser.
7
7
 
8
8
  You can manage your configurations using the **Configurations** page, accessible from the right menu. Depending on your login mode, different management options are available.
9
9
 
@@ -54,4 +54,4 @@ Use advanced operations with caution. All changes affect your active configurati
54
54
 
55
55
  KIP separates configuration into two parts:
56
56
  1. **Server Connection**: This configuration is always stored locally in your browser and is never shared. It is used in the **Connectivity** tab of the **Settings** page.
57
- 2. **Application Settings**: This includes the configuration you can back up, delete, and restore on the **Configurations** page.
57
+ 2. **Application Settings**: This includes the configuration settings you can back up, delete, and restore with the **Configurations** page. It contains all dashboards, widgets and other configuration settings.
@@ -2,12 +2,14 @@
2
2
  You can organize your dashboards from the Dashboards page. To edit a dashboard layout, first visualize the dashboard and unlock it.
3
3
 
4
4
  ## Dashboard Pages
5
- On the Dashboards page, you can add, reorder, delete, rename, and duplicate dashboards. The dashboard name is briefly visible when you cycle through dashboards. Available actions include:
5
+ On the Dashboards page, you can add, reorder, delete, rename, and duplicate dashboards. Each dashboard can have a custom name and icon for easy identification. The dashboard name is briefly visible when you cycle through dashboards. Available actions include:
6
6
  - **Long press** a dashboard to delete or duplicate it.
7
- - **Double tap** a dashboard to rename it.
7
+ - **Double tap** a dashboard to rename it and select an icon.
8
8
  - **Touch and drag** to reorder dashboards.
9
9
  - Use the **(+)** button to add a new dashboard.
10
10
 
11
+ When renaming or creating a dashboard, you can choose from a variety of icons to visually represent the dashboard's purpose (e.g., navigation, engine monitoring, weather). Icons are displayed in the dashboard menu for quick recognition.
12
+
11
13
  ## Editing Layout
12
14
  To edit a dashboard's widgets and arrangement, you need to unlock its layout. View the desired dashboard, access the **Actions menu** on the right-hand side, and tap the bottom **unlock button**. The widgets will become surrounded by dashed borders, indicating you are in edit mode. Actions you can perform while editing a layout include:
13
15
  - **Long press** an empty area of the dashboard to add a widget (you may need to free up space first).
@@ -1,5 +1,5 @@
1
1
  <svg>
2
- <defsid="defs1">
2
+ <defs id="defs1">
3
3
  <svg id="dashboard" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
4
4
  <path fill="currentColor" d="M5 5h4v6H5zm10 8h4v6h-4zM5 17h4v2H5zM15 5h4v2h-4z" opacity="0.3" />
5
5
  <path fill="currentColor" d="M3 13h8V3H3zm2-8h4v6H5zm8 16h8V11h-8zm2-8h4v6h-4zM13 3v6h8V3zm6 4h-4V5h4zM3 21h8v-6H3zm2-4h4v2H5z" />
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["src/app/widget-config/boolean-control-config/boolean-control-config.component.scss"],
4
+ "sourcesContent": [".ctrl-grid {\n display: grid;\n width: auto;\n height: auto;\n margin: 0px;\n grid-template-columns: [col-start] calc(100% - 90px) [col1-end] 80px [col2-end];\n grid-template-areas: \"controls actions\";\n row-gap: 0px;\n column-gap: 10px;\n justify-items: center;\n align-items: center;\n justify-content: center;\n align-content: center;\n margin-bottom: 10px;\n padding-top: 20px;\n}\n\n.controls {\n grid-area: controls;\n width: 100%;\n}\n\n.actions {\n grid-area: actions;\n}\n\n.btn-grid {\n display: grid;\n width: 80px;\n height: 80px;\n margin: 0px;\n grid-template-columns: [col-start] 50% [col1-end] 50% [col2-end];\n grid-template-rows: [row-start] 50% [row1-end] 50% [row2-end];\n grid-template-areas:\n \"up delete\"\n \"down delete\";\n row-gap: 0px;\n column-gap: 0px;\n justify-items: center;\n align-items: center;\n justify-content: center;\n align-content: center;\n}\n\n.up {\n grid-area: up;\n}\n\n.down {\n grid-area: down;\n}\n\n.delete {\n grid-area: delete;\n}\n\n.flex-label {\n flex-grow: 2;\n flex-shrink: 2;\n}\n\n.flex-settings {\n flex-grow: 1;\n flex-shrink: 1;\n}\n\n.settings {\n min-width: 100px;\n}\n\n.flex-actions {\n flex-grow: 0;\n flex-shrink: 0;\n}\n\n.flex-full-width {\n width: 100%;\n}\n"],
5
+ "mappings": ";AAAA,CAAA;AACE,WAAA;AACA,SAAA;AACA,UAAA;AACA,UAAA;AACA,yBAAA,CAAA,WAAA,KAAA,KAAA,EAAA,MAAA,CAAA,UAAA,KAAA,CAAA;AACA,uBAAA;AACA,WAAA;AACA,cAAA;AACA,iBAAA;AACA,eAAA;AACA,mBAAA;AACA,iBAAA;AACA,iBAAA;AACA,eAAA;;AAGF,CAAA;AACE,aAAA;AACA,SAAA;;AAGF,CAAA;AACE,aAAA;;AAGF,CAAA;AACE,WAAA;AACA,SAAA;AACA,UAAA;AACA,UAAA;AACA,yBAAA,CAAA,WAAA,IAAA,CAAA,UAAA,IAAA,CAAA;AACA,sBAAA,CAAA,WAAA,IAAA,CAAA,UAAA,IAAA,CAAA;AACA,uBACE,YAAA;AAEF,WAAA;AACA,cAAA;AACA,iBAAA;AACA,eAAA;AACA,mBAAA;AACA,iBAAA;;AAGF,CAAA;AACE,aAAA;;AAGF,CAAA;AACE,aAAA;;AAGF,CAAA;AACE,aAAA;;AAGF,CAAA;AACE,aAAA;AACA,eAAA;;AAGF,CAAA;AACE,aAAA;AACA,eAAA;;AAGF,CAAA;AACE,aAAA;;AAGF,CAAA;AACE,aAAA;AACA,eAAA;;AAGF,CAAA;AACC,SAAA;;",
6
+ "names": []
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["src/app/widget-config/boolean-multicontrol-options/boolean-multicontrol-options.component.css"],
4
+ "sourcesContent": [":host {\n display: block;\n width: 100%;\n height: 100%;\n padding-top: 15px;\n padding-bottom: 15px;\n}\n\n.add-btn {\n margin-left: calc(50% - 20px);\n}\n\n"],
5
+ "mappings": ";AAAA;AACE,WAAS;AACT,SAAO;AACP,UAAQ;AACR,eAAa;AACb,kBAAgB;AAClB;AAEA,CAAC;AACC,eAAa,KAAK,IAAI,EAAE;AAC1B;",
6
+ "names": []
7
+ }
@@ -0,0 +1,89 @@
1
+ import {
2
+ ModalUserCredentialComponent
3
+ } from "./chunk-U2DCSTRY.js";
4
+ import {
5
+ AppService
6
+ } from "./chunk-OFG4OEIS.js";
7
+ import "./chunk-MCEJWZB2.js";
8
+ import {
9
+ AppSettingsService,
10
+ AuthenticationService,
11
+ MatDialog
12
+ } from "./chunk-BIBIW64D.js";
13
+ import {
14
+ Component,
15
+ inject,
16
+ setClassMetadata,
17
+ ɵsetClassDebugInfo,
18
+ ɵɵdefineComponent
19
+ } from "./chunk-SDOP6T56.js";
20
+
21
+ // src/app/widgets/widget-login/widget-login.component.ts
22
+ var WidgetLoginComponent = class _WidgetLoginComponent {
23
+ dialog = inject(MatDialog);
24
+ auth = inject(AuthenticationService);
25
+ appService = inject(AppService);
26
+ appSettingsService = inject(AppSettingsService);
27
+ connectionConfig = null;
28
+ ngOnInit() {
29
+ this.connectionConfig = this.appSettingsService.getConnectionConfig();
30
+ this.openUserCredentialModal("Sign in failed: Incorrect user/password. Enter valide credentials or access the Confifuration/Settings menu, validate the server URL or/and disable the user Sign in option");
31
+ }
32
+ openUserCredentialModal(errorMsg) {
33
+ const dialogRef = this.dialog.open(ModalUserCredentialComponent, {
34
+ disableClose: true,
35
+ data: {
36
+ user: this.connectionConfig.loginName,
37
+ password: this.connectionConfig.loginPassword,
38
+ error: errorMsg
39
+ }
40
+ });
41
+ dialogRef.afterClosed().subscribe((data) => {
42
+ if (data === void 0 || !data) {
43
+ return;
44
+ } else {
45
+ this.connectionConfig.loginName = data.user;
46
+ this.connectionConfig.loginPassword = data.password;
47
+ this.appSettingsService.setConnectionConfig(this.connectionConfig);
48
+ this.serverLogin();
49
+ }
50
+ });
51
+ }
52
+ serverLogin(newUrl) {
53
+ this.auth.login({ usr: this.connectionConfig.loginName, pwd: this.connectionConfig.loginPassword, newUrl }).then(() => {
54
+ this.appSettingsService.reloadApp();
55
+ }).catch((error) => {
56
+ if (error.status == 401) {
57
+ this.openUserCredentialModal("Sign in failed: Invalide user/password. Enter valide credentials");
58
+ console.log("[Setting-SignalK Component] Sign in failed: " + error.error.message);
59
+ } else if (error.status == 404) {
60
+ this.appService.sendSnackbarNotification("Sign in failed: Login API not found at URL. See connection detail status in Configuration/Settings", 5e3, false);
61
+ console.log("[Setting-SignalK Component] Sign in failed: " + error.error.message);
62
+ } else if (error.status == 0) {
63
+ this.appService.sendSnackbarNotification("Sign in failed: Cannot reach server at Signal K URL. See connection detail status in Configuration/Settings", 5e3, false);
64
+ console.log("[Setting-SignalK Component] Sign in failed: Cannot reach server at Signal K URL:" + error.message);
65
+ } else {
66
+ this.appService.sendSnackbarNotification("Unknown authentication failure: " + JSON.stringify(error), 5e3, false);
67
+ console.log("[Setting-SignalK Component] Unknown login error response: " + JSON.stringify(error));
68
+ }
69
+ });
70
+ }
71
+ static \u0275fac = function WidgetLoginComponent_Factory(__ngFactoryType__) {
72
+ return new (__ngFactoryType__ || _WidgetLoginComponent)();
73
+ };
74
+ static \u0275cmp = /* @__PURE__ */ \u0275\u0275defineComponent({ type: _WidgetLoginComponent, selectors: [["app-widget-login"]], decls: 0, vars: 0, template: function WidgetLoginComponent_Template(rf, ctx) {
75
+ }, encapsulation: 2 });
76
+ };
77
+ (() => {
78
+ (typeof ngDevMode === "undefined" || ngDevMode) && setClassMetadata(WidgetLoginComponent, [{
79
+ type: Component,
80
+ args: [{ selector: "app-widget-login", standalone: true, template: "" }]
81
+ }], null, null);
82
+ })();
83
+ (() => {
84
+ (typeof ngDevMode === "undefined" || ngDevMode) && \u0275setClassDebugInfo(WidgetLoginComponent, { className: "WidgetLoginComponent", filePath: "src/app/widgets/widget-login/widget-login.component.ts", lineNumber: 17 });
85
+ })();
86
+ export {
87
+ WidgetLoginComponent
88
+ };
89
+ //# sourceMappingURL=chunk-2IRAP774.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["src/app/widgets/widget-login/widget-login.component.ts"],
4
+ "sourcesContent": ["import { Component, OnInit, inject } from '@angular/core';\nimport { MatDialog } from '@angular/material/dialog';\nimport { AuthenticationService } from \"../../core/services/authentication.service\";\nimport { AppSettingsService } from '../../core/services/app-settings.service';\nimport { ModalUserCredentialComponent } from '../../core/components/modal-user-credential/modal-user-credential.component';\nimport { IConnectionConfig } from \"../../core/interfaces/app-settings.interfaces\";\nimport { HttpErrorResponse } from '@angular/common/http';\nimport { AppService } from '../../core/services/app-service';\n\n\n@Component({\n selector: 'app-widget-login',\n templateUrl: './widget-login.component.html',\n styleUrls: ['./widget-login.component.css'],\n standalone: true\n})\nexport class WidgetLoginComponent implements OnInit {\n dialog = inject(MatDialog);\n private auth = inject(AuthenticationService);\n private appService = inject(AppService);\n private appSettingsService = inject(AppSettingsService);\n\n public connectionConfig: IConnectionConfig = null;\n\n ngOnInit(): void {\n this.connectionConfig = this.appSettingsService.getConnectionConfig();\n this.openUserCredentialModal(\"Sign in failed: Incorrect user/password. Enter valide credentials or access the Confifuration/Settings menu, validate the server URL or/and disable the user Sign in option\");\n }\n\n public openUserCredentialModal(errorMsg: string) {\n const dialogRef = this.dialog.open(ModalUserCredentialComponent, {\n disableClose: true,\n data: {\n user: this.connectionConfig.loginName,\n password: this.connectionConfig.loginPassword,\n error: errorMsg\n }\n });\n\n dialogRef.afterClosed().subscribe(data => {\n if (data === undefined || !data) {\n return; //clicked Cancel or navigated await from page using url bar.\n } else {\n this.connectionConfig.loginName = data.user;\n this.connectionConfig.loginPassword = data.password;\n this.appSettingsService.setConnectionConfig(this.connectionConfig);\n this.serverLogin();\n }\n });\n }\n\n private serverLogin(newUrl?: string) {\n this.auth.login({ usr: this.connectionConfig.loginName, pwd: this.connectionConfig.loginPassword, newUrl })\n .then(() => {\n this.appSettingsService.reloadApp();\n })\n .catch((error: HttpErrorResponse) => {\n if (error.status == 401) {\n this.openUserCredentialModal(\"Sign in failed: Invalide user/password. Enter valide credentials\");\n console.log(\"[Setting-SignalK Component] Sign in failed: \" + error.error.message);\n } else if (error.status == 404) {\n this.appService.sendSnackbarNotification(\"Sign in failed: Login API not found at URL. See connection detail status in Configuration/Settings\", 5000, false);\n console.log(\"[Setting-SignalK Component] Sign in failed: \" + error.error.message);\n } else if (error.status == 0) {\n this.appService.sendSnackbarNotification(\"Sign in failed: Cannot reach server at Signal K URL. See connection detail status in Configuration/Settings\", 5000, false);\n console.log(\"[Setting-SignalK Component] Sign in failed: Cannot reach server at Signal K URL:\" + error.message);\n } else {\n this.appService.sendSnackbarNotification(\"Unknown authentication failure: \" + JSON.stringify(error), 5000, false);\n console.log(\"[Setting-SignalK Component] Unknown login error response: \" + JSON.stringify(error));\n }\n });\n }\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;AAgBM,IAAO,uBAAP,MAAO,sBAAoB;EAC/B,SAAS,OAAO,SAAS;EACjB,OAAO,OAAO,qBAAqB;EACnC,aAAa,OAAO,UAAU;EAC9B,qBAAqB,OAAO,kBAAkB;EAE/C,mBAAsC;EAE7C,WAAQ;AACN,SAAK,mBAAmB,KAAK,mBAAmB,oBAAmB;AACnE,SAAK,wBAAwB,6KAA6K;EAC5M;EAEO,wBAAwB,UAAgB;AAC7C,UAAM,YAAY,KAAK,OAAO,KAAK,8BAA8B;MAC/D,cAAc;MACd,MAAM;QACJ,MAAM,KAAK,iBAAiB;QAC5B,UAAU,KAAK,iBAAiB;QAChC,OAAO;;KAEV;AAED,cAAU,YAAW,EAAG,UAAU,UAAO;AACvC,UAAI,SAAS,UAAa,CAAC,MAAM;AAC/B;MACF,OAAO;AACL,aAAK,iBAAiB,YAAY,KAAK;AACvC,aAAK,iBAAiB,gBAAgB,KAAK;AAC3C,aAAK,mBAAmB,oBAAoB,KAAK,gBAAgB;AACjE,aAAK,YAAW;MAClB;IACF,CAAC;EACH;EAEQ,YAAY,QAAe;AACjC,SAAK,KAAK,MAAM,EAAE,KAAK,KAAK,iBAAiB,WAAW,KAAK,KAAK,iBAAiB,eAAe,OAAM,CAAE,EACzG,KAAK,MAAK;AACT,WAAK,mBAAmB,UAAS;IACnC,CAAC,EACA,MAAM,CAAC,UAA4B;AAClC,UAAI,MAAM,UAAU,KAAK;AACvB,aAAK,wBAAwB,kEAAkE;AAC/F,gBAAQ,IAAI,iDAAiD,MAAM,MAAM,OAAO;MAClF,WAAW,MAAM,UAAU,KAAK;AAC9B,aAAK,WAAW,yBAAyB,sGAAsG,KAAM,KAAK;AAC1J,gBAAQ,IAAI,iDAAiD,MAAM,MAAM,OAAO;MAClF,WAAW,MAAM,UAAU,GAAG;AAC5B,aAAK,WAAW,yBAAyB,+GAA+G,KAAM,KAAK;AACnK,gBAAQ,IAAI,qFAAqF,MAAM,OAAO;MAChH,OAAO;AACL,aAAK,WAAW,yBAAyB,qCAAqC,KAAK,UAAU,KAAK,GAAG,KAAM,KAAK;AAChH,gBAAQ,IAAI,+DAA+D,KAAK,UAAU,KAAK,CAAC;MAClG;IACF,CAAC;EACH;;qCAvDW,uBAAoB;EAAA;yEAApB,uBAAoB,WAAA,CAAA,CAAA,kBAAA,CAAA,GAAA,OAAA,GAAA,MAAA,GAAA,UAAA,SAAA,8BAAA,IAAA,KAAA;EAAA,GAAA,eAAA,EAAA,CAAA;;;sEAApB,sBAAoB,CAAA;UANhC;uBACa,oBAAkB,YAGhB,MAAI,UAAA,GAAA,CAAA;;;;6EAEP,sBAAoB,EAAA,WAAA,wBAAA,UAAA,0DAAA,YAAA,GAAA,CAAA;AAAA,GAAA;",
6
+ "names": []
7
+ }