@geogirafe/lib-geoportal
Version:
GeoGirafe is a flexible application to build online geoportals.
111 lines (110 loc) • 4.33 kB
JavaScript
import GirafeSingleton from '../../base/GirafeSingleton';
import GirafeConfig from './girafeconfig';
import UserDataManager from '../userdata/userdatamanager';
import { getPropertyByPath, mergeObjects } from '../utils/pathUtils';
class ConfigManager extends GirafeSingleton {
constructor() {
super(...arguments);
Object.defineProperty(this, "config", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
// Backup of config before applying user overrides
Object.defineProperty(this, "defaultConfig", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "loadingPromise", {
enumerable: true,
configurable: true,
writable: true,
value: null
});
Object.defineProperty(this, "storagePathForOverrides", {
enumerable: true,
configurable: true,
writable: true,
value: 'configOverrides'
});
// TODO REG: With multiple interface (not only desktop and mobile)
// We have to find another solution here.
// Perhaps something more generic where we can pass a list of interfaces
Object.defineProperty(this, "isMobile", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
}
initMobile() {
this.isMobile = true;
}
get Config() {
return this.config;
}
async loadConfig() {
if (this.loadingPromise) {
// There's already a promise for loading the configuration
// => return it instead of starting another request
return this.loadingPromise;
}
if (this.config) {
// Config was already loaded.
// => stop here
return Promise.resolve(this.config);
}
// Load config
this.loadingPromise = (async () => {
const response = await fetch('config.json');
let jsonConfig = await response.json();
if (this.isMobile) {
try {
const responseMobile = await fetch('config.mobile.json');
const jsonMobileConfig = await responseMobile.json();
jsonConfig = this.mergeConfigs(jsonConfig, jsonMobileConfig);
}
catch {
console.warn('No configuration found for mobile. Defaulting to desktop configuration.');
}
}
// Create a backup of the default config before applying overrides
this.defaultConfig = new GirafeConfig(structuredClone(jsonConfig));
// Load config overrides and merge them with the default config
const configOverrides = this.getConfigOverrides(this.defaultConfig.userdata.source);
jsonConfig = this.mergeConfigs(jsonConfig, configOverrides);
this.config = new GirafeConfig(jsonConfig);
console.log('Application Configuration loaded.');
return this.config;
})();
return this.loadingPromise;
}
/**
* Merges two configuration objects recursively.
*/
mergeConfigs(obj1, obj2) {
return mergeObjects(obj1, obj2);
}
/**
* Retrieves saved configuration overrides based on the user data source.
* @param userDataSource The source of user data.
*/
getConfigOverrides(userDataSource) {
const userDataManager = UserDataManager.getInstance();
// Set the user data source first before requesting config overrides from the userDataManager
userDataManager.setSource(userDataSource);
return userDataManager.getUserData(this.storagePathForOverrides) || {};
}
/**
* Retrieves the original (default) configuration value before applying overrides.
* @param path The path to the configuration property.
*/
getDefaultConfigValue(path) {
const { found, parentObject, lastKey } = getPropertyByPath(this.defaultConfig, path);
return found && parentObject && lastKey ? parentObject[lastKey] : undefined;
}
}
export default ConfigManager;