diff --git a/frontend/__test_support__/resource_index_builder.ts b/frontend/__test_support__/resource_index_builder.ts index 8ebca58f6..1008249be 100644 --- a/frontend/__test_support__/resource_index_builder.ts +++ b/frontend/__test_support__/resource_index_builder.ts @@ -17,7 +17,8 @@ import { MessageType } from "../sequences/interfaces"; const DEFAULT_DEVICE_BODY: TaggedDevice["body"] = { "id": 415, "name": "wispy-firefly-846", - "tz_offset_hrs": 0 + "tz_offset_hrs": 0, + "ota_hour": 3 }; export function fakeDevice(body: Partial = {}): diff --git a/frontend/api/__tests__/crud_malformed_data_tests.ts b/frontend/api/__tests__/crud_malformed_data_tests.ts index bf7e88221..314dca810 100644 --- a/frontend/api/__tests__/crud_malformed_data_tests.ts +++ b/frontend/api/__tests__/crud_malformed_data_tests.ts @@ -33,7 +33,8 @@ describe("refresh()", () => { "name": "summer-pond-726", "timezone": "America/Chicago", "last_saw_api": "2017-08-30T20:42:35.854Z", - "tz_offset_hrs": 0 + "tz_offset_hrs": 0, + "ota_hour": 3 }, }; diff --git a/frontend/api/__tests__/crud_success_tests.ts b/frontend/api/__tests__/crud_success_tests.ts index c8f6a4787..636aecbd2 100644 --- a/frontend/api/__tests__/crud_success_tests.ts +++ b/frontend/api/__tests__/crud_success_tests.ts @@ -31,6 +31,7 @@ describe("successful refresh()", () => { "body": { "id": 6, "name": "summer-pond-726", + "ota_hour": 3, "timezone": "America/Chicago", "last_saw_api": "2017-08-30T20:42:35.854Z", "tz_offset_hrs": 0 diff --git a/frontend/devices/components/__tests__/farmbot_os_settings_test.tsx b/frontend/devices/components/__tests__/farmbot_os_settings_test.tsx index 9233969b5..5ed4600fb 100644 --- a/frontend/devices/components/__tests__/farmbot_os_settings_test.tsx +++ b/frontend/devices/components/__tests__/farmbot_os_settings_test.tsx @@ -28,7 +28,12 @@ describe("", () => { }); const fakeProps = (): FarmbotOsProps => ({ - deviceAccount: fakeResource("Device", { id: 0, name: "", tz_offset_hrs: 0 }), + deviceAccount: fakeResource("Device", { + id: 0, + name: "", + ota_hour: 3, + tz_offset_hrs: 0 + }), diagnostics: [], dispatch: jest.fn(), bot, diff --git a/frontend/devices/components/fbos_settings/__tests__/last_seen_row_test.tsx b/frontend/devices/components/fbos_settings/__tests__/last_seen_row_test.tsx index d0b8ad20f..091867dac 100644 --- a/frontend/devices/components/fbos_settings/__tests__/last_seen_row_test.tsx +++ b/frontend/devices/components/fbos_settings/__tests__/last_seen_row_test.tsx @@ -13,7 +13,8 @@ describe("", () => { id: 1, name: "foo", last_saw_api: "", - tz_offset_hrs: 0 + tz_offset_hrs: 0, + ota_hour: 3 }); const props = (): LastSeenProps => ({ diff --git a/frontend/devices/components/fbos_settings/fbos_details.tsx b/frontend/devices/components/fbos_settings/fbos_details.tsx index d4c95198c..c84c5f08c 100644 --- a/frontend/devices/components/fbos_settings/fbos_details.tsx +++ b/frontend/devices/components/fbos_settings/fbos_details.tsx @@ -13,6 +13,7 @@ import moment from "moment"; import { timeFormatString } from "../../../util"; import { TimeSettings } from "../../../interfaces"; import { StringConfigKey } from "farmbot/dist/resources/configs/fbos"; +import { OtaTimeSelector, changeOtaHour } from "./ota_time_selector"; /** Return an indicator color for the given temperature (C). */ export const colorFromTemp = (temp: number | undefined): string => { @@ -279,6 +280,9 @@ export function FbosDetails(props: FbosDetailsProps) { + {last_ota_checkup &&

{t("Last checked for updates")}: {reformatDatetime(last_ota_checkup, props.timeSettings)}

} {last_ota &&

{t("Last updated")}: diff --git a/frontend/devices/components/fbos_settings/ota_time_selector/index.tsx b/frontend/devices/components/fbos_settings/ota_time_selector/index.tsx new file mode 100644 index 000000000..bb820a544 --- /dev/null +++ b/frontend/devices/components/fbos_settings/ota_time_selector/index.tsx @@ -0,0 +1,58 @@ +import { DropDownItem, FBSelect } from "../../../../ui"; +import React from "react"; +import { t } from "../../../../i18next_wrapper"; +import { TaggedDevice } from "farmbot"; +import { edit, save } from "../../../../api/crud"; + +const OTA_TIMES: Record = { + 0: { label: "Midnight", value: 0 }, + 1: { label: "1 AM", value: 1 }, + 2: { label: "2 AM", value: 2 }, + 3: { label: "3 AM", value: 3 }, + 4: { label: "4 AM", value: 4 }, + 5: { label: "5 AM", value: 5 }, + 6: { label: "6 AM", value: 6 }, + 7: { label: "7 AM", value: 7 }, + 8: { label: "8 AM", value: 8 }, + 9: { label: "9 AM", value: 9 }, + 10: { label: "10 AM", value: 10 }, + 11: { label: "11 AM", value: 11 }, + 12: { label: "Noon", value: 12 }, + 13: { label: "1 PM", value: 13 }, + 14: { label: "2 PM", value: 14 }, + 15: { label: "3 PM", value: 15 }, + 16: { label: "4 PM", value: 16 }, + 17: { label: "5 PM", value: 17 }, + 18: { label: "6 PM", value: 18 }, + 19: { label: "7 PM", value: 19 }, + 20: { label: "8 PM", value: 20 }, + 21: { label: "9 PM", value: 21 }, + 22: { label: "10 PM", value: 22 }, + 23: { label: "11 PM", value: 23 }, +}; + +const DEFAULT_HOUR = OTA_TIMES[3]; + +interface OtaTimeSelectorProps { + onChange(hour24: number): void; + value: number; +} + +export const changeOtaHour = + (dispatch: Function, device: TaggedDevice) => + (ota_hour: number) => { + dispatch(edit(device, { ota_hour })); + dispatch(save(device.uuid)); + }; +/** Label and toggle button for opting in to FBOS beta releases. */ +export const OtaTimeSelector = ({ onChange, value }: OtaTimeSelectorProps): JSX.Element => { + return

+ + onChange(ddi.value as number)} + list={Object.values(OTA_TIMES)} /> +
; +}; diff --git a/package.json b/package.json index 5d9e6b976..51e16b0d0 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "coveralls": "3.0.7", "enzyme": "3.10.0", "enzyme-adapter-react-16": "1.15.1", - "farmbot": "8.3.0-rc6", + "farmbot": "8.3.0", "i18next": "19.0.0", "install": "0.13.0", "lodash": "4.17.15",