message text t() and formatting improvements
parent
5b6c119e18
commit
45e42689da
|
@ -20,7 +20,7 @@ export class DeleteAccount extends
|
|||
<WidgetHeader title="Delete Account" />
|
||||
<WidgetBody>
|
||||
<div>
|
||||
{Content.ACCOUNT_DELETE_WARNING}
|
||||
{t(Content.ACCOUNT_DELETE_WARNING)}
|
||||
<br /><br />
|
||||
{t(`If you are sure you want to delete your account, type in
|
||||
your password below to continue.`)}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import * as React from "react";
|
||||
import { t } from "i18next";
|
||||
import { connect } from "react-redux";
|
||||
import { Settings, DeleteAccount, ChangePassword } from "./components";
|
||||
import { Props } from "./interfaces";
|
||||
|
@ -33,7 +34,7 @@ export class Account extends React.Component<Props, State> {
|
|||
onSave = () => this
|
||||
.props
|
||||
.dispatch(save(this.props.user.uuid))
|
||||
.then(() => success("saved"), updateNO);
|
||||
.then(() => success(t("saved")), updateNO);
|
||||
|
||||
render() {
|
||||
return <Page className="account">
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import * as React from "react";
|
||||
import * as React from "react";
|
||||
import { t } from "i18next";
|
||||
import { connect } from "react-redux";
|
||||
import * as _ from "lodash";
|
||||
import { init, error } from "farmbot-toastr";
|
||||
|
@ -11,21 +12,15 @@ import { ResourceName, TaggedUser } from "./resources/tagged_resources";
|
|||
import { selectAllLogs, maybeFetchUser } from "./resources/selectors";
|
||||
import { HotKeys } from "./hotkeys";
|
||||
import { ControlsPopup } from "./controls_popup";
|
||||
import { Content } from "./constants";
|
||||
|
||||
/** Remove 300ms delay on touch devices - https://github.com/ftlabs/fastclick */
|
||||
/** Remove 300ms delay on touch devices - https://github.com/ftlabs/fastclick */
|
||||
const fastClick = require("fastclick");
|
||||
fastClick.attach(document.body);
|
||||
|
||||
/** For the logger module */
|
||||
/** For the logger module */
|
||||
init();
|
||||
|
||||
/**
|
||||
* If the sync object takes more than 10s to load, the user will be granted
|
||||
* access into the app, but still warned.
|
||||
*/
|
||||
const TIMEOUT_MESSAGE = `App could not be fully loaded, we recommend you try
|
||||
refreshing the page.`;
|
||||
|
||||
interface AppProps {
|
||||
dispatch: Function;
|
||||
loaded: ResourceName[];
|
||||
|
@ -67,10 +62,14 @@ export class App extends React.Component<AppProps, {}> {
|
|||
_.intersection(this.props.loaded, MUST_LOAD).length);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the sync object takes more than 10s to load, the user will be granted
|
||||
* access into the app, but still warned.
|
||||
*/
|
||||
componentDidMount() {
|
||||
setTimeout(() => {
|
||||
if (!this.isLoaded) {
|
||||
error(TIMEOUT_MESSAGE, "Warning");
|
||||
error(t(Content.APP_LOAD_TIMEOUT_MESSAGE), t("Warning"));
|
||||
}
|
||||
}, 10000);
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ export function logout() {
|
|||
// In those cases, seeing a logout message may confuse the user.
|
||||
// To circumvent this, we must check if the user had a token.
|
||||
// If there was infact a token, we can safely show the message.
|
||||
if (Session.getAll()) { success("You have been logged out."); }
|
||||
if (Session.getAll()) { success(t("You have been logged out.")); }
|
||||
Session.clear();
|
||||
// Technically this is unreachable code:
|
||||
return {
|
||||
|
|
|
@ -255,9 +255,9 @@ export namespace Content {
|
|||
your FarmBot so that is goes back into configuration mode for pairing with
|
||||
another user account. When this happens, all of the data on your FarmBot
|
||||
will be overwritten with the new account's data. If the account is brand
|
||||
new, then FarmBot will become a blank slate.`;
|
||||
new, then FarmBot will become a blank slate.`.replace(/\s+/g, " ");
|
||||
|
||||
// Controls
|
||||
// Device
|
||||
export const FACTORY_RESET_WARNING =
|
||||
`Factory resetting your FarmBot will destroy all data on the device,
|
||||
revoking your FarmBot's abilily to connect to your web app account and your
|
||||
|
@ -265,14 +265,58 @@ export namespace Content {
|
|||
Configurator mode. Factory resetting your FarmBot will not affect any data
|
||||
or settings from your web app account, allowing you to do a complete restore
|
||||
to your device once it is back online and paired with your web app
|
||||
account.`;
|
||||
account.`.replace(/\s+/g, " ");
|
||||
|
||||
export const TIMEZONE_GUESS_BROWSER =
|
||||
`This account did not have a timezone set. Farmbot requires a timezone to
|
||||
operate. We have updated your timezone settings based on your browser.
|
||||
Please verify these settings in the device settings panel. Device sync is
|
||||
recommended.`.replace(/\s+/g, " ");
|
||||
|
||||
export const TIMEZONE_GUESS_UTC =
|
||||
`Warning: Farmbot could not guess your timezone. We have defaulted your
|
||||
timezone to UTC, which is less than ideal for most users. Please select
|
||||
your timezone from the dropdown. Device sync is recommended.`.replace(/\s+/g, " ");
|
||||
|
||||
// Hardware Settings
|
||||
export const RESTORE_DEFAULT_HARDWARE_SETTINGS =
|
||||
`Restoring hardware parameter defaults will destroy the
|
||||
current settings, resetting them to default values.`.replace(/\s+/g, " ");
|
||||
|
||||
// App
|
||||
export const APP_LOAD_TIMEOUT_MESSAGE =
|
||||
`App could not be fully loaded, we recommend you try
|
||||
refreshing the page.`.replace(/\s+/g, " ");
|
||||
|
||||
export const MQTT_DISCONNECTED =
|
||||
`Your web browser is unable to connect to the message broker (MQTT).
|
||||
You might be behind a firewall or disconnected from the Internet. Check
|
||||
your network settings.`.replace(/\s+/g, " ");
|
||||
|
||||
export const MALFORMED_MESSAGE_REC_UPGRADE =
|
||||
`FarmBot sent a malformed message. You may need to upgrade
|
||||
FarmBot OS. Please upgrade FarmBot OS and log back in.`.replace(/\s+/g, " ");
|
||||
|
||||
// Experimental Warning
|
||||
export const EXPERIMENTAL_WARNING =
|
||||
`Warning! This is an EXPERIMENTAL feature. This feature may be broken and may
|
||||
break or otherwise hinder your usage of the rest of the app. This feature may
|
||||
disappear or break at any time.`;
|
||||
disappear or break at any time.`.replace(/\s+/g, " ");
|
||||
|
||||
// Front Page
|
||||
export const TOS_UPDATE =
|
||||
`The terms of service have recently changed. You must accept the new
|
||||
terms of service to continue using the site.`.replace(/\s+/g, " ");
|
||||
|
||||
// Farm Events
|
||||
export const REGIMEN_TODAY_SKIPPED_ITEM_RISK =
|
||||
`You are scheduling a regimen to run today. Be aware that
|
||||
running a regimen too late in the day may result in skipped
|
||||
regimen tasks. Consider rescheduling this event to tomorrow if
|
||||
this is a concern.`.replace(/\s+/g, " ");
|
||||
|
||||
export const INVALID_RUN_TIME =
|
||||
`This Farm Event does not appear to have a valid run time.
|
||||
Perhaps you entered bad dates?`.replace(/\s+/g, " ");
|
||||
}
|
||||
|
||||
export enum Actions {
|
||||
|
|
|
@ -34,10 +34,10 @@ export class Peripherals extends React.Component<PeripheralsProps, PeripheralSta
|
|||
if (allAreSmall) {
|
||||
this.props.dispatch(saveAll(this.props.peripherals, this.toggle));
|
||||
} else {
|
||||
error("Pin numbers must be less than 1000.");
|
||||
error(t("Pin numbers must be less than 1000."));
|
||||
}
|
||||
} else {
|
||||
error("Pin numbers are required and must be positive and unique.");
|
||||
error(t("Pin numbers are required and must be positive and unique."));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ import { getDeviceAccountSettings } from "../resources/selectors";
|
|||
import { TaggedDevice } from "../resources/tagged_resources";
|
||||
import { versionOK } from "./reducer";
|
||||
import { oneOf, HttpData } from "../util";
|
||||
import { Actions } from "../constants";
|
||||
import { Actions, Content } from "../constants";
|
||||
import { mcuParamValidator } from "./update_interceptor";
|
||||
|
||||
const ON = 1, OFF = 0;
|
||||
|
@ -130,7 +130,7 @@ export function sync(): Thunk {
|
|||
.controller_version) {
|
||||
badVersion();
|
||||
} else {
|
||||
info("FarmBot is not connected.", "Disconnected", "red");
|
||||
info(t("FarmBot is not connected."), t("Disconnected"), "red");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -178,7 +178,7 @@ export function save(input: TaggedDevice) {
|
|||
return axios
|
||||
.put(API.current.devicePath, input.body)
|
||||
.then((resp: HttpData<User>) => dispatch({ type: "SAVE_DEVICE_OK", payload: resp.data }))
|
||||
.catch(resp => error("Error saving device settings."));
|
||||
.catch(resp => error(t("Error saving device settings.")));
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -268,9 +268,7 @@ export function connectDevice(token: string): ConnectDeviceReturn {
|
|||
bot.on("online", () => dispatch(setMqttStatus(true)));
|
||||
bot.on("offline", () => {
|
||||
dispatch(setMqttStatus(false));
|
||||
error(t("Your web browser is unable to connect to the message broker " +
|
||||
"(MQTT). You might be behind a firewall or disconnected from the " +
|
||||
"Internet. Check your network settings."));
|
||||
error(t(Content.MQTT_DISCONNECTED));
|
||||
});
|
||||
return bot
|
||||
.connect()
|
||||
|
@ -313,8 +311,7 @@ export function connectDevice(token: string): ConnectDeviceReturn {
|
|||
let alreadyToldYou = false;
|
||||
bot.on("malformed", function () {
|
||||
if (!alreadyToldYou) {
|
||||
warning(t(`FarmBot sent a malformed message. You may need to upgrade
|
||||
FarmBot OS. Please upgrade FarmBot OS and log back in.`));
|
||||
warning(t(Content.MALFORMED_MESSAGE_REC_UPGRADE));
|
||||
alreadyToldYou = true;
|
||||
}
|
||||
});
|
||||
|
@ -413,7 +410,7 @@ export function setSyncStatus(payload: SyncStatus) {
|
|||
}
|
||||
|
||||
function badVersion() {
|
||||
info("You are running an old version of FarmBot OS.", "Please Update", "red");
|
||||
info(t("You are running an old version of FarmBot OS."), t("Please Update"), "red");
|
||||
}
|
||||
|
||||
export let setMqttStatus = (payload: boolean) => ({
|
||||
|
|
|
@ -4,6 +4,7 @@ import { DangerZoneProps } from "../interfaces";
|
|||
import { Row, Col } from "../../../ui/index";
|
||||
import { Header } from "./header";
|
||||
import { Collapse } from "@blueprintjs/core";
|
||||
import { Content } from "../../../constants";
|
||||
|
||||
export function DangerZone(props: DangerZoneProps) {
|
||||
|
||||
|
@ -25,8 +26,7 @@ export function DangerZone(props: DangerZoneProps) {
|
|||
</Col>
|
||||
<Col xs={6}>
|
||||
<p>
|
||||
{t(`Restoring hardware parameter defaults will destroy the
|
||||
current settings, resetting them to default values.`)}
|
||||
{t(Content.RESTORE_DEFAULT_HARDWARE_SETTINGS)}
|
||||
<br />
|
||||
<b>
|
||||
{t("Will reboot device.")}
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import { t } from "i18next";
|
||||
import * as _ from "lodash";
|
||||
import { Content } from "../../constants";
|
||||
/** Remove this in October 2017 - RC */
|
||||
const ONLY_ONCE = {
|
||||
need_to_talk: true
|
||||
|
@ -11,21 +13,14 @@ export function inferTimezone(current: string | undefined): string {
|
|||
const browserTime = maybeResolveTZ();
|
||||
if (browserTime) {
|
||||
if (ONLY_ONCE.need_to_talk) {
|
||||
alert("This account did not have a timezone set. " +
|
||||
"Farmbot requires a timezone to operate. " +
|
||||
"We have updated your timezone settings based on your browser. " +
|
||||
"Please verify these settings in the device settings panel. " +
|
||||
"Device sync is recommended.");
|
||||
alert(t(Content.TIMEZONE_GUESS_BROWSER));
|
||||
ONLY_ONCE.need_to_talk = false;
|
||||
}
|
||||
// WARNING SIDE EFFECTS!!!
|
||||
return browserTime;
|
||||
}
|
||||
if (ONLY_ONCE.need_to_talk) {
|
||||
alert("Warning: Farmbot could not guess your timezone. " +
|
||||
"We have defaulted your timezone to UTC, which is less than ideal for " +
|
||||
"most users. Please select your timezone from the dropdown. Device " +
|
||||
"sync is recommended.");
|
||||
alert(t(Content.TIMEZONE_GUESS_UTC));
|
||||
ONLY_ONCE.need_to_talk = false;
|
||||
}
|
||||
return "UTC";
|
||||
|
|
|
@ -35,6 +35,7 @@ import { TzWarning } from "./tz_warning";
|
|||
import { FarmEventRepeatForm } from "./farm_event_repeat_form";
|
||||
import { scheduleForFarmEvent } from "./calendar/scheduler";
|
||||
import { executableType } from "../util";
|
||||
import { Content } from "../../constants";
|
||||
|
||||
type FormEvent = React.SyntheticEvent<HTMLInputElement>;
|
||||
export const NEVER: TimeUnit = "never";
|
||||
|
@ -184,21 +185,17 @@ export class EditFEForm extends React.Component<EditFEProps, State> {
|
|||
if (nextRun) {
|
||||
// TODO: Internationalizing this will be a challenge.
|
||||
success(`This Farm Event will run ${nextRun.fromNow()}, but
|
||||
you must first SYNC YOUR DEVICE. If you do not sync, the event will\
|
||||
not run.`);
|
||||
you must first SYNC YOUR DEVICE. If you do not sync, the event will
|
||||
not run.`.replace(/\s+/g, " "));
|
||||
this.props.dispatch(maybeWarnAboutMissedTasks(frmEvnt, function () {
|
||||
alert(`You are scheduling a regimen to run today. Be aware that
|
||||
running a regimen too late in the day may result in skipped
|
||||
regimen tasks. Consider rescheduling this event to tomorrow if
|
||||
this is a concern.`.replace(/\s+/g, " "));
|
||||
alert(t(Content.REGIMEN_TODAY_SKIPPED_ITEM_RISK));
|
||||
}));
|
||||
} else {
|
||||
error(`This Farm Event does not appear to have a valid run time.
|
||||
Perhaps you entered bad dates?`);
|
||||
error(t(Content.INVALID_RUN_TIME));
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
error("Unable to save farm event.");
|
||||
error(t("Unable to save farm event."));
|
||||
this.setState({ specialStatusLocal: SpecialStatus.DIRTY });
|
||||
});
|
||||
}
|
||||
|
@ -267,7 +264,7 @@ export class EditFEForm extends React.Component<EditFEProps, State> {
|
|||
onClick={() => {
|
||||
this.dispatch(destroy(fe.uuid)).then(() => {
|
||||
history.push("/app/designer/farm_events");
|
||||
success("Deleted farm event.", "Deleted");
|
||||
success(t("Deleted farm event."), t("Deleted"));
|
||||
});
|
||||
}}>
|
||||
{t("Delete")}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import * as React from "react";
|
||||
import { t } from "i18next";
|
||||
import { EditPlantInfoProps } from "../interfaces";
|
||||
import { history } from "../../history";
|
||||
import { destroy } from "../../api/crud";
|
||||
|
@ -17,7 +18,7 @@ export abstract class PlantInfoBase extends
|
|||
destroy = (plantUUID: string) => {
|
||||
this.props.dispatch(destroy(plantUUID))
|
||||
.then(() => history.push("/app/designer/plants"))
|
||||
.catch(() => error("Could not delete plant.", "Error"));
|
||||
.catch(() => error(t("Could not delete plant."), t("Error")));
|
||||
}
|
||||
|
||||
fallback = () => {
|
||||
|
|
|
@ -59,7 +59,7 @@ export class FarmwarePanel extends React.Component<FWProps, Partial<FWState>> {
|
|||
.installFarmware(this.state.packageUrl)
|
||||
.then(() => this.setState({ packageUrl: "" }));
|
||||
} else {
|
||||
alert("Enter a URL");
|
||||
alert(t("Enter a URL"));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ export class Photos extends React.Component<PhotosProps, {}> {
|
|||
|
||||
takePhoto = () => {
|
||||
const ok = () => success(t("Processing now. Refresh page to see result."));
|
||||
const no = () => error("Error taking photo");
|
||||
const no = () => error(t("Error taking photo"));
|
||||
devices.current.takePhoto().then(ok, no);
|
||||
}
|
||||
|
||||
|
@ -58,8 +58,8 @@ export class Photos extends React.Component<PhotosProps, {}> {
|
|||
const img = this.props.currentImage || this.props.images[0];
|
||||
if (img && img.uuid) {
|
||||
this.props.dispatch(destroy(img.uuid))
|
||||
.then(() => success("Image Deleted.", "Success"))
|
||||
.catch(() => error("Could not delete image.", "Error"));
|
||||
.then(() => success(t("Image Deleted."), t("Success")))
|
||||
.catch(() => error(t("Could not delete image."), t("Error")));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ export class FrontPage extends React.Component<{}, Partial<FrontPageState>> {
|
|||
const data = { email };
|
||||
axios.post(API.current.passwordResetPath, data)
|
||||
.then(() => {
|
||||
success("Email has been sent.", "Forgot Password");
|
||||
success(t("Email has been sent."), t("Forgot Password"));
|
||||
this.setState({ forgotPassword: false });
|
||||
}).catch(error => {
|
||||
let errorMessage = prettyPrintApiErrors(error);
|
||||
|
@ -124,7 +124,7 @@ export class FrontPage extends React.Component<{}, Partial<FrontPageState>> {
|
|||
errorMessage =
|
||||
`That email address is not associated with an account.`;
|
||||
}
|
||||
log(errorMessage);
|
||||
log(t(errorMessage));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import { API } from "./api/index";
|
|||
import { AuthState } from "./auth/interfaces";
|
||||
import * as _ from "lodash";
|
||||
import { AxiosRequestConfig, AxiosResponse } from "axios";
|
||||
import { Content } from "./constants";
|
||||
|
||||
export function responseFulfilled(input: AxiosResponse): AxiosResponse {
|
||||
let method = input.config.method;
|
||||
|
@ -44,8 +45,7 @@ export function responseRejected(x: SafeError | undefined) {
|
|||
break;
|
||||
case 451:
|
||||
// DONT REFACTOR: I want to use alert() because it's blocking.
|
||||
alert(t("The terms of service have recently changed. You must " +
|
||||
"accept the new terms of service to continue using the site."));
|
||||
alert(t(Content.TOS_UPDATE));
|
||||
window.location.href = "/tos_update";
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import * as React from "react";
|
||||
import { t } from "i18next";
|
||||
import { SequenceBodyItem as Step } from "farmbot";
|
||||
import { error } from "farmbot-toastr";
|
||||
import { StepDragger, NULL_DRAGGER_ID } from "../../draggable/step_dragger";
|
||||
|
@ -12,7 +13,7 @@ const stepClick = (dispatch: Function, step: Step, seq: TaggedSequence | undefin
|
|||
if (seq) {
|
||||
pushStep(step, dispatch, seq);
|
||||
} else {
|
||||
error("Select a sequence first");
|
||||
error(t("Select a sequence first"));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue