@raclettejs/core 0.1.8 → 0.1.10

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 (24) hide show
  1. package/CHANGELOG.md +34 -8
  2. package/package.json +1 -1
  3. package/services/frontend/src/core/lib/data/dataApi.ts +9 -7
  4. package/services/frontend/src/core/lib/data/fetchDataHandler.ts +38 -20
  5. package/services/frontend/src/core/lib/data/queryApi.ts +7 -4
  6. package/services/frontend/src/core/lib/data/writeDataHandler.ts +12 -1
  7. package/services/frontend/src/core/lib/easteregg.ts +7 -1
  8. package/services/frontend/src/core/lib/eggs/asteroids/index.ts +2 -2
  9. package/services/frontend/src/core/lib/projectDataHelper.ts +1 -2
  10. package/services/frontend/src/core/setup/plugin-system/api/plugin-data.ts +2 -2
  11. package/services/frontend/src/orchestrator/assets/styles/main.scss +2 -0
  12. package/services/frontend/src/orchestrator/assets/styles/vuetifyStyles.scss +22 -0
  13. package/services/frontend/src/orchestrator/components/menu/UserNotifications.vue +4 -2
  14. package/services/frontend/src/orchestrator/components/welcomeScreen/AdminWelcomeScreen.vue +1 -0
  15. package/services/frontend/src/orchestrator/components/welcomeScreen/UserWelcomeScreen.vue +1 -0
  16. package/services/frontend/src/orchestrator/composables/useVueQueryObservableHelper.ts +5 -2
  17. package/services/frontend/src/orchestrator/composables/useVueWriteOperationHelper.ts +5 -2
  18. package/services/frontend/src/orchestrator/i18n/de-DE.json +4 -0
  19. package/services/frontend/src/orchestrator/i18n/en-EU.json +4 -0
  20. package/services/frontend/src/orchestrator/i18n/sk.json +4 -0
  21. package/services/frontend/src/orchestrator/i18n/tl-TL.json +5 -1
  22. package/services/frontend/src/orchestrator/setup/i18n.ts +2 -1
  23. package/services/frontend/src/orchestrator/setup/loginApp.ts +1 -0
  24. package/services/frontend/src/orchestrator/types/PluginApi.ts +4 -1
package/CHANGELOG.md CHANGED
@@ -7,13 +7,39 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
- ## [0.1.8] - 11.09.2025
10
+ ## [0.1.10] - 12.09.2025 <a href="https://gitlab.com/raclettejs/core/-/compare/v0.1.9...v0.1.10" target="_blank" rel="noopener"><b>Overview of all changes</b></a>
11
+
12
+ ### Changed
13
+
14
+ - added "Overview of all changes" link to all previous versions
15
+
16
+ ### Refactor
17
+
18
+ - changed response structure of queries execute. Will now always return {result:any, response:any} -> see docs for further information
19
+ - https://docs.raclettejs.com/docs/examples/recipes/creatingDataInTheBackend
20
+ - https://docs.raclettejs.com/docs/examples/recipes/readingDataFromTheBackend
21
+ - queries now always return dataArr
22
+
23
+ ### Fix
24
+
25
+ - fixed missing "raclette" string in welcome page
26
+ - fixed missing "new" i18n key in user Notifier
27
+ - fixed min-width in userNotifier
28
+ - Add `<button>` cursor styles from vuetify's reset css (which is disabled), to fix missing `cursor: pointer` css rule.
29
+
30
+ ## [0.1.9] - 11.09.2025 <a href="https://gitlab.com/raclettejs/core/-/compare/v0.1.8...v0.1.9" target="_blank" rel="noopener"><b>Overview of all changes</b></a>
31
+
32
+ ### Feat
33
+
34
+ - language preference is now properly respected in all components
35
+
36
+ ## [0.1.8] - 11.09.2025 <a href="https://gitlab.com/raclettejs/core/-/compare/v0.1.7...v0.1.8" target="_blank" rel="noopener"><b>Overview of all changes</b></a>
11
37
 
12
38
  ### Changed
13
39
 
14
40
  - language and theme toggle in user menu now always store preference in localstorage, not just in dev mode
15
41
 
16
- ## [0.1.7] - 11.09.2025
42
+ ## [0.1.7] - 11.09.2025 <a href="https://gitlab.com/raclettejs/core/-/compare/v0.1.6...v0.1.7" target="_blank" rel="noopener"><b>Overview of all changes</b></a>
17
43
 
18
44
  ### Style
19
45
 
@@ -23,25 +49,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
23
49
 
24
50
  - fixed query handler id suffixing
25
51
 
26
- ## [0.1.6] - 11.09.2025
52
+ ## [0.1.6] - 11.09.2025 <a href="https://gitlab.com/raclettejs/core/-/compare/v0.1.5...v0.1.6" target="_blank" rel="noopener"><b>Overview of all changes</b></a>
27
53
 
28
54
  - version updates
29
55
 
30
- ## [0.1.5] - 11.09.2025
56
+ ## [0.1.5] - 11.09.2025 <a href="https://gitlab.com/raclettejs/core/-/compare/v0.1.4...v0.1.5" target="_blank" rel="noopener"><b>Overview of all changes</b></a>
31
57
 
32
58
  ### Fixed
33
59
 
34
60
  - "refresh all queries" functionallity in user menu now works as expected
35
61
  - issue was introduced during query api update in v0.1.3
36
62
 
37
- ## [0.1.4] - 10.09.2025
63
+ ## [0.1.4] - 10.09.2025 <a href="https://gitlab.com/raclettejs/core/-/compare/v0.1.3...v0.1.4" target="_blank" rel="noopener"><b>Overview of all changes</b></a>
38
64
 
39
65
  ### Fixed
40
66
 
41
67
  - aliases "@app", "@raclettejs/core/frontend" & "@raclettejs/core/backend" are now resolved properly in the IDE
42
68
  - fixed unspecific locale fallback
43
69
 
44
- ## [0.1.3] - 10.09.2025
70
+ ## [0.1.3] - 10.09.2025 <a href="https://gitlab.com/raclettejs/core/-/compare/v0.1.2...v0.1.3" target="_blank" rel="noopener"><b>Overview of all changes</b></a>
45
71
 
46
72
  ### Fixed
47
73
 
@@ -51,14 +77,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
51
77
  - renamed all Types and core internal imports from Client* to Frontend*
52
78
  - this was forgotten in a former refactoring step and resolves build issues encountered after going Live
53
79
 
54
- ## [0.1.2] - 04.09.2025
80
+ ## [0.1.2] - 04.09.2025 <a href="https://gitlab.com/raclettejs/core/-/compare/v0.1.1...v0.1.2" target="_blank" rel="noopener"><b>Overview of all changes</b></a>
55
81
 
56
82
  ### Changed
57
83
 
58
84
  - cache TTL can now be configured via raclette.config.js -> if none is set will default to -1 which implies indefinite ttl
59
85
  - -> make sure to set ttl explicitly during cache.cache() if important for businesslogic!
60
86
 
61
- ## [0.1.1] - 03.09.2025
87
+ ## [0.1.1] - 03.09.2025 <a href="https://gitlab.com/raclettejs/core/-/compare/v0.1.0...v0.1.1" target="_blank" rel="noopener"><b>Overview of all changes</b></a>
62
88
 
63
89
  ### Added
64
90
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@raclettejs/core",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "racletteJS core package",
5
5
  "repository": "https://gitlab.com/raclettejs/core",
6
6
  "author": "Pacifico Digital Explorations GmbH <info@raclettejs.com>",
@@ -19,21 +19,21 @@ const $writeDataApi = (
19
19
  const isLoadingSubject$ = new BehaviorSubject<boolean>(false)
20
20
  const dataSubject$ = new BehaviorSubject([])
21
21
  const errorSubject$ = new BehaviorSubject(null)
22
- const resultSubject$ = new BehaviorSubject({})
22
+ const responseSubject$ = new BehaviorSubject({})
23
23
  const writeApi = {
24
24
  isLoading$: isLoadingSubject$.asObservable(),
25
25
  data$: dataSubject$.asObservable(),
26
26
  error$: errorSubject$.asObservable(),
27
- result$: resultSubject$.asObservable(),
27
+ response$: responseSubject$.asObservable(),
28
28
  execute: async (executeParams = {}) => {
29
29
  const _executeParams = clone(executeParams)
30
30
  errorSubject$.next(null)
31
- resultSubject$.next({})
32
- isLoadingSubject$.next(true)
31
+ responseSubject$.next({})
33
32
  const queryParams = mergeDeepRight(_params, _executeParams)
34
33
  if (options.responseType === "stream") {
35
34
  return writeData(actionId, operationDefinition, queryParams, options)
36
35
  }
36
+ isLoadingSubject$.next(true)
37
37
  const resultData = await writeData(
38
38
  actionId,
39
39
  operationDefinition,
@@ -44,14 +44,16 @@ const $writeDataApi = (
44
44
  errorSubject$.next(errorObj)
45
45
  isLoadingSubject$.next(false)
46
46
  })
47
- resultSubject$.next(resultData)
47
+ responseSubject$.next(resultData?.response)
48
48
 
49
49
  // Update both boolean and observable on success
50
50
  isLoadingSubject$.next(false)
51
51
 
52
52
  // Update data if resultData is available
53
- if (resultData) {
54
- const dataArray = Array.isArray(resultData) ? resultData : [resultData]
53
+ if (resultData?.result) {
54
+ const dataArray = Array.isArray(resultData.result)
55
+ ? resultData.result
56
+ : [resultData.result]
55
57
  dataSubject$.next(dataArray)
56
58
  }
57
59
 
@@ -183,7 +183,10 @@ const finishRemoteQuery = (actionIdentifier, result, params, options) => {
183
183
  actionId: actionId,
184
184
  },
185
185
  })
186
- return result.data
186
+ return {
187
+ result: resultObj,
188
+ response: result.data,
189
+ }
187
190
  }
188
191
 
189
192
  return itemDispatcher(actionIdentifier, resultObj, true)
@@ -225,7 +228,10 @@ const handleRemoteRequest = async (
225
228
  ? await $api.axios.get(target, config)
226
229
  : await $api.axios.post(target, params, config)
227
230
 
228
- return finishRemoteQuery(actionIdentifier, response, params, options)
231
+ return {
232
+ response,
233
+ result: finishRemoteQuery(actionIdentifier, response, params, options),
234
+ }
229
235
  } catch (e) {
230
236
  if (e.name === "AbortError" || e.name === "CanceledError") {
231
237
  log.api(`${method} request was cancelled for actionId:`, actionIdentifier)
@@ -239,12 +245,15 @@ const handleRemoteRequest = async (
239
245
  e,
240
246
  })
241
247
 
242
- return finishRemoteQuery(
243
- actionIdentifier,
244
- { data: [], error: e?.response?.data || e },
245
- params,
246
- options,
247
- )
248
+ return {
249
+ response: e,
250
+ result: finishRemoteQuery(
251
+ actionIdentifier,
252
+ { data: [], error: e?.response?.data || e },
253
+ params,
254
+ options,
255
+ ),
256
+ }
248
257
  }
249
258
  }
250
259
 
@@ -359,22 +368,28 @@ const routeHandlers = {
359
368
  "search/query": async (actionIdentifier, target, params, options, signal) => {
360
369
  if (params.search?.q === "@showall") {
361
370
  const dataState = $store.getState("data")
362
- return itemDispatcher(
371
+ return {
372
+ response: "dataStore",
373
+ result: itemDispatcher(
374
+ actionIdentifier,
375
+ {
376
+ result: Object.values(dataState),
377
+ },
378
+ true,
379
+ ),
380
+ }
381
+ }
382
+
383
+ return {
384
+ response: "dataStore",
385
+ result: itemDispatcher(
363
386
  actionIdentifier,
364
387
  {
365
- result: Object.values(dataState),
388
+ result: [],
366
389
  },
367
390
  true,
368
- )
391
+ ),
369
392
  }
370
-
371
- return itemDispatcher(
372
- actionIdentifier,
373
- {
374
- result: [],
375
- },
376
- true,
377
- )
378
393
  },
379
394
  }
380
395
 
@@ -438,7 +453,10 @@ const getData = async (actionId, target, params, options) => {
438
453
  actionIdentifier,
439
454
  )
440
455
  if (cacheResult !== null) {
441
- return cacheResult
456
+ return {
457
+ response: "cached_" + cachedQuery.hash,
458
+ result: cacheResult,
459
+ }
442
460
  }
443
461
  }
444
462
  // Execute route
@@ -19,7 +19,7 @@ export const $queryApi = (
19
19
  return queryApis[actionId]
20
20
  }
21
21
  const errorSubject$ = new BehaviorSubject(null)
22
- const resultSubject$ = new BehaviorSubject({})
22
+ const responseSubject$ = new BehaviorSubject({})
23
23
  const cleanedParams = fixQueryParamTypes(params)
24
24
  // check if we have a query fullfilling the needs of the one requested
25
25
  // here. If not we will update the one with this actionId
@@ -35,7 +35,7 @@ export const $queryApi = (
35
35
  })
36
36
  const queryApi = {
37
37
  error$: errorSubject$.asObservable(),
38
- result$: resultSubject$.asObservable(),
38
+ response$: responseSubject$.asObservable(),
39
39
  query$: $store.select((state) => state.queries[actionId]),
40
40
  uuids$: $store.select((state) => state.queries[actionId].uuids),
41
41
  remove: () => {
@@ -48,7 +48,7 @@ export const $queryApi = (
48
48
  execute: async (executeParams = {}) => {
49
49
  const _executeParams = clone(executeParams)
50
50
  errorSubject$.next(null)
51
- resultSubject$.next({})
51
+ responseSubject$.next({})
52
52
  const queryParams = mergeDeepRight(cleanedParams, _executeParams)
53
53
  $store.dispatch({
54
54
  type: "queries/update",
@@ -68,10 +68,13 @@ export const $queryApi = (
68
68
  const errorObj = e
69
69
  errorSubject$.next(errorObj)
70
70
  })
71
- resultSubject$.next(resultData)
71
+ responseSubject$.next(resultData?.response)
72
72
  if (options.cb && typeof options.cb === "function") {
73
73
  options.cb(resultData)
74
74
  }
75
+ if (resultData.result) {
76
+ resultData.result = await resultData.result
77
+ }
75
78
  return resultData
76
79
  },
77
80
  onDeleted: (callback) => {
@@ -117,13 +117,24 @@ const writeData = async (actionId, operationDefinition, item, options) => {
117
117
  cleanItem,
118
118
  config,
119
119
  )
120
+ .then((res) => {
121
+ return {
122
+ response: res,
123
+ }
124
+ })
125
+ .catch((e) => reportError(e))
120
126
  } else {
121
127
  return await $api.axios[operationDefinition.method](
122
128
  validTarget,
123
129
  cleanItem,
124
130
  config,
125
131
  )
126
- .then((res) => handleServerItem(res.data, notify, true))
132
+ .then((res) => {
133
+ return {
134
+ response: res,
135
+ result: handleServerItem(res.data, notify, true),
136
+ }
137
+ })
127
138
  .catch((e) => reportError(e))
128
139
  }
129
140
  }
@@ -1,6 +1,7 @@
1
1
  import snow from "./eggs/snow"
2
2
  import asteroids from "./eggs/asteroids/index"
3
3
  import smoke from "./eggs/smoke"
4
+ import { $eventbus } from "@racletteCore/main"
4
5
 
5
6
  const eggs = {
6
7
  asteroids: asteroids,
@@ -12,7 +13,12 @@ const eggMe = (egg) => {
12
13
  return
13
14
  }
14
15
 
15
- return eggs[egg]()
16
+ return eggs[egg](() => {
17
+ $eventbus.emit("ui_addToSnackBar", {
18
+ i18n: "core.eggcontrols." + egg,
19
+ color: "info",
20
+ })
21
+ })
16
22
  }
17
23
 
18
24
  const debounceHelper = (count, time = 800) => {
@@ -519,7 +519,7 @@ function isTouchOnly() {
519
519
  return isTouchOnly
520
520
  }
521
521
  // Export function to create and start the game with SSR safety
522
- export default (): ModernAsteroids | null => {
522
+ export default (notifyUser): ModernAsteroids | null => {
523
523
  if (
524
524
  typeof window === "undefined" ||
525
525
  typeof document === "undefined" ||
@@ -528,6 +528,6 @@ export default (): ModernAsteroids | null => {
528
528
  console.warn("Racleroids game can only run in browser environment")
529
529
  return null
530
530
  }
531
-
531
+ notifyUser()
532
532
  return new ModernAsteroids()
533
533
  }
@@ -9,7 +9,6 @@ const setupSpace = async (
9
9
  interactionLinks: InteractionLink[],
10
10
  projectConfig: ProjectConfiguration,
11
11
  ) => {
12
- const userLanguage = useLocalStorage<string>("user-language", null)
13
12
  const userTheme = useLocalStorage<string>("user-theme", null)
14
13
  let sessionTheme = userTheme.value
15
14
  // set compositions
@@ -48,7 +47,7 @@ const setupSpace = async (
48
47
  }
49
48
  await $store.dispatch({
50
49
  type: "ui/update",
51
- payload: { theme: sessionTheme},
50
+ payload: { theme: sessionTheme },
52
51
  })
53
52
  }
54
53
 
@@ -82,7 +82,7 @@ export const handlePluginOperations =
82
82
  params = {},
83
83
  options = {},
84
84
  }: CustomStoreActionsPayload = {}) => {
85
- if (id) handlerId = id
85
+ if (id?.length) handlerId = id
86
86
  const instanceActionId =
87
87
  getInstanceActionId(
88
88
  prefixedPluginName,
@@ -118,7 +118,7 @@ export const handlePluginOperations =
118
118
  params = {},
119
119
  options = {},
120
120
  }: CustomStoreActionsPayload = {}) => {
121
- if (id) handlerId = id
121
+ if (id?.length) handlerId = id
122
122
  const instanceActionId =
123
123
  getInstanceActionId(
124
124
  prefixedPluginName,
@@ -5,9 +5,11 @@
5
5
  .ASTEROIDSYEAH {
6
6
  @apply tw:overflow-hidden;
7
7
  }
8
+
8
9
  .klingon * {
9
10
  font-family: "Klingon";
10
11
  }
12
+
11
13
  .raclette {
12
14
  font-family: "Quicksand" !important;
13
15
  font-weight: 700;
@@ -3,3 +3,25 @@
3
3
  $reset: false
4
4
  );
5
5
  @use "@mdi/font/css/materialdesignicons.css";
6
+
7
+ // The styles below are picked from vuetify's reset css (which is disabled)
8
+
9
+ /* Apply cursor pointer to button elements */
10
+ button,
11
+ [type="button"],
12
+ [type="reset"],
13
+ [type="submit"],
14
+ [role="button"] {
15
+ cursor: pointer;
16
+ color: inherit;
17
+ }
18
+
19
+ /* Specify the pointer cursor of trigger elements */
20
+ [aria-controls] {
21
+ cursor: pointer;
22
+ }
23
+
24
+ /* Specify the unstyled cursor of disabled, not-editable, or otherwise inoperable elements */
25
+ [aria-disabled="true"] {
26
+ cursor: default;
27
+ }
@@ -32,10 +32,12 @@
32
32
  </v-btn>
33
33
  </template>
34
34
 
35
- <v-card left class="tw:w-[450px]">
35
+ <v-card left>
36
36
  <v-expansion-panels v-model="panel">
37
37
  <v-expansion-panel>
38
- <v-expansion-panel-title>Neu</v-expansion-panel-title>
38
+ <v-expansion-panel-title>{{
39
+ $t("core.new")
40
+ }}</v-expansion-panel-title>
39
41
  <v-expansion-panel-text>
40
42
  <v-list density="compact">
41
43
  <v-list-item
@@ -5,6 +5,7 @@
5
5
  <v-card-title class="tw:text-3xl tw:font-bold tw:pb-2">
6
6
  🧀
7
7
  {{ $t("core.welcomeScreen.title") }}
8
+ <span class="raclette">raclette</span>
8
9
  </v-card-title>
9
10
  <v-card-subtitle class="tw:text-lg tw:opacity-90">
10
11
  {{ $t("core.welcomeScreen.subtitle") }}
@@ -5,6 +5,7 @@
5
5
  <v-card-title class="tw:text-3xl tw:font-bold tw:pb-2">
6
6
  🧀
7
7
  {{ $t("core.welcomeScreen.title") }}
8
+ <span class="raclette">raclette</span>
8
9
  </v-card-title>
9
10
  <v-card-subtitle class="tw:text-lg tw:opacity-90">
10
11
  {{ $t("core.welcomeScreen.subtitleUser") }}
@@ -41,7 +41,7 @@ export const useVueQueryObservableHelper = (
41
41
  subscriber$[instanceActionId] = coreQuery
42
42
  const queryRef = useObservable<QueryApiQuery>(coreQuery.query$)
43
43
  const errorObservable = useObservable(coreQuery.error$)
44
- const resultRef = useObservable<QueryApiQuery>(coreQuery.result$)
44
+ const responseRef = useObservable<QueryApiQuery>(coreQuery.response$)
45
45
  if (options.useStore !== false) {
46
46
  watch(queryRef, (value, oldValue) => {
47
47
  const newUUIDS = value?.uuids || []
@@ -73,7 +73,10 @@ export const useVueQueryObservableHelper = (
73
73
  return queryRef.value?.loading
74
74
  }),
75
75
  data,
76
- response: resultRef,
76
+ dataArr: computed(() => {
77
+ return data.value ? Object.values(data.value) : []
78
+ }),
79
+ response: responseRef,
77
80
  execute: coreQuery.execute,
78
81
  uuids: coreQuery.uuids$,
79
82
  error: computed(() => {
@@ -45,7 +45,7 @@ export const useVueWriteOperationHelper = (
45
45
  const isLoadingObservable = useObservable(writeOperation.isLoading$)
46
46
  const dataObservable = useObservable(writeOperation.data$)
47
47
  const errorObservable = useObservable(writeOperation.error$)
48
- const resultRef = useObservable(writeOperation.result$)
48
+ const responseRef = useObservable(writeOperation.response$)
49
49
  if (options.useStore !== false) {
50
50
  watch(dataObservable, (value, oldValue) => {
51
51
  const uuids = []
@@ -80,7 +80,10 @@ export const useVueWriteOperationHelper = (
80
80
  return isLoadingObservable.value
81
81
  }),
82
82
  data,
83
- response: resultRef,
83
+ dataArr: computed(() => {
84
+ return data.value ? Object.values(data.value) : []
85
+ }),
86
+ response: responseRef,
84
87
  execute: writeOperation.execute,
85
88
  error: computed(() => {
86
89
  return errorObservable.value
@@ -85,6 +85,7 @@
85
85
  "return_to_home": "Zur Startseite",
86
86
  "noConnectionToServer": "Es kann keine Verbindung zum Server hergestellt werden"
87
87
  },
88
+ "new": "Neu",
88
89
  "lastSocketUpdateReceivedAt": "Letzte Servernachricht erhalten am",
89
90
  "logout": "Abmelden",
90
91
  "refreshAllQueries": "Alle Suchen aktualisieren",
@@ -105,6 +106,9 @@
105
106
  "reloadPageHint": "Bitte laden Sie diese Seite in ihren Browser neu, um die Änderungen zu aktivieren.",
106
107
  "color": "Farbe",
107
108
  "versionUpdate": "Eine neue Version ist verfügbar. Laden Sie die Seite neu, um alle neuen Features zu nutzen.",
109
+ "eggcontrols": {
110
+ "asteroids": "Nutzen sie die Pfeiltasten zum Navigieren und die Leertaste zum Schießen. Viel Spaß!"
111
+ },
108
112
  "languages": {
109
113
  "tl-TL": "Klingonisch",
110
114
  "de-DE": "Deutsch (Deutschland)",
@@ -85,6 +85,7 @@
85
85
  "return_to_home": "Go to home page",
86
86
  "noConnectionToServer": "Cannot connect to the server"
87
87
  },
88
+ "new": "New",
88
89
  "lastSocketUpdateReceivedAt": "Last server message received at",
89
90
  "logout": "Log out",
90
91
  "refreshAllQueries": "Refresh all queries",
@@ -105,6 +106,9 @@
105
106
  "reloadPageHint": "Please reload this page in your browser to activate the changes.",
106
107
  "color": "Color",
107
108
  "versionUpdate": "A new version is available. Reload the page to use all new features.",
109
+ "eggcontrols": {
110
+ "asteroids": "Use the arrow keys to navigate and the spacebar to shoot. Have fun!"
111
+ },
108
112
  "languages": {
109
113
  "tl-TL": "Klingon",
110
114
  "de-DE": "German (Germany)",
@@ -85,6 +85,7 @@
85
85
  "return_to_home": "Prejsť na domovskú stránku",
86
86
  "noConnectionToServer": "Nepodarilo sa pripojiť k serveru"
87
87
  },
88
+ "new": "nové",
88
89
  "lastSocketUpdateReceivedAt": "Posledná správa zo servera prijatá o",
89
90
  "logout": "Odhlásiť sa",
90
91
  "refreshAllQueries": "Obnoviť všetky dopyty",
@@ -105,6 +106,9 @@
105
106
  "reloadPageHint": "Obnovte túto stránku vo svojom prehliadači, aby sa zmeny prejavili.",
106
107
  "color": "Farba",
107
108
  "versionUpdate": "Je dostupná nová verzia. Obnovte stránku pre použitie všetkých nových funkcií.",
109
+ "eggcontrols": {
110
+ "asteroids": "Použite šípky na navigáciu a medzerník na streľbu. Bavte sa!"
111
+ },
108
112
  "languages": {
109
113
  "tl-TL": "Klingončina",
110
114
  "de-DE": "Nemčina (Nemecko)",
@@ -85,6 +85,7 @@
85
85
  "return_to_home": "vav paqDaq yIja’",
86
86
  "noConnectionToServer": "tlhej QunDaq ‘ej tobogh log tapbe’"
87
87
  },
88
+ "new": "qchu'",
88
89
  "lastSocketUpdateReceivedAt": "Qun QaptaH neghtaH rep",
89
90
  "logout": "Qel",
90
91
  "refreshAllQueries": "bochmey Qap yItlhutlh",
@@ -104,6 +105,9 @@
104
105
  "batch$CountSynced": "{count} ghItlhmey serverDaq QaptaH law’",
105
106
  "reloadPageHint": "paqvam loDnI'pu' Daq laD chel — ngeD choH!",
106
107
  "color": "ngem",
107
- "versionUpdate": "veS wov ’oH. paq reload chel pagh SoH Hoch tlhab!"
108
+ "versionUpdate": "veS wov ’oH. paq reload chel pagh SoH Hoch tlhab!",
109
+ "eggcontrols": {
110
+ "asteroids": "QuQ navmey Dalo'nIS, 'ej bachmeH patlh yIlo'. yIchep!"
111
+ }
108
112
  }
109
113
  }
@@ -410,7 +410,8 @@ class I18nOrchestrator {
410
410
  private async determineInitialLocale(
411
411
  availableLocales: string[],
412
412
  ): Promise<string> {
413
- const browserLocale = navigator.language
413
+ const userLanguage = localStorage.getItem("user-language")
414
+ const browserLocale = userLanguage || navigator.language
414
415
  let initialLocale = this.fallbackLocale
415
416
 
416
417
  // Use the same fallback logic as message loading
@@ -1,3 +1,4 @@
1
+ // TODO: check if this file can be deleted
1
2
  export const createLoginApp = async (
2
3
  el: string,
3
4
  loginMethod: Function,
@@ -16,7 +16,10 @@ export type PluginMethod = (payload?: CustomStoreActionsPayload) => {
16
16
  response: Ref<unknown>
17
17
  error: Ref<unknown>
18
18
  data: ComputedRef<unknown>
19
- execute: (params?: Record<string, any>) => void
19
+ dataArr: Array<ComputedRef<unknown>>
20
+ execute: (
21
+ params?: Record<string, any>,
22
+ ) => Promise<{ response: any; result: any }>
20
23
  // query and uuids only provided from queryObservableHelper
21
24
  query?: ComputedRef<Query>
22
25
  uuids?: Array<string>