Skip to content

Commit

Permalink
feat: merge configs on initialization
Browse files Browse the repository at this point in the history
* values from configs (default, instance, brandings) are now merged when loading instead of fetching them on each 'getProperty()' call
  • Loading branch information
xflord authored and HejdaJakub committed Oct 23, 2023
1 parent 0e8406a commit 962926a
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 37 deletions.
14 changes: 7 additions & 7 deletions libs/config/src/lib/app-config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,20 +128,20 @@ export class AppConfigService {
.get('/assets/config/instanceConfig.json', {
headers: this.getNoCacheHeaders(),
})
.subscribe(
(config: PerunConfig) => {
this.storeService.setInstanceConfig(config);
.subscribe({
next: (config: PerunConfig) => {
this.storeService.mergeConfig(config);
const branding = document.location.hostname;
if (config?.['brandings']?.[branding]) {
this.storeService.setBanding(branding);
this.storeService.mergeConfig(config?.['brandings']?.[branding]);
}
resolve();
},
() => {
error: () => {
// console.log('instance config not detected');
resolve();
}
);
},
});
});
}

Expand Down
54 changes: 24 additions & 30 deletions libs/perun/services/src/lib/store.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,13 @@ import { PerunConfig } from '@perun-web-apps/perun/models';
providedIn: 'root',
})
export class StoreService {
private instanceConfig: PerunConfig;
private defaultConfig: PerunConfig;
private config: PerunConfig;
private appsConfig: PerunAppsConfig;
private principal: PerunPrincipal;
private initialPageId: number;
private branding = '';

setInstanceConfig(instanceConfig: PerunConfig): void {
this.instanceConfig = instanceConfig;
}

setDefaultConfig(defaultConfig: PerunConfig): void {
this.defaultConfig = defaultConfig;
this.config = defaultConfig;
}

getAppsConfig(): PerunAppsConfig {
Expand Down Expand Up @@ -57,35 +51,35 @@ export class StoreService {
return this.getProperty('member_profile_attributes_friendly_names');
}

setBanding(branding: string): void {
this.branding = branding;
}

getProperty<T extends keyof PerunConfig>(key: T): PerunConfig[T] {
if (!this.instanceConfig || !this.defaultConfig) {
if (!this.config) {
return null;
}
return this.config[key];
}

const configs: PerunConfig[] = [
this.instanceConfig?.brandings?.[this.branding],
this.instanceConfig,
];

const defaultValue: PerunConfig[T] = this.defaultConfig[key];
let currentValue: PerunConfig[T] = null;
for (const config of configs) {
if (config && (currentValue === null || currentValue === undefined)) {
currentValue = config[key];
}
/*
Merges a config into the existing config, substituting values in the existing with values in the configToMerge.
Objects are merged per property, not as a whole (see `addMissingValuesToProperty`)
Be careful of order of merging (make sure default config is set before merging another config)
*/
mergeConfig<T extends object, K extends keyof T>(configToMerge: PerunConfig): void {
for (const key of Object.keys(configToMerge)) {
if (key === 'brandings') continue;
this.config[key] = this.addMissingValuesToProperty(
configToMerge[key] as T[K],
this.config[key] as T[K]
);
}
if (currentValue === null) {
return defaultValue;
}

return this.addMissingValuesToProperty(currentValue, defaultValue);
}

addMissingValuesToProperty<T extends object, K extends keyof T>(
/*
For an object property, merge properties from the `defaultValue` with properties from `value`.
Properties defined in `value` are overwritten with their value, remaining properties are kept from `defaultValue`
Returns `value` if a simple type is passed.
Works recursively
*/
private addMissingValuesToProperty<T extends object, K extends keyof T>(
value: T[K],
defaultValue: T[K]
): T[K] {
Expand Down

0 comments on commit 962926a

Please sign in to comment.