@fmidev/smartmet-alert-client 4.2.7 → 4.7.0-alpha.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 (127) hide show
  1. package/.eslintignore +2 -14
  2. package/.github/workflows/test.yaml +26 -0
  3. package/.nvmrc +1 -0
  4. package/dist/index.dark.html +1 -1
  5. package/dist/index.en.html +1 -1
  6. package/dist/index.fi.html +1 -1
  7. package/dist/index.html +5 -0
  8. package/dist/index.js +105 -135
  9. package/dist/index.mjs +112 -135
  10. package/dist/index.sv.html +1 -1
  11. package/dist/locale-en-DCEKDw5G.js +8 -0
  12. package/dist/locale-fi-DPiOM1rB.js +8 -0
  13. package/dist/locale-sv-B0FlbgEF.js +8 -0
  14. package/dist/vendor-Cfkkvdz7.js +21 -0
  15. package/dist/vue/index.mjs +15245 -0
  16. package/dist/vue/style.css +1 -0
  17. package/dist/xml-parser-BiNO9kc-.js +13 -0
  18. package/package.json +61 -25
  19. package/public/index.dark.html +1 -1
  20. package/public/index.en.html +1 -1
  21. package/public/index.fi.html +1 -1
  22. package/public/index.sv.html +1 -1
  23. package/src/AlertClientVue.vue +170 -0
  24. package/src/App.vue +58 -176
  25. package/src/assets/img/ui/arrow-down.svg +4 -14
  26. package/src/assets/img/ui/arrow-up.svg +4 -14
  27. package/src/assets/img/ui/clear.svg +7 -21
  28. package/src/assets/img/ui/close.svg +4 -15
  29. package/src/assets/img/ui/toggle-selected.svg +12 -0
  30. package/src/assets/img/ui/toggle-unselected.svg +12 -0
  31. package/src/assets/img/warning/cold-weather.svg +3 -6
  32. package/src/assets/img/warning/flood-level-3.svg +4 -7
  33. package/src/assets/img/warning/forest-fire-weather.svg +2 -6
  34. package/src/assets/img/warning/grass-fire-weather.svg +2 -6
  35. package/src/assets/img/warning/hot-weather.svg +3 -6
  36. package/src/assets/img/warning/pedestrian-safety.svg +3 -7
  37. package/src/assets/img/warning/rain.svg +2 -7
  38. package/src/assets/img/warning/sea-icing.svg +2 -6
  39. package/src/assets/img/warning/sea-thunder-storm.svg +2 -5
  40. package/src/assets/img/warning/sea-water-height-high-water.svg +3 -8
  41. package/src/assets/img/warning/sea-water-height-shallow-water.svg +3 -7
  42. package/src/assets/img/warning/sea-wave-height.svg +4 -7
  43. package/src/assets/img/warning/sea-wind-legend.svg +2 -5
  44. package/src/assets/img/warning/sea-wind.svg +2 -5
  45. package/src/assets/img/warning/several.svg +2 -5
  46. package/src/assets/img/warning/thunder-storm.svg +2 -5
  47. package/src/assets/img/warning/traffic-weather.svg +2 -6
  48. package/src/assets/img/warning/uv-note.svg +2 -6
  49. package/src/assets/img/warning/wind.svg +2 -5
  50. package/src/components/AlertClient.vue +42 -20
  51. package/src/components/CollapsiblePanel.vue +284 -0
  52. package/src/components/DayLarge.vue +40 -32
  53. package/src/components/DaySmall.vue +17 -7
  54. package/src/components/Days.vue +77 -52
  55. package/src/components/DescriptionWarning.vue +26 -8
  56. package/src/components/GrayScaleToggle.vue +42 -35
  57. package/src/components/Legend.vue +36 -240
  58. package/src/components/MapLarge.vue +55 -50
  59. package/src/components/MapSmall.vue +48 -29
  60. package/src/components/PopupRow.vue +6 -3
  61. package/src/components/Region.vue +162 -53
  62. package/src/components/RegionWarning.vue +33 -11
  63. package/src/components/Regions.vue +59 -29
  64. package/src/components/Warning.vue +53 -49
  65. package/src/components/Warnings.vue +54 -16
  66. package/src/locales/en.json +21 -4
  67. package/src/locales/fi.json +23 -6
  68. package/src/locales/sv.json +20 -3
  69. package/src/main.js +1 -0
  70. package/src/mixins/alertClientCore.js +210 -0
  71. package/src/mixins/config.js +263 -257
  72. package/src/mixins/utils.js +46 -15
  73. package/src/plugins/index.js +1 -1
  74. package/src/scss/_utilities.scss +193 -0
  75. package/src/scss/backgrounds.scss +2 -0
  76. package/src/scss/colors.scss +5 -3
  77. package/src/scss/constants.scss +3 -2
  78. package/src/scss/themes/dark-gray.scss +3 -3
  79. package/src/scss/themes/dark.scss +1 -1
  80. package/src/scss/themes/light-gray.scss +5 -5
  81. package/src/scss/themes/light.scss +3 -3
  82. package/src/scss/warningImages.scss +9 -5
  83. package/src/vue.js +41 -0
  84. package/svgo.config.js +45 -0
  85. package/tests/README.md +430 -0
  86. package/tests/fixtures/mockWarningData.js +135 -0
  87. package/tests/integration/warning-flow.spec.js +452 -0
  88. package/tests/setup.js +41 -0
  89. package/tests/unit/components/AlertClient.spec.js +734 -0
  90. package/tests/unit/components/DayLarge.spec.js +281 -0
  91. package/tests/unit/components/DaySmall.spec.js +278 -0
  92. package/tests/unit/components/Days.spec.js +565 -0
  93. package/tests/unit/components/DescriptionWarning.spec.js +432 -0
  94. package/tests/unit/components/GrayScaleToggle.spec.js +311 -0
  95. package/tests/unit/components/Legend.spec.js +223 -0
  96. package/tests/unit/components/MapLarge.spec.js +276 -0
  97. package/tests/unit/components/MapSmall.spec.js +226 -0
  98. package/tests/unit/components/PopupRow.spec.js +261 -0
  99. package/tests/unit/components/Region.spec.js +430 -0
  100. package/tests/unit/components/RegionWarning.snapshot.spec.js +73 -0
  101. package/tests/unit/components/RegionWarning.spec.js +408 -0
  102. package/tests/unit/components/Regions.spec.js +335 -0
  103. package/tests/unit/components/Warning.snapshot.spec.js +107 -0
  104. package/tests/unit/components/Warning.spec.js +472 -0
  105. package/tests/unit/components/Warnings.spec.js +329 -0
  106. package/tests/unit/components/__snapshots__/RegionWarning.snapshot.spec.js.snap +21 -0
  107. package/tests/unit/components/__snapshots__/Warning.snapshot.spec.js.snap +199 -0
  108. package/tests/unit/mixins/config.spec.js +269 -0
  109. package/tests/unit/mixins/i18n.spec.js +115 -0
  110. package/tests/unit/mixins/keycodes.spec.js +37 -0
  111. package/tests/unit/mixins/utils.spec.js +624 -0
  112. package/vite.config.js +96 -26
  113. package/vitest.config.js +40 -0
  114. package/dist/index.mjs.map +0 -1
  115. package/dist/index.relative.html +0 -19
  116. package/dist/index.start.html +0 -20
  117. package/playwright.config.ts +0 -18
  118. package/public/index.relative.html +0 -19
  119. package/public/index.start.html +0 -20
  120. package/src/assets/img/ui/toggle-selected-blue.svg +0 -4
  121. package/src/assets/img/ui/toggle-selected-dark.svg +0 -4
  122. package/src/assets/img/ui/toggle-selected-light.svg +0 -4
  123. package/src/assets/img/ui/toggle-unselected-dark.svg +0 -4
  124. package/src/assets/img/ui/toggle-unselected-light.svg +0 -4
  125. package/src/mixins/panzoom.js +0 -900
  126. package/test/snapshot.test.ts +0 -126
  127. package/vitest.config.ts +0 -6
@@ -1,18 +1,26 @@
1
1
  <template>
2
- <div id="fmi-warnings-view" :class="theme">
2
+ <div
3
+ id="fmi-warnings-view"
4
+ :class="theme"
5
+ >
3
6
  <div
4
7
  v-if="input.length > 0"
5
- :class="['row', 'symbol-list-main-row', 'show-text-row']">
8
+ :class="['row', 'symbol-list-main-row', 'show-text-row']"
9
+ >
6
10
  <button
7
11
  tabindex="0"
8
12
  type="button"
9
13
  class="bold-text show-text d-none focus-ring"
10
14
  :class="{ 'd-sm-block': hiddenWarnings }"
11
- @click="showAll">
15
+ @click="showAll"
16
+ >
12
17
  {{ showWarningsText }}
13
18
  </button>
14
19
  </div>
15
- <div v-if="input.length > 0" class="row symbol-list-main-row">
20
+ <div
21
+ v-if="input.length > 0"
22
+ class="row symbol-list-main-row"
23
+ >
16
24
  <hr class="symbol-block-separator" />
17
25
  </div>
18
26
  <div id="fmi-warnings-list">
@@ -23,21 +31,28 @@
23
31
  :hideable="warnings.length > 1"
24
32
  :theme="theme"
25
33
  :language="language"
26
- @warningToggled="onWarningToggled" />
34
+ @warning-toggled="onWarningToggled"
35
+ />
27
36
  </div>
28
37
  <div class="row symbol-list-main-row">
29
38
  <hr
30
39
  class="symbol-block-separator legend-separator"
31
- :class="noWarnings ? 'no-warnings' : ''" />
40
+ :class="noWarnings ? 'no-warnings' : ''"
41
+ />
32
42
  </div>
33
43
  <div class="row symbol-list-main-row">
34
44
  <div class="symbol-list-table">
35
45
  <div class="symbol-list-cell symbol-list-cell-image">
36
46
  <div
37
- class="gray several symbol-list-image-column symbol-list-image warning-image"></div>
47
+ class="gray several symbol-list-image-column symbol-list-image warning-image"
48
+ aria-labelledby="symbol-list-several-warnings-text"
49
+ ></div>
38
50
  </div>
39
51
  <div class="symbol-list-cell symbol-list-cell-text">
40
- <div class="item-text symbol-list-text">
52
+ <div
53
+ id="symbol-list-several-warnings-text"
54
+ class="item-text symbol-list-text"
55
+ >
41
56
  {{ severalWarningsText }}
42
57
  </div>
43
58
  </div>
@@ -47,10 +62,15 @@
47
62
  <div class="symbol-list-table">
48
63
  <div class="symbol-list-cell symbol-list-cell-image">
49
64
  <div
50
- class="level-1 symbol-list-image-column symbol-list-image warning-image"></div>
65
+ class="level-1 symbol-list-image-column symbol-list-image warning-image"
66
+ aria-labelledby="symbol-list-warning-level-1-text"
67
+ ></div>
51
68
  </div>
52
69
  <div class="symbol-list-cell symbol-list-cell-text">
53
- <div class="item-text symbol-list-text">
70
+ <div
71
+ id="symbol-list-warning-level-1-text"
72
+ class="item-text symbol-list-text"
73
+ >
54
74
  {{ warningLevel1Text }}
55
75
  </div>
56
76
  </div>
@@ -60,10 +80,15 @@
60
80
  <div class="symbol-list-table">
61
81
  <div class="symbol-list-cell symbol-list-cell-image">
62
82
  <div
63
- class="level-2 symbol-list-image-column symbol-list-image warning-image"></div>
83
+ class="level-2 symbol-list-image-column symbol-list-image warning-image"
84
+ aria-labelledby="symbol-list-warning-level-2-text"
85
+ ></div>
64
86
  </div>
65
87
  <div class="symbol-list-cell symbol-list-cell-text">
66
- <div class="item-text symbol-list-text">
88
+ <div
89
+ id="symbol-list-warning-level-2-text"
90
+ class="item-text symbol-list-text"
91
+ >
67
92
  {{ warningLevel2Text }}
68
93
  </div>
69
94
  </div>
@@ -73,10 +98,15 @@
73
98
  <div class="symbol-list-table">
74
99
  <div class="symbol-list-cell symbol-list-cell-image">
75
100
  <div
76
- class="level-3 symbol-list-image-column symbol-list-image warning-image"></div>
101
+ class="level-3 symbol-list-image-column symbol-list-image warning-image"
102
+ aria-labelledby="symbol-list-warning-level-3-text"
103
+ ></div>
77
104
  </div>
78
105
  <div class="symbol-list-cell symbol-list-cell-text">
79
- <div class="item-text symbol-list-text">
106
+ <div
107
+ id="symbol-list-warning-level-3-text"
108
+ class="item-text symbol-list-text"
109
+ >
80
110
  {{ warningLevel3Text }}
81
111
  </div>
82
112
  </div>
@@ -86,10 +116,15 @@
86
116
  <div class="symbol-list-table">
87
117
  <div class="symbol-list-cell symbol-list-cell-image">
88
118
  <div
89
- class="level-4 symbol-list-image-column symbol-list-image warning-image"></div>
119
+ class="level-4 symbol-list-image-column symbol-list-image warning-image"
120
+ aria-labelledby="symbol-list-warning-level-4-text"
121
+ ></div>
90
122
  </div>
91
123
  <div class="symbol-list-cell symbol-list-cell-text">
92
- <div class="item-text symbol-list-text">
124
+ <div
125
+ id="symbol-list-warning-level-4-text"
126
+ class="item-text symbol-list-text"
127
+ >
93
128
  {{ warningLevel4Text }}
94
129
  </div>
95
130
  <hr class="bottom-separator" />
@@ -197,6 +232,7 @@ div.show-text-row {
197
232
  }
198
233
 
199
234
  div#fmi-warnings-view > div.row > button.show-text {
235
+ height: 30px;
200
236
  line-height: 30px;
201
237
  float: right;
202
238
  cursor: pointer;
@@ -334,6 +370,8 @@ div#fmi-warnings-view {
334
370
  div.symbol-list-text {
335
371
  display: table-cell;
336
372
  height: $symbol-list-line-height;
373
+ word-break: break-word;
374
+ hyphens: auto;
337
375
  }
338
376
 
339
377
  hr {
@@ -164,9 +164,24 @@
164
164
  "moveMap": "Use the arrow keys to move the map",
165
165
  "mapAriaLabel": "Magnifiable map",
166
166
  "toContent": "Go to text-formatted warnings",
167
- "warningsInAreaStart": "Warnings in",
168
- "warningsInAreaEnd": "areas.",
169
- "toNextContent": "Go to next paragraph.",
167
+ "warningsInAreasStart": "Warnings",
168
+ "fromDirection": "from",
169
+ "in1Areas": "in one area",
170
+ "in2Areas": "in two areas",
171
+ "in3Areas": "in three areas",
172
+ "in4Areas": "in four areas",
173
+ "in5Areas": "in five areas",
174
+ "in6Areas": "in six areas",
175
+ "in7Areas": "in seven areas",
176
+ "in8Areas": "in eight areas",
177
+ "in9Areas": "in nine areas",
178
+ "in10Areas": "in ten areas",
179
+ "in11Areas": "in eleven areas",
180
+ "in12Areas": "in twelve areas",
181
+ "in13Areas": "in thirteen areas",
182
+ "in14Areas": "in fourteen areas",
183
+ "in15Areas": "in fifteen areas",
184
+ "toNextContent": "Go to next section.",
170
185
  "infoButtonAriaLabelShowRegion": "Show current warnings for",
171
186
  "infoButtonAriaLabelCloseRegion": "Close current warnings for",
172
187
  "infoButtonAriaLabelValidWarnings": ".",
@@ -176,5 +191,7 @@
176
191
  "warningsInEffect": "warnings in effect in",
177
192
  "landAreas": "land areas and",
178
193
  "seaAreas": "sea areas",
179
- "grayScale": "Gray scale"
194
+ "grayScale": "Gray scale",
195
+ "toggleOn": "On",
196
+ "toggleOff": "Off"
180
197
  }
@@ -87,7 +87,7 @@
87
87
  "coldWeather": "Pakkasvaroitus",
88
88
  "floodLevel": "Tulvavaroitus",
89
89
  "forestFireWeather": "Maastopalo&shy;varoitus",
90
- "grassFireWeather": "Ruohikkopalovaara",
90
+ "grassFireWeather": "Ruohikko&shy;palovaara",
91
91
  "hotWeather": "Hellevaroitus",
92
92
  "pedestrianSafety": "Jalankulkusää",
93
93
  "rain": "Sadevaroitus",
@@ -95,7 +95,7 @@
95
95
  "seaThunderStorm": "Ukkospuuskia merialueilla",
96
96
  "seaWaterHeightHighWater": "Varoitus korkeasta merivedestä",
97
97
  "seaWaterHeightShallowWater": "Varoitus matalasta merivedestä",
98
- "seaWaveHeight": "Aallokkovaroitus",
98
+ "seaWaveHeight": "Aallokko&shy;varoitus",
99
99
  "seaWind": "Tuulivaroitus merelle",
100
100
  "thunderStorm": "Raju ukonilma",
101
101
  "trafficWeather": "Liikennesää",
@@ -164,9 +164,24 @@
164
164
  "moveMap": "Siirrä karttaa nuolinäppäimillä",
165
165
  "mapAriaLabel": "Zoomattava kartta",
166
166
  "toContent": "Siirry tekstimuotoisiin varoituksiin",
167
- "warningsInAreaStart": "Varoituksia",
168
- "warningsInAreaEnd": "alueella.",
169
- "toNextContent": "Siirry seuraavaan kappaleeseen.",
167
+ "warningsInAreasStart": "Varoituksia",
168
+ "fromDirection": "suunnasta",
169
+ "in1Areas": "yhdellä alueella",
170
+ "in2Areas": "kahdella alueella",
171
+ "in3Areas": "kolmella alueella",
172
+ "in4Areas": "neljällä alueella",
173
+ "in5Areas": "viidellä alueella",
174
+ "in6Areas": "kuudella alueella",
175
+ "in7Areas": "seitsemällä alueella",
176
+ "in8Areas": "kahdeksalla alueella",
177
+ "in9Areas": "yhdeksällä alueella",
178
+ "in10Areas": "kymmenellä alueella",
179
+ "in11Areas": "yhdellätoista alueella",
180
+ "in12Areas": "kahdellatoista alueella",
181
+ "in13Areas": "kolmellatoista alueella",
182
+ "in14Areas": "neljällätoista alueella",
183
+ "in15Areas": "viidellätoista alueella",
184
+ "toNextContent": "Siirry seuraavaan osioon.",
170
185
  "infoButtonAriaLabelShowRegion": "Näytä alueen",
171
186
  "infoButtonAriaLabelCloseRegion": "Sulje alueen",
172
187
  "infoButtonAriaLabelValidWarnings": "voimassaolevat varoitukset",
@@ -176,5 +191,7 @@
176
191
  "warningsInEffect": "Varoituksia voimassa",
177
192
  "landAreas": "maa-alueella ja",
178
193
  "seaAreas": "merialueella",
179
- "grayScale": "Harmaasävyt"
194
+ "grayScale": "Harmaasävyt",
195
+ "toggleOn": "On",
196
+ "toggleOff": "Off"
180
197
  }
@@ -164,8 +164,23 @@
164
164
  "moveMap": "Använd piltangenterna för att flytta kartan",
165
165
  "mapAriaLabel": "Förstorande karta",
166
166
  "toContent": "Gå till varningar i text format",
167
- "warningsInAreaStart": "Varningar i",
168
- "warningsInAreaEnd": "områden.",
167
+ "warningsInAreasStart": "Varningar",
168
+ "fromDirection": "från",
169
+ "in1Areas": "i ett område",
170
+ "in2Areas": "i två områden",
171
+ "in3Areas": "i tre områden",
172
+ "in4Areas": "i fyra områden",
173
+ "in5Areas": "i fem områden",
174
+ "in6Areas": "i sex områden",
175
+ "in7Areas": "i sju områden",
176
+ "in8Areas": "i åtta områden",
177
+ "in9Areas": "i nio områden",
178
+ "in10Areas": "i tio områden",
179
+ "in11Areas": "i elva områden",
180
+ "in12Areas": "i tolv områden",
181
+ "in13Areas": "i tretton områden",
182
+ "in14Areas": "i fjorton områden",
183
+ "in15Areas": "i femton områden",
169
184
  "toNextContent": "Gå till nästa stycke.",
170
185
  "infoButtonAriaLabelShowRegion": "Visa giltiga varningar för",
171
186
  "infoButtonAriaLabelCloseRegion": "Stäng giltiga varningar för",
@@ -176,5 +191,7 @@
176
191
  "warningsInEffect": "varningar i kraft i",
177
192
  "landAreas": "landområden och",
178
193
  "seaAreas": "havsområden",
179
- "grayScale": "Gråskala"
194
+ "grayScale": "Gråskala",
195
+ "toggleOn": "On",
196
+ "toggleOff": "Off"
180
197
  }
package/src/main.js CHANGED
@@ -5,6 +5,7 @@ import {
5
5
  h,
6
6
  } from 'vue'
7
7
  import { createWebComponent } from 'vue-web-component-wrapper'
8
+
8
9
  import app from './App.vue'
9
10
 
10
11
  createWebComponent({
@@ -0,0 +1,210 @@
1
+ /**
2
+ * Core mixin for AlertClient wrapper components.
3
+ * Contains shared logic for both web component (App.vue) and Vue component (AlertClientVue.vue).
4
+ *
5
+ * This mixin provides:
6
+ * - Data state management (loading, warningsData, themeClass, etc.)
7
+ * - Computed properties for API queries
8
+ * - Lifecycle hooks (created, mounted, serverPrefetch)
9
+ * - Methods for fetching warnings and handling events
10
+ *
11
+ * Components using this mixin must provide:
12
+ * - Props with appropriate types (string-only for web components, mixed for Vue)
13
+ * - Normalized computed properties that convert props to correct types
14
+ */
15
+ import fetch from 'cross-fetch'
16
+
17
+ // Helper to normalize string|boolean to boolean
18
+ export const toBool = (val, defaultVal = true) => {
19
+ if (typeof val === 'boolean') return val
20
+ if (typeof val === 'string') return val.toLowerCase() !== 'false'
21
+ return defaultVal
22
+ }
23
+
24
+ // Helper to normalize string|number to number
25
+ export const toNum = (val, defaultVal = 0) => {
26
+ if (typeof val === 'number') return val
27
+ if (typeof val === 'string') return Number(val)
28
+ return defaultVal
29
+ }
30
+
31
+ export default {
32
+ data() {
33
+ return {
34
+ loading: 1,
35
+ updatedAt: null,
36
+ refreshedAt: null,
37
+ themeClass: `${this.theme}-theme`,
38
+ warningsData: null,
39
+ visible: true,
40
+ }
41
+ },
42
+ computed: {
43
+ // API query type names
44
+ weatherUpdatedType() {
45
+ return 'weather_update_time'
46
+ },
47
+ floodUpdatedType() {
48
+ return 'flood_update_time'
49
+ },
50
+ weatherWarningsType() {
51
+ return 'weather_finland_active_all'
52
+ },
53
+ floodWarningsType() {
54
+ return 'flood_finland_active_all'
55
+ },
56
+
57
+ // Query builders
58
+ weatherUpdatedQuery() {
59
+ return this.weatherUpdated || `${this.query}${this.weatherUpdatedType}`
60
+ },
61
+ floodUpdatedQuery() {
62
+ return this.floodUpdated || `${this.query}${this.floodUpdatedType}`
63
+ },
64
+ weatherWarningsQuery() {
65
+ return this.weatherWarnings || `${this.query}${this.weatherWarningsType}`
66
+ },
67
+ floodWarningsQuery() {
68
+ return (
69
+ this.floodWarnings ||
70
+ `${this.query}${this.floodWarningsType}${this.floodFilter}`
71
+ )
72
+ },
73
+ query() {
74
+ return '?service=WFS&version=1.0.0&request=GetFeature&maxFeatures=1000&outputFormat=application%2Fjson&typeName='
75
+ },
76
+ floodSupportedSeverities() {
77
+ return ['moderate', 'severe', 'extreme']
78
+ },
79
+ floodFilter() {
80
+ return `${this.floodSupportedSeverities.reduce(
81
+ (filter, severity, index) =>
82
+ `${filter + (index === 0 ? '' : ',')}%27${severity.toUpperCase()}%27`,
83
+ '&cql_filter=severity%20IN%20('
84
+ )})%20AND%20language=%27${this.capLanguage()}%27`
85
+ },
86
+ capLanguage() {
87
+ return () =>
88
+ ({
89
+ fi: 'fi-FI',
90
+ sv: 'sv-SV',
91
+ en: 'en-US',
92
+ })[this.language]
93
+ },
94
+
95
+ // Current time calculation
96
+ currentTime() {
97
+ if (this.refreshedAt) {
98
+ return this.refreshedAt
99
+ }
100
+ if (this.currentDate) {
101
+ const date =
102
+ this.currentDate instanceof Date
103
+ ? this.currentDate
104
+ : new Date(this.currentDate)
105
+ return date.getTime()
106
+ }
107
+ return Date.now()
108
+ },
109
+ },
110
+ created() {
111
+ if (this.warnings) {
112
+ this.warningsData =
113
+ typeof this.warnings === 'string'
114
+ ? JSON.parse(this.warnings)
115
+ : this.warnings
116
+ }
117
+ },
118
+ mounted() {
119
+ const fontScaleNum = toNum(this.fontScale, 1)
120
+ if (fontScaleNum !== 1) {
121
+ let originalFontSize
122
+ if (
123
+ typeof window !== 'undefined' &&
124
+ typeof document !== 'undefined' &&
125
+ document.documentElement &&
126
+ window.getComputedStyle
127
+ ) {
128
+ const htmlElement = document.documentElement
129
+ const computedStyle = window.getComputedStyle(htmlElement)
130
+ originalFontSize = parseFloat(computedStyle.fontSize)
131
+ }
132
+ if (originalFontSize == null || Number.isNaN(originalFontSize)) {
133
+ originalFontSize = 16 // Fallback
134
+ }
135
+ const scaledFontSize = fontScaleNum * originalFontSize
136
+ const newFontSize = Math.round(scaledFontSize * 100) / 100
137
+ document.documentElement.style.fontSize = `${newFontSize}px`
138
+ }
139
+ },
140
+ serverPrefetch() {
141
+ if (!this.warnings) {
142
+ return this.fetchWarnings()
143
+ }
144
+ },
145
+ methods: {
146
+ onLoaded(loaded) {
147
+ if (loaded !== 0) {
148
+ this.loading = loaded === -1 ? -1 : 0
149
+ }
150
+ },
151
+ onThemeChanged(newTheme) {
152
+ this.themeClass = `${
153
+ newTheme != null && newTheme.length > 0 ? newTheme : this.theme
154
+ }-theme`
155
+ },
156
+ fetchWarnings() {
157
+ if (this.warnings) {
158
+ return
159
+ }
160
+ this.loading = 1
161
+ // debugModeNormalized is provided by the component using this mixin
162
+ if (this.debugModeNormalized) {
163
+ console.log(`Updating warnings at ${new Date()}`)
164
+ }
165
+ const queries = new Map()
166
+ .set(
167
+ `${this.baseUrl}${this.weatherUpdatedQuery}`,
168
+ this.weatherUpdatedType
169
+ )
170
+ .set(`${this.baseUrl}${this.floodUpdatedQuery}`, this.floodUpdatedType)
171
+ .set(
172
+ `${this.baseUrl}${this.weatherWarningsQuery}`,
173
+ this.weatherWarningsType
174
+ )
175
+ .set(
176
+ `${this.baseUrl}${this.floodWarningsQuery}`,
177
+ this.floodWarningsType
178
+ )
179
+ const responseData = {}
180
+ return Promise.allSettled(
181
+ [...queries.keys()].map(async (query) =>
182
+ fetch(query).then((response) =>
183
+ response
184
+ .json()
185
+ .then((json) => {
186
+ const currentTime = Date.now()
187
+ if (this.updatedAt != null) {
188
+ this.refreshedAt = currentTime
189
+ }
190
+ this.updatedAt = currentTime
191
+ responseData[queries.get(query)] = json
192
+ })
193
+ .catch((error) => {
194
+ this.loading = -1
195
+ console.log(error)
196
+ })
197
+ )
198
+ )
199
+ ).then(() => {
200
+ this.warningsData = responseData
201
+ })
202
+ },
203
+ show() {
204
+ this.visible = true
205
+ },
206
+ hide() {
207
+ this.visible = false
208
+ },
209
+ },
210
+ }