src/app/core/setup/setup.service.ts
Loads available "scenarios" of base configs that users can select to start with setting up their system.
Methods |
|
Async getAvailableBaseConfig |
getAvailableBaseConfig()
|
Defined in src/app/core/setup/setup.service.ts:33
|
Returns :
Promise<BaseConfig[]>
|
Async initSystemWithBaseConfig | ||||||
initSystemWithBaseConfig(baseConfig: BaseConfig)
|
||||||
Defined in src/app/core/setup/setup.service.ts:59
|
||||||
Initialize the system with the given base config, saving all given base-config entities to the database.
Parameters :
Returns :
Promise<void>
|
Public Async waitForConfigReady | ||||||||
waitForConfigReady(mustHaveConfigAndSync: boolean)
|
||||||||
Defined in src/app/core/setup/setup.service.ts:111
|
||||||||
Check if we are currently still waiting for config to be initialized or downloaded and keep the app on the loading screen until that is done.
Parameters :
Returns :
Promise<boolean>
|
import { inject, Injectable } from "@angular/core";
import { BaseConfig } from "./base-config";
import { EntityMapperService } from "../entity/entity-mapper/entity-mapper.service";
import { HttpClient } from "@angular/common/http";
import { combineLatest, filter, firstValueFrom, merge, of } from "rxjs";
import { EntitySchemaService } from "../entity/schema/entity-schema.service";
import { EntityRegistry } from "../entity/database-entity.decorator";
import { Entity } from "../entity/model/entity";
import { Logging } from "../logging/logging.service";
import { SyncStateSubject } from "../session/session-type";
import { ConfigService } from "../config/config.service";
import { SyncState } from "../session/session-states/sync-state.enum";
import { catchError, switchMap } from "rxjs/operators";
import { asArray } from "../../utils/asArray";
/**
* Loads available "scenarios" of base configs
* that users can select to start with setting up their system.
*/
@Injectable({
providedIn: "root",
})
export class SetupService {
private readonly BASE_CONFIGS_FOLDER = "assets/base-configs";
private readonly httpClient = inject(HttpClient);
private readonly entityMapper = inject(EntityMapperService);
private readonly schemaService = inject(EntitySchemaService);
private readonly entityRegistry = inject(EntityRegistry);
private readonly configService = inject(ConfigService);
private readonly syncState = inject(SyncStateSubject);
async getAvailableBaseConfig(): Promise<BaseConfig[]> {
const doc = await firstValueFrom(
this.httpClient
.get<
BaseConfig[]
>(this.BASE_CONFIGS_FOLDER + "/available-configs.json", { responseType: "json" })
.pipe(
catchError((e) => {
if (e.status === 404) {
Logging.warn("No available-configs.json found.");
return of([]);
} else {
throw e;
}
}),
),
);
return doc;
}
/**
* Initialize the system with the given base config,
* saving all given base-config entities to the database.
* @param baseConfig
*/
async initSystemWithBaseConfig(baseConfig: BaseConfig): Promise<void> {
Logging.debug("Initializing system with new base config", baseConfig);
for (const file of baseConfig.entitiesToImport) {
const fileName = `${this.BASE_CONFIGS_FOLDER}/${file}`;
const docs = await firstValueFrom(
this.httpClient.get<Object | Object[]>(fileName, {
responseType: "json",
}),
);
for (const doc of asArray(docs)) {
const entity = this.parseObjectToEntity(doc);
if (entity) {
await this.entityMapper.save(entity);
} else {
Logging.warn(
"Invalid entity file. SetupService is skipping to import this.",
fileName,
doc,
);
}
}
}
}
/**
* (Try to) convert the given doc to an Entity instance to be saved to the database.
*/
private parseObjectToEntity(doc: any): Entity | undefined {
if (!doc || !doc["_id"]) {
return;
}
const entityType = this.entityRegistry.get(
Entity.extractTypeFromId(doc["_id"]),
);
if (!entityType) {
throw new Error("EntityType for entityToImport not found: " + doc["_id"]);
}
const entity = this.schemaService.loadDataIntoEntity(new entityType(), doc);
Logging.debug("Importing baseConfig entity", entity);
return entity;
}
/**
* Check if we are currently still waiting for config to be initialized or downloaded
* and keep the app on the loading screen until that is done.
*/
public async waitForConfigReady(
mustHaveConfigAndSync: boolean = false,
): Promise<boolean> {
const configReady$ = this.configService.configUpdates.pipe(
filter((c) => c !== undefined),
);
const sync$ = this.syncState.pipe(
filter((state) => state === SyncState.COMPLETED),
// make sure config update is already done after the sync:
switchMap(() => this.configService.loadOnce()),
);
if (mustHaveConfigAndSync) {
await firstValueFrom(combineLatest([configReady$, sync$]));
} else {
await firstValueFrom(merge(configReady$, sync$));
}
return true;
}
}