import userStore from '$lib/stores/user-store'; import type { AllAppConfig, AppConfigRawResponse } from '$lib/types/application-configuration.type'; import { cachedApplicationLogo, cachedBackgroundImage, cachedDefaultProfilePicture, cachedEmailLogo, cachedProfilePicture } from '$lib/utils/cached-image-util'; import { get } from 'svelte/store'; import APIService from './api-service'; export default class AppConfigService extends APIService { list = async (showAll = false) => { let url = '/application-configuration'; if (showAll) url += '/all'; const { data } = await this.api.get(url); return parseConfigList(data); }; update = async (appConfig: AllAppConfig) => { // Convert all values to string, stringifying JSON where needed const appConfigConvertedToString: Record = {}; for (const key in appConfig) { const value = (appConfig as any)[key]; appConfigConvertedToString[key] = typeof value === 'object' && value !== null ? JSON.stringify(value) : String(value); } const res = await this.api.put('/application-configuration', appConfigConvertedToString); return parseConfigList(res.data); }; updateFavicon = async (favicon: File) => { const formData = new FormData(); formData.append('file', favicon); await this.api.put(`/application-images/favicon`, formData); }; updateLogo = async (logo: File, light = true) => { const formData = new FormData(); formData.append('file', logo); await this.api.put(`/application-images/logo`, formData, { params: { light } }); cachedApplicationLogo.bustCache(light); }; updateEmailLogo = async (emailLogo: File) => { const formData = new FormData(); formData.append('file', emailLogo); await this.api.put(`/application-images/email`, formData); cachedEmailLogo.bustCache(); }; updateDefaultProfilePicture = async (defaultProfilePicture: File) => { const formData = new FormData(); formData.append('file', defaultProfilePicture); await this.api.put(`/application-images/default-profile-picture`, formData); cachedDefaultProfilePicture.bustCache(); }; updateBackgroundImage = async (backgroundImage: File) => { const formData = new FormData(); formData.append('file', backgroundImage!); await this.api.put(`/application-images/background`, formData); cachedBackgroundImage.bustCache(); }; deleteBackgroundImage = async () => { await this.api.delete(`/application-images/background`); cachedBackgroundImage.bustCache(); }; deleteDefaultProfilePicture = async () => { await this.api.delete('/application-images/default-profile-picture'); cachedDefaultProfilePicture.bustCache(); cachedProfilePicture.bustCache(get(userStore)!.id); }; sendTestEmail = async () => { await this.api.post('/application-configuration/test-email'); }; syncLdap = async () => { await this.api.post('/application-configuration/sync-ldap'); }; } function parseConfigList(data: AppConfigRawResponse) { const appConfig: Partial = {}; data.forEach(({ key, value }) => { (appConfig as any)[key] = parseValue(value); }); return appConfig as AllAppConfig; } function parseValue(value: string) { // Try to parse JSON first try { const parsed = JSON.parse(value); if (typeof parsed === 'object' && parsed !== null) { return parsed; } value = String(parsed); } catch {} // Handle rest of the types if (value === 'true') { return true; } else if (value === 'false') { return false; } else if (/^-?\d+(\.\d+)?$/.test(value)) { return parseFloat(value); } else { return value; } }