diff --git a/interface/src/components/layout/LayoutMenu.tsx b/interface/src/components/layout/LayoutMenu.tsx
index b2d049e71..4989be1c2 100644
--- a/interface/src/components/layout/LayoutMenu.tsx
+++ b/interface/src/components/layout/LayoutMenu.tsx
@@ -32,8 +32,8 @@ const LayoutMenu: FC = () => {
)}
-
- {features.ntp && }
+
+ {features.ntp && }
{features.mqtt && }
{
return provision_mode === APProvisionMode.AP_MODE_ALWAYS || provision_mode === APProvisionMode.AP_MODE_DISCONNECTED;
};
@@ -29,6 +31,8 @@ const APSettingsForm: FC = () => {
update: APApi.updateAPSettings
});
+ const { LL } = useI18nContext();
+
const [fieldErrors, setFieldErrors] = useState();
const updateFormValue = updateValue(setData);
@@ -53,7 +57,7 @@ const APSettingsForm: FC = () => {
{
onChange={updateFormValue}
margin="normal"
>
-
-
-
+
+
+
{isAPEnabled(data) && (
<>
{
{
{
}
- label="Hide SSID"
+ label={LL.AP_HIDE_SSID()}
/>
{
type="submit"
onClick={validateAndSubmit}
>
- Save
+ {LL.SAVE()}
>
@@ -176,7 +180,7 @@ const APSettingsForm: FC = () => {
};
return (
-
+
{content()}
);
diff --git a/interface/src/framework/ap/APStatusForm.tsx b/interface/src/framework/ap/APStatusForm.tsx
index e0a99e3b2..e4589c836 100644
--- a/interface/src/framework/ap/APStatusForm.tsx
+++ b/interface/src/framework/ap/APStatusForm.tsx
@@ -11,6 +11,8 @@ import { APNetworkStatus, APStatus } from '../../types';
import { ButtonRow, FormLoader, SectionContent } from '../../components';
import { useRest } from '../../utils';
+import { useI18nContext } from '../../i18n/i18n-react';
+
export const apStatusHighlight = ({ status }: APStatus, theme: Theme) => {
switch (status) {
case APNetworkStatus.ACTIVE:
@@ -24,24 +26,26 @@ export const apStatusHighlight = ({ status }: APStatus, theme: Theme) => {
}
};
-export const apStatus = ({ status }: APStatus) => {
- switch (status) {
- case APNetworkStatus.ACTIVE:
- return 'Active';
- case APNetworkStatus.INACTIVE:
- return 'Inactive';
- case APNetworkStatus.LINGERING:
- return 'Lingering until idle';
- default:
- return 'Unknown';
- }
-};
-
const APStatusForm: FC = () => {
const { loadData, data, errorMessage } = useRest({ read: APApi.readAPStatus });
+ const { LL } = useI18nContext();
+
const theme = useTheme();
+ const apStatus = ({ status }: APStatus) => {
+ switch (status) {
+ case APNetworkStatus.ACTIVE:
+ return LL.ACTIVE();
+ case APNetworkStatus.INACTIVE:
+ return LL.INACTIVE();
+ case APNetworkStatus.LINGERING:
+ return 'Lingering until idle';
+ default:
+ return LL.UNKNOWN();
+ }
+ };
+
const content = () => {
if (!data) {
return ;
@@ -56,7 +60,7 @@ const APStatusForm: FC = () => {
-
+
@@ -87,7 +91,7 @@ const APStatusForm: FC = () => {
} variant="outlined" color="secondary" onClick={loadData}>
- Refresh
+ {LL.REFRESH()}
>
@@ -95,7 +99,7 @@ const APStatusForm: FC = () => {
};
return (
-
+
{content()}
);
diff --git a/interface/src/framework/ap/AccessPoint.tsx b/interface/src/framework/ap/AccessPoint.tsx
index 742db7b24..d90b645cc 100644
--- a/interface/src/framework/ap/AccessPoint.tsx
+++ b/interface/src/framework/ap/AccessPoint.tsx
@@ -8,8 +8,12 @@ import APStatusForm from './APStatusForm';
import APSettingsForm from './APSettingsForm';
import { RequireAdmin, RouterTabs, useLayoutTitle, useRouterTab } from '../../components';
+import { useI18nContext } from '../../i18n/i18n-react';
+
const AccessPoint: FC = () => {
- useLayoutTitle('Access Point');
+ const { LL } = useI18nContext();
+
+ useLayoutTitle(LL.ACCESS_POINT());
const authenticatedContext = useContext(AuthenticatedContext);
@@ -18,8 +22,12 @@ const AccessPoint: FC = () => {
return (
<>
-
-
+
+
} />
diff --git a/interface/src/framework/mqtt/Mqtt.tsx b/interface/src/framework/mqtt/Mqtt.tsx
index d44edb781..53ed3b44b 100644
--- a/interface/src/framework/mqtt/Mqtt.tsx
+++ b/interface/src/framework/mqtt/Mqtt.tsx
@@ -9,7 +9,11 @@ import { AuthenticatedContext } from '../../contexts/authentication';
import MqttStatusForm from './MqttStatusForm';
import MqttSettingsForm from './MqttSettingsForm';
+import { useI18nContext } from '../../i18n/i18n-react';
+
const Mqtt: FC = () => {
+ const { LL } = useI18nContext();
+
useLayoutTitle('MQTT');
const authenticatedContext = useContext(AuthenticatedContext);
@@ -18,8 +22,8 @@ const Mqtt: FC = () => {
return (
<>
-
-
+
+
} />
diff --git a/interface/src/framework/mqtt/MqttSettingsForm.tsx b/interface/src/framework/mqtt/MqttSettingsForm.tsx
index 9997fb77b..8cc8c0064 100644
--- a/interface/src/framework/mqtt/MqttSettingsForm.tsx
+++ b/interface/src/framework/mqtt/MqttSettingsForm.tsx
@@ -17,12 +17,16 @@ import { MqttSettings } from '../../types';
import { numberValue, updateValue, useRest } from '../../utils';
import * as MqttApi from '../../api/mqtt';
+import { useI18nContext } from '../../i18n/i18n-react';
+
const MqttSettingsForm: FC = () => {
const { loadData, saving, data, setData, saveData, errorMessage } = useRest({
read: MqttApi.readMqttSettings,
update: MqttApi.updateMqttSettings
});
+ const { LL } = useI18nContext();
+
const [fieldErrors, setFieldErrors] = useState();
const updateFormValue = updateValue(setData);
@@ -46,7 +50,7 @@ const MqttSettingsForm: FC = () => {
<>
}
- label="Enable MQTT"
+ label={LL.ENABLE_MQTT()}
/>
@@ -91,7 +95,7 @@ const MqttSettingsForm: FC = () => {
{
{
{
}
- label="Set Clean Session"
+ label={LL.MQTT_CLEAN_SESSION()}
/>
}
- label="Always use Retain Flag"
+ label={LL.MQTT_RETAIN_FLAG()}
/>
- Formatting
+ {LL.FORMATTING()}
{
margin="normal"
select
>
-
-
+
+
}
- label="Publish command output to a 'response' topic"
+ label={LL.MQTT_RESPONSE()}
/>
{!data.ha_enabled && (
}
- label="Publish single value topics on change"
+ label={LL.MQTT_PUBLISH_TEXT_1()}
/>
{data.publish_single && (
@@ -200,7 +204,7 @@ const MqttSettingsForm: FC = () => {
control={
}
- label="Publish to command topics (ioBroker)"
+ label={LL.MQTT_PUBLISH_TEXT_2()}
/>
)}
@@ -211,14 +215,14 @@ const MqttSettingsForm: FC = () => {
}
- label="Enable MQTT Discovery (Home Assistant, Domoticz)"
+ label={LL.MQTT_PUBLISH_TEXT_3()}
/>
{data.ha_enabled && (
{
)}
- Publish Intervals (0=auto)
+ {LL.MQTT_PUBLISH_INTERVALS()} (0=auto)
seconds
}}
@@ -253,7 +257,7 @@ const MqttSettingsForm: FC = () => {
seconds
}}
@@ -269,7 +273,7 @@ const MqttSettingsForm: FC = () => {
seconds
}}
@@ -285,7 +289,7 @@ const MqttSettingsForm: FC = () => {
seconds
}}
@@ -301,7 +305,7 @@ const MqttSettingsForm: FC = () => {
seconds
}}
@@ -320,7 +324,7 @@ const MqttSettingsForm: FC = () => {
InputProps={{
endAdornment: seconds
}}
- label="Default"
+ label={LL.DEFAULT()}
fullWidth
variant="outlined"
value={numberValue(data.publish_time_other)}
@@ -339,7 +343,7 @@ const MqttSettingsForm: FC = () => {
type="submit"
onClick={validateAndSubmit}
>
- Save
+ {LL.SAVE()}
>
@@ -347,7 +351,7 @@ const MqttSettingsForm: FC = () => {
};
return (
-
+
{content()}
);
diff --git a/interface/src/framework/mqtt/MqttStatusForm.tsx b/interface/src/framework/mqtt/MqttStatusForm.tsx
index b39fff4c7..a889ec0fa 100644
--- a/interface/src/framework/mqtt/MqttStatusForm.tsx
+++ b/interface/src/framework/mqtt/MqttStatusForm.tsx
@@ -11,6 +11,8 @@ import { MqttStatus, MqttDisconnectReason } from '../../types';
import * as MqttApi from '../../api/mqtt';
import { useRest } from '../../utils';
+import { useI18nContext } from '../../i18n/i18n-react';
+
export const mqttStatusHighlight = ({ enabled, connected }: MqttStatus, theme: Theme) => {
if (!enabled) {
return theme.palette.info.main;
@@ -29,44 +31,46 @@ export const mqttPublishHighlight = ({ mqtt_fails }: MqttStatus, theme: Theme) =
return theme.palette.error.main;
};
-export const mqttStatus = ({ enabled, connected }: MqttStatus) => {
- if (!enabled) {
- return 'Not enabled';
- }
- if (connected) {
- return 'Connected';
- }
- return 'Disconnected';
-};
-
-export const disconnectReason = ({ disconnect_reason }: MqttStatus) => {
- switch (disconnect_reason) {
- case MqttDisconnectReason.TCP_DISCONNECTED:
- return 'TCP disconnected';
- case MqttDisconnectReason.MQTT_UNACCEPTABLE_PROTOCOL_VERSION:
- return 'Unacceptable protocol version';
- case MqttDisconnectReason.MQTT_IDENTIFIER_REJECTED:
- return 'Client ID rejected';
- case MqttDisconnectReason.MQTT_SERVER_UNAVAILABLE:
- return 'Server unavailable';
- case MqttDisconnectReason.MQTT_MALFORMED_CREDENTIALS:
- return 'Malformed credentials';
- case MqttDisconnectReason.MQTT_NOT_AUTHORIZED:
- return 'Not authorized';
- case MqttDisconnectReason.ESP8266_NOT_ENOUGH_SPACE:
- return 'Device out of memory';
- case MqttDisconnectReason.TLS_BAD_FINGERPRINT:
- return 'Server fingerprint invalid';
- default:
- return 'Unknown';
- }
-};
-
const MqttStatusForm: FC = () => {
const { loadData, data, errorMessage } = useRest({ read: MqttApi.readMqttStatus });
+ const { LL } = useI18nContext();
+
const theme = useTheme();
+ const mqttStatus = ({ enabled, connected }: MqttStatus) => {
+ if (!enabled) {
+ return LL.NOT_ENABLED();
+ }
+ if (connected) {
+ return LL.CONNECTED();
+ }
+ return LL.DISCONNECTED();
+ };
+
+ const disconnectReason = ({ disconnect_reason }: MqttStatus) => {
+ switch (disconnect_reason) {
+ case MqttDisconnectReason.TCP_DISCONNECTED:
+ return 'TCP disconnected';
+ case MqttDisconnectReason.MQTT_UNACCEPTABLE_PROTOCOL_VERSION:
+ return 'Unacceptable protocol version';
+ case MqttDisconnectReason.MQTT_IDENTIFIER_REJECTED:
+ return 'Client ID rejected';
+ case MqttDisconnectReason.MQTT_SERVER_UNAVAILABLE:
+ return 'Server unavailable';
+ case MqttDisconnectReason.MQTT_MALFORMED_CREDENTIALS:
+ return 'Malformed credentials';
+ case MqttDisconnectReason.MQTT_NOT_AUTHORIZED:
+ return 'Not authorized';
+ case MqttDisconnectReason.ESP8266_NOT_ENOUGH_SPACE:
+ return 'Device out of memory';
+ case MqttDisconnectReason.TLS_BAD_FINGERPRINT:
+ return 'Server fingerprint invalid';
+ default:
+ return 'Unknown';
+ }
+ };
+
const content = () => {
if (!data) {
return ;
@@ -89,7 +93,7 @@ const MqttStatusForm: FC = () => {
-
+
>
);
@@ -102,7 +106,7 @@ const MqttStatusForm: FC = () => {
-
+
>
@@ -118,14 +122,14 @@ const MqttStatusForm: FC = () => {
-
+
{data.enabled && renderConnectionStatus()}
} variant="outlined" color="secondary" onClick={loadData}>
- Refresh
+ {LL.REFRESH()}
>
@@ -133,7 +137,7 @@ const MqttStatusForm: FC = () => {
};
return (
-
+
{content()}
);
diff --git a/interface/src/framework/ntp/NTPSettingsForm.tsx b/interface/src/framework/ntp/NTPSettingsForm.tsx
index 557239625..f538b87d9 100644
--- a/interface/src/framework/ntp/NTPSettingsForm.tsx
+++ b/interface/src/framework/ntp/NTPSettingsForm.tsx
@@ -12,12 +12,16 @@ import * as NTPApi from '../../api/ntp';
import { selectedTimeZone, timeZoneSelectItems, TIME_ZONES } from './TZ';
import { NTP_SETTINGS_VALIDATOR } from '../../validators/ntp';
+import { useI18nContext } from '../../i18n/i18n-react';
+
const NTPSettingsForm: FC = () => {
const { loadData, saving, data, setData, saveData, errorMessage } = useRest({
read: NTPApi.readNTPSettings,
update: NTPApi.updateNTPSettings
});
+ const { LL } = useI18nContext();
+
const updateFormValue = updateValue(setData);
const [fieldErrors, setFieldErrors] = useState();
@@ -49,7 +53,7 @@ const NTPSettingsForm: FC = () => {
<>
}
- label="Enable NTP"
+ label={LL.ENABLE_NTP()}
/>
{
{
margin="normal"
select
>
-
+
{timeZoneSelectItems()}
@@ -84,7 +88,7 @@ const NTPSettingsForm: FC = () => {
type="submit"
onClick={validateAndSubmit}
>
- Save
+ {LL.SAVE()}
>
@@ -92,7 +96,7 @@ const NTPSettingsForm: FC = () => {
};
return (
-
+
{content()}
);
diff --git a/interface/src/framework/ntp/NTPStatusForm.tsx b/interface/src/framework/ntp/NTPStatusForm.tsx
index 1b9855e69..316731cab 100644
--- a/interface/src/framework/ntp/NTPStatusForm.tsx
+++ b/interface/src/framework/ntp/NTPStatusForm.tsx
@@ -49,19 +49,6 @@ export const ntpStatusHighlight = ({ status }: NTPStatus, theme: Theme) => {
}
};
-export const ntpStatus = ({ status }: NTPStatus) => {
- switch (status) {
- case NTPSyncStatus.NTP_DISABLED:
- return 'Disabled';
- case NTPSyncStatus.NTP_INACTIVE:
- return 'Inactive';
- case NTPSyncStatus.NTP_ACTIVE:
- return 'Active';
- default:
- return 'Unknown';
- }
-};
-
const NTPStatusForm: FC = () => {
const { loadData, data, errorMessage } = useRest({ read: NTPApi.readNTPStatus });
const [localTime, setLocalTime] = useState('');
@@ -81,6 +68,19 @@ const NTPStatusForm: FC = () => {
const theme = useTheme();
+ const ntpStatus = ({ status }: NTPStatus) => {
+ switch (status) {
+ case NTPSyncStatus.NTP_DISABLED:
+ return LL.DISABLED();
+ case NTPSyncStatus.NTP_INACTIVE:
+ return LL.INACTIVE();
+ case NTPSyncStatus.NTP_ACTIVE:
+ return LL.ACTIVE();
+ default:
+ return LL.UNKNOWN();
+ }
+ };
+
const configureTime = async () => {
setProcessing(true);
try {
@@ -100,11 +100,11 @@ const NTPStatusForm: FC = () => {
const renderSetTimeDialog = () => {
return (
@@ -149,7 +149,7 @@ const NTPStatusForm: FC = () => {
-
+
{isNtpEnabled(data) && (
@@ -171,7 +171,7 @@ const NTPStatusForm: FC = () => {
-
+
@@ -180,7 +180,7 @@ const NTPStatusForm: FC = () => {
-
+
@@ -188,7 +188,7 @@ const NTPStatusForm: FC = () => {
} variant="outlined" color="secondary" onClick={loadData}>
- Refresh
+ {LL.REFRESH()}
@@ -196,7 +196,7 @@ const NTPStatusForm: FC = () => {
}>
- Set Time
+ {LL.SET_TIME()}
@@ -208,7 +208,7 @@ const NTPStatusForm: FC = () => {
};
return (
-
+
{content()}
);
diff --git a/interface/src/framework/ntp/NetworkTime.tsx b/interface/src/framework/ntp/NetworkTime.tsx
index b58fdbb9d..7e34e46c2 100644
--- a/interface/src/framework/ntp/NetworkTime.tsx
+++ b/interface/src/framework/ntp/NetworkTime.tsx
@@ -13,7 +13,7 @@ import { useI18nContext } from '../../i18n/i18n-react';
const NetworkTime: FC = () => {
const { LL } = useI18nContext();
- useLayoutTitle(LL.NETWORK_TIME());
+ useLayoutTitle("NTP");
const authenticatedContext = useContext(AuthenticatedContext);
const { routerTab } = useRouterTab();
@@ -21,8 +21,8 @@ const NetworkTime: FC = () => {
return (
<>
-
-
+
+
} />
diff --git a/interface/src/framework/security/GenerateToken.tsx b/interface/src/framework/security/GenerateToken.tsx
index 75296c946..6b28a0d72 100644
--- a/interface/src/framework/security/GenerateToken.tsx
+++ b/interface/src/framework/security/GenerateToken.tsx
@@ -19,6 +19,8 @@ import { MessageBox } from '../../components';
import * as SecurityApi from '../../api/security';
import { Token } from '../../types';
+import { useI18nContext } from '../../i18n/i18n-react';
+
interface GenerateTokenProps {
username?: string;
onClose: () => void;
@@ -28,15 +30,17 @@ const GenerateToken: FC = ({ username, onClose }) => {
const [token, setToken] = useState();
const open = !!username;
+ const { LL } = useI18nContext();
+
const { enqueueSnackbar } = useSnackbar();
const getToken = useCallback(async () => {
try {
setToken((await SecurityApi.generateToken(username)).data);
} catch (error: unknown) {
- enqueueSnackbar(extractErrorMessage(error, 'Problem generating token'), { variant: 'error' });
+ enqueueSnackbar(extractErrorMessage(error, LL.PROBLEM_UPDATING()), { variant: 'error' });
}
- }, [username, enqueueSnackbar]);
+ }, [username, enqueueSnackbar, LL]);
useEffect(() => {
if (open) {
@@ -46,16 +50,11 @@ const GenerateToken: FC = ({ username, onClose }) => {
return (
diff --git a/interface/src/framework/security/ManageUsersForm.tsx b/interface/src/framework/security/ManageUsersForm.tsx
index c7b9324b8..827a5f5d8 100644
--- a/interface/src/framework/security/ManageUsersForm.tsx
+++ b/interface/src/framework/security/ManageUsersForm.tsx
@@ -20,6 +20,8 @@ import { createUserValidator } from '../../validators';
import { useRest } from '../../utils';
import { AuthenticatedContext } from '../../contexts/authentication';
+import { useI18nContext } from '../../i18n/i18n-react';
+
import GenerateToken from './GenerateToken';
import UserForm from './UserForm';
@@ -34,9 +36,11 @@ const ManageUsersForm: FC = () => {
const [generatingToken, setGeneratingToken] = useState();
const authenticatedContext = useContext(AuthenticatedContext);
+ const { LL } = useI18nContext();
+
const table_theme = useTheme({
Table: `
- --data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) 90px 120px;
+ --data-table-library_grid-template-columns: repeat(1, minmax(0, 1fr)) 120px 120px;
`,
BaseRow: `
font-size: 14px;
@@ -136,8 +140,8 @@ const ManageUsersForm: FC = () => {
<>
- USERNAME
- IS ADMIN
+ {LL.USERNAME()}
+ {LL.IS_ADMIN()}
@@ -169,9 +173,7 @@ const ManageUsersForm: FC = () => {
)}
- {noAdminConfigured() && (
-
- )}
+ {noAdminConfigured() && }
@@ -183,14 +185,14 @@ const ManageUsersForm: FC = () => {
type="submit"
onClick={onSubmit}
>
- Save
+ {LL.SAVE()}
} variant="outlined" color="secondary" onClick={createUser}>
- Add
+ {LL.ADD()}
@@ -210,7 +212,7 @@ const ManageUsersForm: FC = () => {
};
return (
-
+
{content()}
);
diff --git a/interface/src/framework/security/Security.tsx b/interface/src/framework/security/Security.tsx
index 1615c8e76..3c5ca85ee 100644
--- a/interface/src/framework/security/Security.tsx
+++ b/interface/src/framework/security/Security.tsx
@@ -19,8 +19,8 @@ const Security: FC = () => {
return (
<>
-
-
+
+
} />
diff --git a/interface/src/framework/security/SecuritySettingsForm.tsx b/interface/src/framework/security/SecuritySettingsForm.tsx
index 0a300a3a2..1d2c65baa 100644
--- a/interface/src/framework/security/SecuritySettingsForm.tsx
+++ b/interface/src/framework/security/SecuritySettingsForm.tsx
@@ -11,7 +11,11 @@ import { SECURITY_SETTINGS_VALIDATOR, validate } from '../../validators';
import { updateValue, useRest } from '../../utils';
import { AuthenticatedContext } from '../../contexts/authentication';
+import { useI18nContext } from '../../i18n/i18n-react';
+
const SecuritySettingsForm: FC = () => {
+ const { LL } = useI18nContext();
+
const [fieldErrors, setFieldErrors] = useState();
const { loadData, saving, data, setData, saveData, errorMessage } = useRest({
read: SecurityApi.readSecuritySettings,
@@ -42,7 +46,7 @@ const SecuritySettingsForm: FC = () => {
{
/>
@@ -63,7 +67,7 @@ const SecuritySettingsForm: FC = () => {
type="submit"
onClick={validateAndSubmit}
>
- Save
+ {LL.SAVE()}
>
@@ -71,7 +75,7 @@ const SecuritySettingsForm: FC = () => {
};
return (
-
+
{content()}
);
diff --git a/interface/src/framework/security/UserForm.tsx b/interface/src/framework/security/UserForm.tsx
index 4a82f08a9..7a8f0d105 100644
--- a/interface/src/framework/security/UserForm.tsx
+++ b/interface/src/framework/security/UserForm.tsx
@@ -11,6 +11,8 @@ import { User } from '../../types';
import { updateValue } from '../../utils';
import { validate } from '../../validators';
+import { useI18nContext } from '../../i18n/i18n-react';
+
interface UserFormProps {
creating: boolean;
validator: Schema;
@@ -23,6 +25,8 @@ interface UserFormProps {
}
const UserForm: FC = ({ creating, validator, user, setUser, onDoneEditing, onCancelEditing }) => {
+ const { LL } = useI18nContext();
+
const updateFormValue = updateValue(setUser);
const [fieldErrors, setFieldErrors] = useState();
const open = !!user;
@@ -49,12 +53,14 @@ const UserForm: FC = ({ creating, validator, user, setUser, onDon