@geogirafe/lib-geoportal 1.2.0-dev.2775426316 → 1.2.0-dev.2776642665
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/i18n/de.json +1 -0
- package/assets/i18n/en.json +1 -0
- package/assets/i18n/fr.json +1 -0
- package/assets/i18n/it.json +1 -0
- package/components/userpreferences/component.d.ts +1 -4
- package/components/userpreferences/component.js +30 -15
- package/package.json +1 -1
- package/templates/public/about.json +1 -1
- package/tools/configuration/girafeconfig.d.ts +1 -0
- package/tools/configuration/girafeconfig.js +1 -0
- package/tools/state/statemanager.d.ts +9 -0
- package/tools/state/statemanager.js +23 -1
package/assets/i18n/de.json
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"Basemap visible": "Hintergrundkartenauswahl sichtbar",
|
|
33
33
|
"Basemaps": "Hintergrundkarten",
|
|
34
34
|
"Batch creation mode": "Batch-Modus",
|
|
35
|
+
"Browser or application default": "Browser- oder Applikationseinstellung",
|
|
35
36
|
"Build": "Build",
|
|
36
37
|
"by selecting a theme": "wählen Sie ein Thema",
|
|
37
38
|
"Cancel": "Abbrechen",
|
package/assets/i18n/en.json
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"Basemap visible": "Basemap selection visible",
|
|
33
33
|
"Basemaps": "Basemaps",
|
|
34
34
|
"Batch creation mode": "Batch creation mode",
|
|
35
|
+
"Browser or application default": "Browser or application default",
|
|
35
36
|
"Build": "Build",
|
|
36
37
|
"by selecting a theme": "by selecting a theme",
|
|
37
38
|
"Cancel": "Cancel",
|
package/assets/i18n/fr.json
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"Basemap visible": "Sélection de la carte de base visible",
|
|
33
33
|
"Basemaps": "Fonds de carte",
|
|
34
34
|
"Batch creation mode": "mode batch",
|
|
35
|
+
"Browser or application default": "Paramètres du navigateur ou de l'application",
|
|
35
36
|
"Build": "Build",
|
|
36
37
|
"by selecting a theme": "en sélectionnant un thème",
|
|
37
38
|
"Cancel": "Annuler",
|
package/assets/i18n/it.json
CHANGED
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"Basemap visible": "Selezione mappa di base visibile",
|
|
33
33
|
"Basemaps": "Mappe di base",
|
|
34
34
|
"Batch creation mode": "Modalità di creazione batch",
|
|
35
|
+
"Browser or application default": "Impostazioni del browser o dell'applicazione",
|
|
35
36
|
"Build": "Build",
|
|
36
37
|
"by selecting a theme": "selezionando un tema",
|
|
37
38
|
"Cancel": "Annulla",
|
|
@@ -30,6 +30,7 @@ export default class UserPreferencesComponent extends GirafeHTMLElement implemen
|
|
|
30
30
|
For preferences that have options to choose from, readout all possible select options to show in the dropdowns
|
|
31
31
|
*/
|
|
32
32
|
private initPreferenceOptions;
|
|
33
|
+
private refreshLanguageOptions;
|
|
33
34
|
/**
|
|
34
35
|
* Collect all possible options for the default theme preference. This has to be repeatable, since the user
|
|
35
36
|
* can create new custom themes at any time.
|
|
@@ -71,10 +72,6 @@ export default class UserPreferencesComponent extends GirafeHTMLElement implemen
|
|
|
71
72
|
Save the user preference as a config override in user data storage
|
|
72
73
|
*/
|
|
73
74
|
private updatePreferenceInStorage;
|
|
74
|
-
/**
|
|
75
|
-
Delete user preference in the local browser storage
|
|
76
|
-
*/
|
|
77
|
-
private deletePreferenceInStorage;
|
|
78
75
|
/**
|
|
79
76
|
* Reset user preferences back to defaults. This will delete the configOverrides object in storage and set the
|
|
80
77
|
* current state back to the defaults from config.json
|
|
@@ -37,7 +37,15 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
37
37
|
initPreferences() {
|
|
38
38
|
// Define all settings that the user can change
|
|
39
39
|
this.preferences = {
|
|
40
|
-
language: new UserPreference('languages.
|
|
40
|
+
language: new UserPreference('languages.userLanguage', 'language', 'system', 'select', (lang) => {
|
|
41
|
+
if (lang === null) {
|
|
42
|
+
// No user preference, reset language to default
|
|
43
|
+
return this.context.stateManager.decideLanguage();
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
return lang;
|
|
47
|
+
}
|
|
48
|
+
}),
|
|
41
49
|
logLevel: new UserPreference('general.logLevel', null, 'system', 'select'),
|
|
42
50
|
theme: new UserPreference('themes.defaultTheme', 'theme', 'map', 'select', (themeName) => {
|
|
43
51
|
const themeId = Object.keys(this.state.themes._allThemes).find((themeKey) => this.state.themes._allThemes[Number(themeKey)].name === themeName);
|
|
@@ -72,8 +80,8 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
72
80
|
delete this.preferences[key];
|
|
73
81
|
}
|
|
74
82
|
}
|
|
75
|
-
this.subscribe('
|
|
76
|
-
if (
|
|
83
|
+
this.subscribe('application.isReady', (_, isReady) => {
|
|
84
|
+
if (isReady) {
|
|
77
85
|
this.initPreferenceOptions();
|
|
78
86
|
this.initCurrentPreferenceValues();
|
|
79
87
|
this.initDarkModeDefaults();
|
|
@@ -127,11 +135,7 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
127
135
|
For preferences that have options to choose from, readout all possible select options to show in the dropdowns
|
|
128
136
|
*/
|
|
129
137
|
initPreferenceOptions() {
|
|
130
|
-
|
|
131
|
-
this.preferences.language.options = Object.keys(this.context.configManager.Config.languages.translations).map((key) => {
|
|
132
|
-
return { label: key, value: key };
|
|
133
|
-
});
|
|
134
|
-
}
|
|
138
|
+
this.refreshLanguageOptions();
|
|
135
139
|
if (this.preferences.logLevel) {
|
|
136
140
|
this.preferences.logLevel.options = [
|
|
137
141
|
{ label: 'debug', value: 'debug' },
|
|
@@ -172,6 +176,19 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
172
176
|
];
|
|
173
177
|
}
|
|
174
178
|
}
|
|
179
|
+
refreshLanguageOptions() {
|
|
180
|
+
if (this.preferences.language) {
|
|
181
|
+
this.preferences.language.options = Object.keys(this.context.configManager.Config.languages.translations).map((key) => {
|
|
182
|
+
return { label: key, value: key };
|
|
183
|
+
});
|
|
184
|
+
const defaultOptionLabel = this.context.i18nManager.getTranslation('Browser or application default');
|
|
185
|
+
const fallbackLanguage = this.context.i18nManager.getTranslation(this.context.stateManager.fallbackLanguage() ?? '?');
|
|
186
|
+
this.preferences.language.options = [
|
|
187
|
+
{ label: `${defaultOptionLabel} (${fallbackLanguage})`, value: null },
|
|
188
|
+
...this.preferences.language.options
|
|
189
|
+
];
|
|
190
|
+
}
|
|
191
|
+
}
|
|
175
192
|
/**
|
|
176
193
|
* Collect all possible options for the default theme preference. This has to be repeatable, since the user
|
|
177
194
|
* can create new custom themes at any time.
|
|
@@ -238,6 +255,10 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
238
255
|
this.refreshThemeOptions();
|
|
239
256
|
this.refreshRender();
|
|
240
257
|
}
|
|
258
|
+
else if (preferenceKey === 'language') {
|
|
259
|
+
this.refreshLanguageOptions();
|
|
260
|
+
this.refreshRender();
|
|
261
|
+
}
|
|
241
262
|
}
|
|
242
263
|
/**
|
|
243
264
|
Called when user changes a preference in the panel
|
|
@@ -285,12 +306,6 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
285
306
|
// Values are saved under 'configOverrides' in the same structure as in the config
|
|
286
307
|
this.context.userDataManager.saveUserData(`${this.storagePath}.${preference.configPath}`, preference.currentValue);
|
|
287
308
|
}
|
|
288
|
-
/**
|
|
289
|
-
Delete user preference in the local browser storage
|
|
290
|
-
*/
|
|
291
|
-
deletePreferenceInStorage(preferenceKey) {
|
|
292
|
-
this.context.userDataManager.deleteUserData(`${this.storagePath}.${this.preferences[preferenceKey].configPath}`);
|
|
293
|
-
}
|
|
294
309
|
/**
|
|
295
310
|
* Reset user preferences back to defaults. This will delete the configOverrides object in storage and set the
|
|
296
311
|
* current state back to the defaults from config.json
|
|
@@ -302,8 +317,8 @@ ${this.htmlUnsafe(this.feedbackTemplateHtml ?? '')}`;
|
|
|
302
317
|
}
|
|
303
318
|
}
|
|
304
319
|
resetAll() {
|
|
320
|
+
this.context.userDataManager.deleteUserData(this.storagePath);
|
|
305
321
|
for (const preferenceKey in this.preferences) {
|
|
306
|
-
this.deletePreferenceInStorage(preferenceKey);
|
|
307
322
|
this.preferences[preferenceKey].currentValue = this.context.configManager.getDefaultConfigValue(this.preferences[preferenceKey].configPath);
|
|
308
323
|
this.updatePreferenceInState(preferenceKey);
|
|
309
324
|
this.updatePreferenceInConfig(preferenceKey);
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.2.0-dev.
|
|
1
|
+
{"version":"1.2.0-dev.2776642665", "build":"2776642665", "date":"20/08/2026"}
|
|
@@ -339,6 +339,7 @@ class GirafeConfig {
|
|
|
339
339
|
if (!config.languages) {
|
|
340
340
|
throw new Error(`Configuration for languages is required. See https://doc.geogirafe.org/docs/configuration.`);
|
|
341
341
|
}
|
|
342
|
+
config.languages.userLanguage = config.languages.userLanguage ?? null;
|
|
342
343
|
return config.languages;
|
|
343
344
|
}
|
|
344
345
|
initConfigInterface(config) {
|
|
@@ -10,6 +10,15 @@ declare class StateManager extends GirafeSingleton {
|
|
|
10
10
|
constructor(context: IGirafeContext);
|
|
11
11
|
initializeSingleton(): void;
|
|
12
12
|
private setDefaultValues;
|
|
13
|
+
/**
|
|
14
|
+
* Get the language based on the following priority:
|
|
15
|
+
* 1. user preferences, 2. browser language, 3. app default language
|
|
16
|
+
*/
|
|
17
|
+
decideLanguage(): string | null;
|
|
18
|
+
/**
|
|
19
|
+
* The fallback language is based on the browser language or app default language
|
|
20
|
+
*/
|
|
21
|
+
fallbackLanguage(): string | null;
|
|
13
22
|
private onChange;
|
|
14
23
|
subscribe(path: string, callback: Callback): Callback;
|
|
15
24
|
subscribe(path: RegExp, callback: Callback): Callback;
|
|
@@ -26,10 +26,32 @@ class StateManager extends GirafeSingleton {
|
|
|
26
26
|
if (this.state && config) {
|
|
27
27
|
this.state.application.isConfigurationLoaded = true;
|
|
28
28
|
this.state.projection = config.map.srid;
|
|
29
|
-
this.state.language =
|
|
29
|
+
this.state.language = this.decideLanguage();
|
|
30
30
|
this.state.interface.selectionComponent = config.interface.defaultSelectionComponent;
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Get the language based on the following priority:
|
|
35
|
+
* 1. user preferences, 2. browser language, 3. app default language
|
|
36
|
+
*/
|
|
37
|
+
decideLanguage() {
|
|
38
|
+
return this.context.configManager.Config?.languages.userLanguage ?? this.fallbackLanguage();
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The fallback language is based on the browser language or app default language
|
|
42
|
+
*/
|
|
43
|
+
fallbackLanguage() {
|
|
44
|
+
const languageConfig = this.context.configManager.Config?.languages;
|
|
45
|
+
if (!languageConfig) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const browserLanguage = navigator.language.toLowerCase();
|
|
49
|
+
const languageCode = browserLanguage.substring(0, 2);
|
|
50
|
+
if (Object.keys(languageConfig.translations).includes(languageCode)) {
|
|
51
|
+
return languageCode;
|
|
52
|
+
}
|
|
53
|
+
return languageConfig.defaultLanguage;
|
|
54
|
+
}
|
|
33
55
|
onChange(property, oldValue, value, parents) {
|
|
34
56
|
const path = property.trim();
|
|
35
57
|
for (const key in this.callbacks) {
|