/** * Service for managing structured user preferences defined by a schema * * The UserPreferencesRepository provides a managed key-value store for user * preferences that are declared by a schema. Unlike {@link UserDataRepository}, * which allows storing arbitrary data under any key, the keys here are the ones * the system already knows about. * * Each preference has a default that comes from the application configuration. * Reads fall back to that default until the user stores a value of their own, * so a preference always has a value even before anyone changes it. * * @example Reading and updating a preference * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const userPreferences = platform.get( * PlatformServiceName.UserPreferencesRepository * ); * * const emailNotifications = userPreferences.get('emailNotifications'); * * await userPreferences.set('emailNotifications', !emailNotifications); * ``` * * @example Saving a preferences form against the schema * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const userPreferences = platform.get( * PlatformServiceName.UserPreferencesRepository * ); * * const formValues: Record = { * language: 'sv-SE', * pageSize: 25, * unknownSetting: 'ignored', * }; * * // Only save the values the schema knows about * for (const key of Object.keys(userPreferences.getSchema())) { * const value = formValues[key]; * * if (value !== undefined) { * await userPreferences.set(key, value); * } * } * ``` * * @public * @group User data * @see {@link UserDataRepository} for storing arbitrary data */ export interface UserPreferencesRepository { /** * Get user preference values * * This method can retrieve either all preferences or a specific preference * value. When called without arguments, it returns an object containing all * preference values. When called with a key, it returns only that specific * preference value. * * Values the user has not changed fall back to the default from the * application configuration. The returned object is built fresh on every * call, so changing it does not change the stored preferences. Use * {@link UserPreferencesRepository.set} for that. * * @param key - Optional key for a specific preference. If omitted, all preferences are returned * @returns If a key is supplied, the value stored under that key, or `undefined` when * the key has neither a stored value nor a default. If no key is supplied, * an object containing all preference values * * @typeParam T - The expected type of the preference value(s) * * @example Getting all preferences * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const userPreferences = platform.get( * PlatformServiceName.UserPreferencesRepository * ); * * const allPreferences = userPreferences.get(); * console.log('Language:', allPreferences.language); * console.log('Timezone:', allPreferences.timezone); * ``` * * @example Getting a specific preference * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const userPreferences = platform.get( * PlatformServiceName.UserPreferencesRepository * ); * * const language = userPreferences.get('language'); * const showHints = userPreferences.get('showHints'); * ``` * * @see {@link UserPreferencesRepository.set} to change a preference * @see {@link UserPreferencesRepository.getSchema} to discover the available keys */ get(key?: string): T; /** * Set or clear a user preference value * * Saves a preference value to the server. The value must be JSON-serializable. * To go back to the default, pass `undefined` as the data. The key is dropped * when the preferences are sent to the server, so reads return `undefined` * rather than the default until the request has completed. * * @param key - The preference key to set * @param data - The value to save. Pass `undefined` to clear the stored value * @returns A promise that resolves when the preference has been saved * @throws An error if the request to the server fails * * @typeParam T - The type of the preference value * * @example Setting various preference types * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const userPreferences = platform.get( * PlatformServiceName.UserPreferencesRepository * ); * * await userPreferences.set('language', 'sv-SE'); * await userPreferences.set('pageSize', 25); * await userPreferences.set('showAdvancedFeatures', true); * ``` * * @example Setting complex preference values * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * interface DashboardLayout { * widgets: string[]; * columns: number; * } * * const userPreferences = platform.get( * PlatformServiceName.UserPreferencesRepository * ); * * const layout: DashboardLayout = { * widgets: ['calendar', 'tasks', 'notifications'], * columns: 3, * }; * * await userPreferences.set('dashboardLayout', layout); * ``` * * @example Resetting a preference to default * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const userPreferences = platform.get( * PlatformServiceName.UserPreferencesRepository * ); * * // Clear the stored value so the configured default applies again * await userPreferences.set('fontSize', undefined); * ``` * * @note The value must be serializable as JSON. Non-serializable data * (like functions, circular references, etc.) may result in errors * or data loss * * @see {@link UserPreferencesRepository.get} to read a preference */ set(key: string, data?: T): Promise; /** * Get the JSON schema defining available user preferences * * Returns the schema that declares which preferences exist and what shape * their values have. This is useful for building a preferences UI without * hard-coding the list of keys. * * The schema is served by the backend and is not applied to the values * passed to {@link UserPreferencesRepository.set}, which are stored as * given. Default values are not part of the schema either, they come from * the application configuration and are already applied by * {@link UserPreferencesRepository.get}. * * @returns An object representing the JSON schema for user preferences * * @example Using the schema to build a preferences UI * ```ts * import { PlatformServiceName } from '@limetech/lime-web-components'; * * const userPreferences = platform.get( * PlatformServiceName.UserPreferencesRepository * ); * * // Build the form from the keys the schema declares * for (const [key, value] of Object.entries(userPreferences.getSchema())) { * // The schema is plain JSON, so a consumer has to state its shape * const definition = value as { type: string }; * * console.log(`Preference: ${key}`); * console.log(`Type: ${definition.type}`); * console.log('Current value:', userPreferences.get(key)); * } * ``` * * @see {@link UserPreferencesRepository.get} to read the current values */ getSchema(): Record; }