added Swedish/SE - Multi-language/I18n support #22

This commit is contained in:
Proddy
2022-09-09 21:09:51 +02:00
parent 5845c37672
commit 4cd655fb36
16 changed files with 347 additions and 63 deletions

View File

@@ -23,6 +23,7 @@ import { loadLocaleAsync } from './i18n/i18n-util.async';
import { ReactComponent as NLflag } from './i18n/NL.svg';
import { ReactComponent as DEflag } from './i18n/DE.svg';
import { ReactComponent as GBflag } from './i18n/GB.svg';
import { ReactComponent as SEflag } from './i18n/SE.svg';
const SignIn: FC = () => {
const authenticationContext = useContext(AuthenticationContext);
@@ -120,6 +121,10 @@ const SignIn: FC = () => {
<NLflag style={{ width: 24 }} />
&nbsp;NL
</Button>
<Button size="small" variant={locale === 'se' ? 'contained' : 'outlined'} onClick={() => selectLocale('se')}>
<SEflag style={{ width: 24 }} />
&nbsp;SE
</Button>
</Box>
<ValidatedTextField

View File

@@ -26,6 +26,7 @@ import { loadLocaleAsync } from '../../i18n/i18n-util.async';
import { ReactComponent as NLflag } from '../../i18n/NL.svg';
import { ReactComponent as DEflag } from '../../i18n/DE.svg';
import { ReactComponent as GBflag } from '../../i18n/GB.svg';
import { ReactComponent as SEflag } from '../../i18n/SE.svg';
const ItemTypography = styled(Typography)<TypographyProps>({
maxWidth: '250px',
@@ -82,6 +83,10 @@ const LayoutAuthMenu: FC = () => {
<NLflag style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;NL
</MenuItem>
<MenuItem key="se" value="se">
<SEflag style={{ width: 16, verticalAlign: 'middle' }} />
&nbsp;SE
</MenuItem>
</TextField>
<IconButton

View File

@@ -16,7 +16,8 @@ import {
ListItemText,
TextField,
Theme,
useTheme
useTheme,
Typography
} from '@mui/material';
import RefreshIcon from '@mui/icons-material/Refresh';
import AccessTimeIcon from '@mui/icons-material/AccessTime';
@@ -97,43 +98,42 @@ const NTPStatusForm: FC = () => {
}
};
const renderSetTimeDialog = () => {
return (
<Dialog open={settingTime} onClose={() => setSettingTime(false)}>
<DialogTitle>{LL.SET_TIME()}</DialogTitle>
<DialogContent dividers>
<Box mb={2}>{LL.SET_TIME_TEXT()}</Box>
<TextField
label={LL.LOCAL_TIME()}
type="datetime-local"
value={localTime}
onChange={updateLocalTime}
disabled={processing}
variant="outlined"
fullWidth
InputLabelProps={{
shrink: true
}}
/>
</DialogContent>
<DialogActions>
<Button startIcon={<CancelIcon />} variant="outlined" onClick={() => setSettingTime(false)} color="secondary">
{LL.CANCEL()}
</Button>
<Button
startIcon={<AccessTimeIcon />}
variant="outlined"
onClick={configureTime}
disabled={processing}
color="primary"
autoFocus
>
{LL.SET_TIME()}
</Button>
</DialogActions>
</Dialog>
);
};
const renderSetTimeDialog = () => (
<Dialog open={settingTime} onClose={() => setSettingTime(false)}>
<DialogTitle>{LL.SET_TIME()}</DialogTitle>
<DialogContent dividers>
<Box color="warning.main" p={0} pl={0} pr={0} mt={0} mb={2}>
<Typography variant="body2">{LL.SET_TIME_TEXT()}</Typography>
</Box>
<TextField
label={LL.LOCAL_TIME()}
type="datetime-local"
value={localTime}
onChange={updateLocalTime}
disabled={processing}
fullWidth
InputLabelProps={{
shrink: true
}}
/>
</DialogContent>
<DialogActions>
<Button startIcon={<CancelIcon />} variant="outlined" onClick={() => setSettingTime(false)} color="secondary">
{LL.CANCEL()}
</Button>
<Button
startIcon={<AccessTimeIcon />}
variant="outlined"
onClick={configureTime}
disabled={processing}
color="primary"
autoFocus
>
{LL.SET_TIME()}
</Button>
</DialogActions>
</Dialog>
);
const content = () => {
if (!data) {

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 85.333 512 341.333"><path fill="#0052B4" d="M0 85.333h512V426.67H0z"/><path fill="#FFDA44" d="M192 85.33h-64v138.666H0v64h128v138.666h64V287.996h320v-64H192z"/></svg>

After

Width:  |  Height:  |  Size: 217 B

View File

@@ -230,7 +230,7 @@ const de: Translation = {
ACTIVE: 'Aktiv',
UNKNOWN: 'Unbekannt',
SET_TIME: 'Zeiteinstellung',
SET_TIME_TEXT: 'Geben Sie das lokale Datum und die Zeit ein.',
SET_TIME_TEXT: 'Geben Sie das lokale Datum und die Zeit ein',
LOCAL_TIME: 'Lokalzeit',
UTC_TIME: 'UTC Zeit',
ENABLE_NTP: 'Aktiviere NTP',

View File

@@ -134,7 +134,7 @@ const en: BaseTranslation = {
CUSTOMIZATIONS_RESTART: 'All customizations have been removed. Restarting...',
CUSTOMIZATIONS_FULL: 'Selected entities exceeded limit. Please save in batches',
CUSTOMIZATIONS_SAVED: 'Customizations saved',
CUSTOMIZATIONS_HELP_1: 'Select a device and customize the entities using the options',
CUSTOMIZATIONS_HELP_1: 'Select a device and customize the entities options or click to rename',
CUSTOMIZATIONS_HELP_2: 'mark as favorite',
CUSTOMIZATIONS_HELP_3: 'disable write action',
CUSTOMIZATIONS_HELP_4: 'exclude from MQTT and API',
@@ -230,7 +230,7 @@ const en: BaseTranslation = {
ACTIVE: 'Active',
UNKNOWN: 'Unknown',
SET_TIME: 'Set Time',
SET_TIME_TEXT: 'Enter local date and time below to set the time.',
SET_TIME_TEXT: 'Enter local date and time below to set the time',
LOCAL_TIME: 'Local Time',
UTC_TIME: 'UTC Time',
ENABLE_NTP: 'Enable NTP',

View File

@@ -9,6 +9,7 @@ export type Locales =
| 'de'
| 'en'
| 'nl'
| 'se'
export type Translation = RootTranslation
@@ -543,7 +544,7 @@ type RootTranslation = {
*/
CUSTOMIZATIONS_SAVED: string
/**
* Select a device and customize the entities using the options
* Select a device and customize the entities options or click to rename
*/
CUSTOMIZATIONS_HELP_1: string
/**
@@ -907,7 +908,7 @@ type RootTranslation = {
*/
SET_TIME: string
/**
* Enter local date and time below to set the time.
* Enter local date and time below to set the time
*/
SET_TIME_TEXT: string
/**
@@ -1548,7 +1549,7 @@ export type TranslationFunctions = {
*/
CUSTOMIZATIONS_SAVED: () => LocalizedString
/**
* Select a device and customize the entities using the options
* Select a device and customize the entities options or click to rename
*/
CUSTOMIZATIONS_HELP_1: () => LocalizedString
/**
@@ -1912,7 +1913,7 @@ export type TranslationFunctions = {
*/
SET_TIME: () => LocalizedString
/**
* Enter local date and time below to set the time.
* Enter local date and time below to set the time
*/
SET_TIME_TEXT: () => LocalizedString
/**

View File

@@ -9,6 +9,7 @@ const localeTranslationLoaders = {
de: () => import('./de'),
en: () => import('./en'),
nl: () => import('./nl'),
se: () => import('./se'),
}
const updateDictionary = (locale: Locales, dictionary: Partial<Translations>) =>

View File

@@ -8,11 +8,13 @@ import { loadedFormatters, loadedLocales, locales } from './i18n-util'
import de from './de'
import en from './en'
import nl from './nl'
import se from './se'
const localeTranslations = {
de,
en,
nl,
se,
}
export const loadLocale = (locale: Locales): void => {

View File

@@ -11,7 +11,8 @@ export const baseLocale: Locales = 'en'
export const locales: Locales[] = [
'de',
'en',
'nl'
'nl',
'se'
]
export const loadedLocales = {} as Record<Locales, Translations>

View File

@@ -230,7 +230,7 @@ const nl: BaseTranslation = {
ACTIVE: 'Actief',
UNKNOWN: 'Onbekend',
SET_TIME: 'Tijd instellen',
SET_TIME_TEXT: 'Geef de locale datum en tijd in.',
SET_TIME_TEXT: 'Geef de locale datum en tijd in',
LOCAL_TIME: 'Locale Tijd',
UTC_TIME: 'UTC Tijd',
ENABLE_NTP: 'Activeer NTP',

View File

@@ -0,0 +1,266 @@
import type { BaseTranslation } from '../i18n-types';
const se: BaseTranslation = {
LANGUAGE: 'SE_Language',
RETRY: 'SE_Retry',
LOADING: 'SE_Loading',
IS_REQUIRED: 'SE_is required',
SIGN_IN: 'SE_Sign In',
SIGN_OUT: 'SE_Sign Out',
USERNAME: 'SE_Username',
PASSWORD: 'SE_Password',
DASHBOARD: 'SE_Dashboard',
SETTINGS: 'SE_Settings',
SAVED: 'SE_saved',
HELP: 'SE_Help',
LOGGED_IN: 'SE_Logged in as {name}',
PLEASE_SIGNIN: 'SE_Please sign in to continue',
UPLOAD_SUCCESSFUL: 'SE_Upload successful',
DOWNLOAD_SUCCESSFUL: 'SE_Download successful',
INVALID_LOGIN: 'SE_Invalid login details',
NETWORK: 'SE_Network',
SECURITY: 'SE_Security',
ONOFF_CAP: 'SE_ON/OFF',
ONOFF: 'SE_on/off',
TYPE: 'SE_Type',
DESCRIPTION: 'SE_Description',
ENTITIES: 'SE_Entities',
REFRESH: 'SE_Refresh',
EXPORT: 'SE_Export',
DEVICE_DETAILS: 'SE_Device Details',
BRAND: 'SE_Brand',
ENTITY_NAME: 'SE_Entity Name',
VALUE: 'SE_Value',
SHOW_FAV: 'SE_only show favorites',
DEVICE_SENSOR_DATA: 'SE_Device and Sensor Data',
DEVICES_SENSORS: 'SE_Devices & Sensors',
ATTACHED_SENSORS: 'SE_Attached EMS-ESP Sensors',
RUN_COMMAND: 'SE_Call Command',
CHANGE_VALUE: 'SE_Change Value',
CANCEL: 'SE_Cancel',
RESET: 'SE_Reset',
SEND: 'SE_Send',
SAVE: 'SE_Save',
REMOVE: 'SE_Remove',
PROBLEM_UPDATING: 'SE_Problem updating',
PROBLEM_LOADING: 'SE_Problem loading',
ACCESS_DENIED: 'SE_Access Denied',
ANALOG_SENSOR: 'SE_Analog Sensor',
ANALOG_SENSORS: 'SE_Analog Sensors',
UPDATED: 'SE_Updated',
UPDATE: 'SE_Update',
REMOVED: 'SE_Removed',
DELETION: 'SE_Deletion',
OFFSET: 'SE_Offset',
FACTOR: 'SE_Factor',
FREQ: 'SE_Frequency',
STARTVALUE: 'SE_Start value',
WARN_GPIO: 'SE_Warning: be careful when assigning a GPIO!',
EDIT: 'SE_Edit',
TEMP_SENSOR: 'SE_Temperature Sensor',
TEMP_SENSORS: 'SE_Temperature Sensors',
WRITE_COMMAND: 'SE_Write command {cmd}',
EMS_BUS_WARNING:
'EMS bus disconnected. If this warning still persists after a few seconds please check settings and board profile',
EMS_BUS_SCANNING: 'SE_Scanning for EMS devices...',
CONNECTED: 'SE_Connected',
TX_ISSUES: 'SE_Tx issues - try a different Tx Mode',
DISCONNECTED: 'SE_Disconnected',
EMS_SCAN: 'SE_Are you sure you want to initiate a full device scan of the EMS bus?',
EMS_BUS_STATUS: 'SE_EMS Bus Status',
ACTIVE_DEVICES: 'SE_Active Devices & Sensors',
DEVICE: 'SE_Device',
SUCCESS: 'SE_SUCCESS',
FAIL: 'SE_FAIL',
QUALITY: 'SE_QUALITY',
SCAN_DEVICES: 'SE_Scan for new devices',
EMS_BUS_STATUS_TITLE: 'SE_EMS Bus & Activity Status',
SCAN: 'SE_Scan',
STATUS_NAMES: [
'SE_EMS Telegrams Received (Rx)',
'SE_EMS Reads (Tx)',
'SE_EMS Writes (Tx)',
'SE_Temperature Sensor Reads',
'SE_Analog Sensor Reads',
'SE_MQTT Publishes',
'SE_API Calls',
'SE_Syslog Messages'
],
NUM_DEVICES: 'SE_{num} Device{{s}}',
NUM_TEMP_SENSORS: 'SE_{num} Temperature Sensor{{s}}',
NUM_ANALOG_SENSORS: 'SE_{num} Analog Sensor{{s}}',
NUM_DAYS: 'SE_{num} Day{{s}}',
NUM_SECONDS: 'SE_{num} Second{{s}}',
NUM_HOURS: 'SE_{num} Hour{{s}}',
NUM_MINUTES: 'SE_{num} Minute{{s}}',
APPLICATION_SETTINGS: 'SE_Application Settings',
CUSTOMIZATION: 'SE_Customization',
APPLICATION_RESTARTING: 'SE_EMS-ESP is restarting',
BOARD_PROFILE_TEXT:
'Select a pre-configured interface board profile from the list below or choose Custom to configure your own hardware settings',
BOARD_PROFILE: 'SE_Board Profile',
BUTTON: 'SE_Button',
TEMPERATURE: 'SE_Temperature',
DISABLED: 'SE_disabled',
GENERAL_OPTIONS: 'SE_General Options',
LANGUAGE_ENTITIES: 'SE_Language (for device entities)',
HIDE_LED: 'SE_Hide LED',
ENABLE_TELNET: 'SE_Enable Telnet Console',
ENABLE_ANALOG: 'SE_Enable Analog Sensors',
CONVERT_FAHRENHEIT: 'SE_Convert temperature values to Fahrenheit',
BYPASS_TOKEN: 'SE_Bypass Access Token authorization on API calls',
READONLY: 'SE_Enable read-only mode (blocks all outgoing EMS Tx Write commands)',
UNDERCLOCK_CPU: 'SE_Underclock CPU speed',
ENABLE_SHOWER_TIMER: 'SE_Enable Shower Timer',
ENABLE_SHOWER_ALERT: 'SE_Enable Shower Alert',
TRIGGER_TIME: 'SE_Trigger Time',
COLD_SHOT_DURATION: 'SE_Cold Shot Duration',
FORMATTING_OPTIONS: 'SE_Formatting Options',
BOOLEAN_FORMAT_DASHBOARD: 'SE_Boolean Format Dashboard',
BOOLEAN_FORMAT_API: 'SE_Boolean Format API/MQTT',
ENUM_FORMAT: 'SE_Enum Format API/MQTT',
INDEX: 'SE_Index',
ENABLE_PARASITE: 'SE_Enable parasite power',
LOGGING: 'SE_Logging',
LOG_HEX: 'SE_Log EMS telegrams in hexadecimal',
ENABLE_SYSLOG: 'SE_Enable Syslog',
MARK_INTERVAL: 'SE_Mark Interval',
SECONDS: 'SE_seconds',
MINUTES: 'SE_minutes',
RESTART: 'SE_Restart',
HOURS: 'SE_hours',
RESTART_TEXT: 'SE_EMS-ESP needs to be restarted to apply changed system settings',
COMMAND: 'SE_Command',
CUSTOMIZATIONS_RESTART: 'SE_All customizations have been removed. Restarting...',
CUSTOMIZATIONS_FULL: 'SE_Selected entities exceeded limit. Please save in batches',
CUSTOMIZATIONS_SAVED: 'SE_Customizations saved',
CUSTOMIZATIONS_HELP_1: 'SE_Select a device and customize the entities using the options',
CUSTOMIZATIONS_HELP_2: 'SE_mark as favorite',
CUSTOMIZATIONS_HELP_3: 'SE_disable write action',
CUSTOMIZATIONS_HELP_4: 'SE_exclude from MQTT and API',
CUSTOMIZATIONS_HELP_5: 'SE_hide from Dashboard',
SELECT_DEVICE: 'SE_Select a device',
SET_ALL: 'SE_set all',
OPTIONS: 'SE_Options',
NAME: 'SE_Name',
CUSTOMIZATIONS_RESET:
'Are you sure you want remove all customizations including the custom settings of the Temperature and Analog sensors?',
DEVICE_ENTITIES: 'SE_Device Entities',
USER_CUSTOMIZATION: 'SE_User Customization',
SUPPORT_INFORMATION: 'SE_Support Information',
CLICK_HERE: 'SE_Click Here',
HELP_INFORMATION_1: 'SE_Visit the online wiki to get instructions on how to configure EMS-ESP',
HELP_INFORMATION_2: 'SE_For live community chat join our Discord server',
HELP_INFORMATION_3: 'SE_To request a feature or report a bug',
HELP_INFORMATION_4:
'SE_remember to download and attach your system information for a faster response when reporting an issue',
HELP_INFORMATION_5:
'SE_EMS-ESP is a free and open-source project. Please support its future development by giving it a star on Github!',
SUPPORT_INFO: 'SE_Support Info',
UPLOAD: 'SE_Upload',
DOWNLOAD: 'SE_Download',
ABORTED: 'SE_aborted',
FAILED: 'SE_failed',
SUCCESSFUL: 'SE_successful',
SYSTEM: 'SE_System',
LOG: 'SE_Log',
STATUS: 'SE_Status',
UPLOAD_DOWNLOAD: 'SE_Upload/Download',
SYSTEM_VERSION_RUNNING: 'SE_You are currently running version',
SYSTEM_APPLY_FIRMWARE: 'SE_to apply the new firmware',
CLOSE: 'SE_Close',
USE: 'SE_Use',
FACTORY_RESET: 'SE_Factory Reset',
SYSTEM_FACTORY_TEXT: 'SE_Device has been factory reset and will now restart',
SYSTEM_FACTORY_TEXT_DIALOG: 'SE_Are you sure you want to reset the device to its factory defaults?',
VERSION_CHECK: 'SE_Version Check',
THE_LATEST: 'SE_The latest',
PLATFORM: 'SE_Device (Platform / SDK)',
UPTIME: 'SE_System Uptime',
CPU_FREQ: 'SE_CPU Frequency',
HEAP: 'SE_Heap (Free / Max Alloc)',
PSRAM: 'SE_PSRAM (Size / Free)',
FLASH: 'SE_Flash Chip (Size / Speed)',
FILESYSTEM: 'SE_File System (Used / Total)',
BUFFER_SIZE: 'SE_Buffer Size',
COMPACT: 'SE_Compact',
ENABLE_OTA: 'SE_Enable OTA Updates',
DOWNLOAD_CUSTOMIZATION_TEXT: 'SE_Download the entity customizations',
DOWNLOAD_SETTINGS_TEXT:
'Download the application settings. Be careful when sharing your settings as this file contains passwords and other sensitive system information',
UPLOAD_TEXT: 'SE_Upload a new firmware (.bin) file, settings or customizations (.json) file below',
UPLOADING: 'SE_Uploading',
UPLOAD_DROP_TEXT: 'SE_Drop file or click here',
ERROR: 'SE_Unexpected Error, please try again',
TIME_SET: 'SE_Time set',
MANAGE_USERS: 'SE_Manage Users',
IS_ADMIN: 'SE_is Admin',
USER_WARNING: 'SE_You must have at least one admin user configured',
ADD: 'SE_Add',
ACCESS_TOKEN_FOR: 'SE_Access Token for',
ACCESS_TOKEN_TEXT:
'SE_The token below is used with REST API calls that require authorization. It can be passed either as a Bearer token in the Authorization header or in the access_token URL query parameter.',
GENERATING_TOKEN: 'SE_Generating token',
USER: 'SE_User',
MODIFY: 'SE_Modify',
SU_TEXT:
'SE_The su (super user) password is used to sign authentication tokens and also enable admin privileges within the Console.',
NOT_ENABLED: 'SE_Not enabled',
ERRORS: 'SE_Errors',
DISCONNECT_REASON: 'SE_Disconnect Reason',
ENABLE_MQTT: 'SE_Enable MQTT',
OPTIONAL: 'SE_Optional',
FORMATTING: 'SE_Formatting',
FORMAT: 'SE_Format',
MQTT_NEST_1: 'SE_Nested in a single topic',
MQTT_NEST_2: 'SE_As individual topics',
MQTT_RESPONSE: 'SE_Publish command output to a `response` topic',
MQTT_PUBLISH_TEXT_1: 'SE_Publish single value topics on change',
MQTT_PUBLISH_TEXT_2: 'SE_Publish to command topics (ioBroker)',
MQTT_PUBLISH_TEXT_3: 'SE_Enable MQTT Discovery (Home Assistant, Domoticz)',
MQTT_PUBLISH_TEXT_4: 'SE_Prefix for the Discovery topics',
MQTT_PUBLISH_INTERVALS: 'SE_Publish Intervals',
MQTT_INT_BOILER: 'SE_Boilers and Heat Pumps',
MQTT_INT_THERMOSTATS: 'SE_Thermostats',
MQTT_INT_SOLAR: 'SE_Solar Modules',
MQTT_INT_MIXER: 'SE_Mixer Modules',
DEFAULT: 'SE_Default',
MQTT_CLEAN_SESSION: 'SE_Set Clean Session',
MQTT_RETAIN_FLAG: 'SE_Always set Retain flag',
INACTIVE: 'SE_Inactive',
ACTIVE: 'SE_Active',
UNKNOWN: 'SE_Unknown',
SET_TIME: 'SE_Set Time',
SET_TIME_TEXT: 'SE_Enter local date and time below to set the time',
LOCAL_TIME: 'SE_Local Time',
UTC_TIME: 'SE_UTC Time',
ENABLE_NTP: 'SE_Enable NTP',
TIME_ZONE: 'SE_Time Zone',
ACCESS_POINT: 'SE_Access Point',
AP_PROVIDE: 'SE_Enable Access Point',
AP_PROVIDE_TEXT_1: 'SE_always',
AP_PROVIDE_TEXT_2: 'SE_when WiFi is disconnected',
AP_PROVIDE_TEXT_3: 'SE_never',
AP_PREFERRED_CHANNEL: 'SE_Preferred Channel',
AP_HIDE_SSID: 'SE_Hide SSID',
NETWORK_SCAN: 'SE_Scan WiFi Networks',
IDLE: 'SE_Idle',
LOST: 'SE_Lost',
SCANNING: 'SE_Scanning',
SCAN_AGAIN: 'SE_Scan again',
NETWORK_SCANNER: 'SE_Network Scanner',
NETWORK_NO_WIFI: 'SE_No WiFi networks found',
NETWORK_BLANK_SSID: 'SE_leave blank to disable WiFi',
POWER: 'SE_Power',
NETWORK_DISABLE_SLEEP: 'SE_Disable WiFi Sleep Mode',
NETWORK_LOW_BAND: 'SE_Use Lower WiFi Bandwidth',
NETWORK_USE_DNS: 'SE_Enable mDNS Service',
NETWORK_ENABLE_IPV6: 'SE_Enable IPv6 support',
NETWORK_FIXED_IP: 'SE_Use Fixed IP address',
ADMIN: 'SE_Admin',
GUEST: 'SE_Guest',
NEW: 'SE_New',
RENAME: 'SE_Rename'
};
export default se;

View File

@@ -580,11 +580,11 @@ const DashboardData: FC = () => {
return (
<Dialog open={sensor !== undefined} onClose={() => setSensor(undefined)}>
<DialogTitle>
{LL.EDIT()} {LL.TEMP_SENSORS()}
{LL.EDIT()} {LL.TEMP_SENSOR()}
</DialogTitle>
<DialogContent dividers>
<Box color="warning.main" p={0} pl={0} pr={0} mt={0} mb={2}>
<Typography variant="body2">Sensor ID {sensor.id}</Typography>
<Typography variant="body2">Sensor ID: {sensor.id}</Typography>
</Box>
<Grid container spacing={1}>
<Grid item>
@@ -1034,7 +1034,7 @@ const DashboardData: FC = () => {
return (
<Dialog open={analog !== undefined} onClose={() => setAnalog(undefined)}>
<DialogTitle>
{LL.EDIT()} {LL.ANALOG_SENSORS()}
{LL.EDIT()} {LL.ANALOG_SENSOR()}
</DialogTitle>
<DialogContent dividers>
<Grid container spacing={2}>

View File

@@ -338,9 +338,10 @@ const SettingsApplication: FC = () => {
size="small"
select
>
<MenuItem value="en">English (en)</MenuItem>
<MenuItem value="de">Deutsch (de)</MenuItem>
<MenuItem value="nl">Nederlands (nl)</MenuItem>
<MenuItem value="en">English (EN)</MenuItem>
<MenuItem value="de">Deutsch (DE)</MenuItem>
<MenuItem value="nl">Nederlands (NL)</MenuItem>
<MenuItem value="se">Svenska (SE)</MenuItem>
</ValidatedTextField>
</Box>
{data.led_gpio !== 0 && (

View File

@@ -284,7 +284,7 @@ const SettingsCustomization: FC = () => {
return (
<>
<Box mb={2} color="warning.main">
<Typography variant="body2">{LL.CUSTOMIZATIONS_HELP_1()}:</Typography>
<Typography variant="body2">{LL.CUSTOMIZATIONS_HELP_1()}</Typography>
<Typography variant="body2">
<OptionIcon type="favorite" isSet={true} />={LL.CUSTOMIZATIONS_HELP_2()}&nbsp;&nbsp;
<OptionIcon type="readonly" isSet={true} />={LL.CUSTOMIZATIONS_HELP_3()}&nbsp;&nbsp;
@@ -558,10 +558,10 @@ const SettingsCustomization: FC = () => {
);
};
const renderEditEntity = () => (
<Dialog open={!!deviceEntity} onClose={() => setDeviceEntity(undefined)}>
{deviceEntity && (
<>
const renderEditEntity = () => {
if (deviceEntity) {
return (
<Dialog open={!!deviceEntity} onClose={() => setDeviceEntity(undefined)}>
<DialogTitle>{LL.RENAME() + ' ' + LL.ENTITY_NAME()}</DialogTitle>
<DialogContent dividers>
<Box color="warning.main" p={0} pl={0} pr={0} mt={0} mb={2}>
@@ -599,10 +599,10 @@ const SettingsCustomization: FC = () => {
{LL.SAVE()}
</Button>
</DialogActions>
</>
)}
</Dialog>
);
</Dialog>
);
}
};
return (
<SectionContent title={LL.USER_CUSTOMIZATION()} titleGutter>

View File

@@ -22,8 +22,9 @@
#define EMSESP_LOCALE_EN "en"
#define EMSESP_LOCALE_DE "de"
#define EMSESP_LOCALE_NL "nl"
#define EMSESP_LOCALE_SE "se"
// translations are in order en, de
// translations are in order en, de,nl, se....
// if there is no translation, it will default to en
// General