All files / core/blong-browser/src/components/LanguageSwitcher LanguageSwitcher.tsx

100% Statements 19/19
100% Branches 10/10
100% Functions 7/7
100% Lines 13/13

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69                                                                      31x 31x 31x         10x 9x 9x 5x 9x 2x   4x       10x   5x           1x              
import './LanguageSwitcher.css';
 
import {useMemo} from 'react';
import {Dropdown} from '../../primereact/index.js';
import {useAppStore} from '../../state/appStore.js';
 
/** A selectable UI language — `value` matches the translation-dictionary key. */
export interface ILanguageOption {
    value: string;
    label: string;
}
 
export interface ILanguageSwitcherProps {
    /**
     * Explicit language list — wins over the portal config
     * (`config.portal.languages`).  When neither is set, the switcher falls
     * back to the keys of the configured translation dictionaries.
     */
    languages?: ILanguageOption[];
}
 
/**
 * LanguageSwitcher — the configurable UI-language selector in the portal
 * menubar, rendered to the left of the profile menu.
 *
 * It offers ad-hoc (client-side) switching: selecting a language calls
 * `appStore.setLanguage`, which swaps the active translation dictionary and
 * activates the matching PrimeReact locale.  The choice is NOT persisted to
 * the user profile — that is the profile page's `preferredLanguage` edit.
 *
 * The available languages are config-driven (`config.portal.languages`), with
 * a fallback to the keys of `config.portal.translations`.  When fewer than
 * two languages are configured the switcher renders nothing.
 */
export function LanguageSwitcher({languages: languagesProp}: ILanguageSwitcherProps) {
    const language = useAppStore(s => s.language);
    const setLanguage = useAppStore(s => s.setLanguage);
    const portalConfig = useAppStore(s => s.portal.portalConfig);
 
    // Config wins (prop → portal config), then fall back to the configured
    // translation-dictionary keys so any app with translations gets a switcher
    // without extra config.
    const languages = useMemo<ILanguageOption[]>(() => {
        const configured = languagesProp ?? portalConfig?.languages;
        if (configured && configured.length) return configured;
        const dicts = portalConfig?.translations;
        if (dicts) {
            return Object.keys(dicts).map(value => ({value, label: value}));
        }
        return [];
    }, [languagesProp, portalConfig?.languages, portalConfig?.translations]);
 
    // Nothing to switch between — hide the selector.
    if (languages.length < 2) return null;
 
    return (
        <Dropdown
            value={language}
            options={languages}
            optionLabel="label"
            optionValue="value"
            onChange={e => setLanguage(e.value as string)}
            className="blong-language-switcher"
            panelClassName="blong-language-switcher__panel"
            aria-label="Language"
        />
    );
}