From 464b730cd85fc917652a5112c266f17885fbc497 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Fri, 7 Feb 2020 15:05:16 -0800 Subject: [PATCH] groups updates --- ...230135_add_show_zones_to_web_app_config.rb | 8 + ...ditional_mocks.ts => additional_mocks.tsx} | 7 + frontend/__test_support__/fake_html_events.ts | 36 +++ frontend/__test_support__/fake_input_event.ts | 7 - .../__test_support__/fake_state/resources.ts | 3 +- .../{unmock_i18next.ts => mock_i18next.ts} | 0 frontend/__tests__/error_boundary_test.tsx | 2 + .../connectivity/__tests__/ping_mqtt_test.ts | 2 - frontend/constants.ts | 32 ++- frontend/css/farm_designer/farm_designer.scss | 17 +- .../farm_designer/farm_designer_panels.scss | 108 ++++++++ frontend/css/inputs.scss | 2 +- .../__tests__/boot_sequence_selector_test.tsx | 12 +- .../hardware_settings/pin_guard.tsx | 3 +- .../components/hardware_settings/zero_row.tsx | 3 +- frontend/devices/interfaces.ts | 3 +- .../__tests__/designer_panel_test.tsx | 7 + .../__tests__/farm_designer_test.tsx | 5 +- .../__tests__/panel_header_test.tsx | 2 +- .../farm_designer/__tests__/reducer_test.ts | 4 +- .../__tests__/state_to_props_test.tsx | 8 +- frontend/farm_designer/designer_panel.tsx | 11 +- .../map_state_to_props_add_edit_test.ts | 19 +- frontend/farm_designer/index.tsx | 11 +- frontend/farm_designer/interfaces.ts | 14 +- .../map/__tests__/actions_test.ts | 2 +- .../map/__tests__/garden_map_test.tsx | 53 +++- frontend/farm_designer/map/actions.ts | 5 +- .../__tests__/selection_box_actions_test.tsx | 60 ++++- .../map/background/selection_box_actions.tsx | 52 +++- frontend/farm_designer/map/garden_map.tsx | 110 ++++++-- frontend/farm_designer/map/interfaces.ts | 8 +- .../plants/__tests__/garden_plant_test.tsx | 9 +- .../plants/__tests__/plant_layer_test.tsx | 9 +- .../map/layers/plants/garden_plant.tsx | 7 +- .../map/layers/plants/plant_layer.tsx | 11 +- .../points/__tests__/point_layer_test.tsx | 30 ++- .../map/layers/points/point_layer.tsx | 6 +- .../spread/__tests__/spread_layer_test.tsx | 57 ++-- .../map/layers/spread/spread_layer.tsx | 4 +- .../zones/__tests__/zones_layer_test.tsx | 86 ++++++ .../map/layers/zones/__tests__/zones_test.tsx | 165 ++++++++++++ .../farm_designer/map/layers/zones/zones.tsx | 161 +++++++++++ .../map/layers/zones/zones_layer.tsx | 31 +++ .../__tests__/garden_map_legend_test.tsx | 1 + .../map/legend/garden_map_legend.tsx | 5 + frontend/farm_designer/map/util.ts | 3 +- .../plants/__tests__/add_plant_test.tsx | 37 +-- .../__tests__/map_state_to_props_test.ts | 18 +- .../__tests__/plant_inventory_item_test.tsx | 41 ++- .../plants/__tests__/plant_inventory_test.tsx | 18 +- .../plants/grid/__tests__/grid_input_test.tsx | 11 +- .../plants/map_state_to_props.tsx | 40 +-- .../farm_designer/plants/plant_inventory.tsx | 4 +- .../plants/plant_inventory_item.tsx | 52 ++-- .../farm_designer/plants/select_plants.tsx | 4 +- .../point_groups/__tests__/actions_test.ts | 37 ++- .../__tests__/fetch_group_from_url_test.ts | 26 -- .../__tests__/group_detail_active_test.tsx | 45 ++-- .../__tests__/group_detail_test.tsx | 51 +++- .../__tests__/group_inventory_item_test.tsx | 40 ++- .../__tests__/group_list_panel_test.tsx | 30 ++- .../__tests__/group_order_visual_test.tsx | 25 +- .../point_groups/__tests__/paths_test.tsx | 98 +++++-- .../__tests__/point_group_item_test.tsx | 134 ++++++---- .../point_group_sort_selector_test.tsx | 40 ++- .../farm_designer/point_groups/actions.ts | 51 ++-- .../criteria/__tests__/add_test.tsx | 252 ++++++++++++++++++ .../criteria/__tests__/apply_test.ts | 116 ++++++++ .../criteria/__tests__/component_test.tsx | 64 +++++ .../criteria/__tests__/edit_test.ts | 133 +++++++++ .../criteria/__tests__/presets_test.tsx | 56 ++++ .../criteria/__tests__/show_test.tsx | 199 ++++++++++++++ .../point_groups/criteria/add.tsx | 215 +++++++++++++++ .../point_groups/criteria/apply.ts | 57 ++++ .../point_groups/criteria/component.tsx | 74 +++++ .../point_groups/criteria/edit.ts | 70 +++++ .../point_groups/criteria/index.tsx | 6 + .../point_groups/criteria/interfaces.ts | 81 ++++++ .../point_groups/criteria/presets.tsx | 58 ++++ .../point_groups/criteria/show.tsx | 212 +++++++++++++++ .../point_groups/group_detail.tsx | 61 ++--- .../point_groups/group_detail_active.tsx | 98 ++++--- .../point_groups/group_inventory_item.tsx | 9 +- .../point_groups/group_list_panel.tsx | 13 +- .../point_groups/group_order_visual.tsx | 35 ++- frontend/farm_designer/point_groups/paths.tsx | 36 +-- .../point_groups/point_group_item.tsx | 64 +++-- .../point_group_sort_selector.tsx | 30 +-- .../points/__tests__/create_points_test.tsx | 2 +- .../points/__tests__/point_inventory_test.tsx | 22 +- .../points/__tests__/weeds_inventory_test.tsx | 8 +- frontend/farm_designer/points/point_info.tsx | 4 +- .../farm_designer/points/point_inventory.tsx | 8 +- frontend/farm_designer/points/weeds_edit.tsx | 4 +- .../farm_designer/points/weeds_inventory.tsx | 8 +- frontend/farm_designer/reducer.ts | 15 +- frontend/farm_designer/state_to_props.ts | 17 +- .../zones/__tests__/edit_zone_test.tsx | 28 +- .../zones/__tests__/zones_inventory_test.tsx | 63 +++++ frontend/farm_designer/zones/edit_zone.tsx | 24 +- .../farm_designer/zones/zones_inventory.tsx | 31 ++- .../images/__tests__/image_flipper_test.tsx | 1 - .../__tests__/image_workspace_test.tsx | 7 +- frontend/folders/__tests__/actions_test.ts | 11 +- .../front_page/__tests__/front_page_test.tsx | 25 +- .../open_farm/__tests__/cached_crop_test.ts | 49 +++- frontend/open_farm/cached_crop.ts | 24 +- .../__tests__/password_reset_test.tsx | 6 +- .../__tests__/regimen_name_input_test.tsx | 2 +- .../regimens/list/__tests__/index_test.tsx | 2 +- frontend/resources/selectors_by_id.ts | 18 +- frontend/resources/tagged_resources.ts | 5 +- ...cation_form_coordinate_input_boxes_test.ts | 2 +- .../locals_list/location_form_list.ts | 16 +- .../__tests__/tile_move_absolute_test.tsx | 2 +- .../step_tiles/mark_as/resource_list.ts | 6 +- .../__tests__/lua_part_test.tsx | 6 +- frontend/session_keys.ts | 1 + .../tos_update/__tests__/component_test.tsx | 24 +- frontend/ui/__tests__/tooltip_test.tsx | 3 +- frontend/ui/__tests__/widget_test.ts | 4 +- frontend/ui/delete_button.tsx | 2 +- frontend/util/util.ts | 2 - jest.config.js | 4 +- package.json | 2 +- 126 files changed, 3646 insertions(+), 754 deletions(-) create mode 100644 db/migrate/20200204230135_add_show_zones_to_web_app_config.rb rename frontend/__test_support__/{additional_mocks.ts => additional_mocks.tsx} (73%) create mode 100644 frontend/__test_support__/fake_html_events.ts delete mode 100644 frontend/__test_support__/fake_input_event.ts rename frontend/__test_support__/{unmock_i18next.ts => mock_i18next.ts} (100%) create mode 100644 frontend/farm_designer/map/layers/zones/__tests__/zones_layer_test.tsx create mode 100644 frontend/farm_designer/map/layers/zones/__tests__/zones_test.tsx create mode 100644 frontend/farm_designer/map/layers/zones/zones.tsx create mode 100644 frontend/farm_designer/map/layers/zones/zones_layer.tsx delete mode 100644 frontend/farm_designer/point_groups/__tests__/fetch_group_from_url_test.ts create mode 100644 frontend/farm_designer/point_groups/criteria/__tests__/add_test.tsx create mode 100644 frontend/farm_designer/point_groups/criteria/__tests__/apply_test.ts create mode 100644 frontend/farm_designer/point_groups/criteria/__tests__/component_test.tsx create mode 100644 frontend/farm_designer/point_groups/criteria/__tests__/edit_test.ts create mode 100644 frontend/farm_designer/point_groups/criteria/__tests__/presets_test.tsx create mode 100644 frontend/farm_designer/point_groups/criteria/__tests__/show_test.tsx create mode 100644 frontend/farm_designer/point_groups/criteria/add.tsx create mode 100644 frontend/farm_designer/point_groups/criteria/apply.ts create mode 100644 frontend/farm_designer/point_groups/criteria/component.tsx create mode 100644 frontend/farm_designer/point_groups/criteria/edit.ts create mode 100644 frontend/farm_designer/point_groups/criteria/index.tsx create mode 100644 frontend/farm_designer/point_groups/criteria/interfaces.ts create mode 100644 frontend/farm_designer/point_groups/criteria/presets.tsx create mode 100644 frontend/farm_designer/point_groups/criteria/show.tsx diff --git a/db/migrate/20200204230135_add_show_zones_to_web_app_config.rb b/db/migrate/20200204230135_add_show_zones_to_web_app_config.rb new file mode 100644 index 000000000..f4a23279b --- /dev/null +++ b/db/migrate/20200204230135_add_show_zones_to_web_app_config.rb @@ -0,0 +1,8 @@ +class AddShowZonesToWebAppConfig < ActiveRecord::Migration[6.0] + def change + add_column :web_app_configs, + :show_zones, + :boolean, + default: false + end +end diff --git a/frontend/__test_support__/additional_mocks.ts b/frontend/__test_support__/additional_mocks.tsx similarity index 73% rename from frontend/__test_support__/additional_mocks.ts rename to frontend/__test_support__/additional_mocks.tsx index 6d80eed8a..6b2b3046d 100644 --- a/frontend/__test_support__/additional_mocks.ts +++ b/frontend/__test_support__/additional_mocks.tsx @@ -1,3 +1,5 @@ +import * as React from "react"; + jest.mock("browser-speech", () => ({ talk: jest.fn(), })); @@ -16,3 +18,8 @@ window.location = { pathname: "", href: "", hash: "", search: "", hostname: "", origin: "", port: "", protocol: "", host: "", }; + +jest.mock("../error_boundary", () => ({ + // tslint:disable-next-line:no-any + ErrorBoundary: (p: any) =>
{p.children}
, +})); diff --git a/frontend/__test_support__/fake_html_events.ts b/frontend/__test_support__/fake_html_events.ts new file mode 100644 index 000000000..e0aecfe1e --- /dev/null +++ b/frontend/__test_support__/fake_html_events.ts @@ -0,0 +1,36 @@ +import { DeepPartial } from "redux"; + +type DomEvent = React.SyntheticEvent; +export const inputEvent = (value: string, name?: string): DomEvent => { + const event: DeepPartial = { currentTarget: { value, name } }; + return event as DomEvent; +}; + +type ChangeEvent = React.ChangeEvent; +export const changeEvent = (value: string): ChangeEvent => { + const event: DeepPartial = { currentTarget: { value } }; + return event as ChangeEvent; +}; + +type IMGEvent = React.SyntheticEvent; +export const imgEvent = (): IMGEvent => { + const event: DeepPartial = { + currentTarget: { + getAttribute: jest.fn(), + setAttribute: jest.fn(), + } + }; + return event as IMGEvent; +}; + +type FormEvent = React.FormEvent; +export const formEvent = (): FormEvent => { + const event: Partial = { preventDefault: jest.fn() }; + return event as FormEvent; +}; + +type DragEvent = React.DragEvent; +export const dragEvent = (key: string): DragEvent => { + const event: DeepPartial = { dataTransfer: { getData: () => key } }; + return event as DragEvent; +}; diff --git a/frontend/__test_support__/fake_input_event.ts b/frontend/__test_support__/fake_input_event.ts deleted file mode 100644 index bd742a7ca..000000000 --- a/frontend/__test_support__/fake_input_event.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { DeepPartial } from "redux"; - -type DomEvent = React.SyntheticEvent; -export const inputEvent = (value: string): DomEvent => { - const event: DeepPartial = { currentTarget: { value } }; - return event as DomEvent; -}; diff --git a/frontend/__test_support__/fake_state/resources.ts b/frontend/__test_support__/fake_state/resources.ts index 9a545bee4..641cba1bb 100644 --- a/frontend/__test_support__/fake_state/resources.ts +++ b/frontend/__test_support__/fake_state/resources.ts @@ -316,6 +316,7 @@ export function fakeWebAppConfig(): TaggedWebAppConfig { show_historic_points: false, time_format_24_hour: false, show_pins: false, + show_zones: false, disable_emergency_unlock_confirmation: false, map_size_x: 2900, map_size_y: 1400, @@ -459,7 +460,7 @@ export function fakePointGroup(): TaggedPointGroup { sort_type: "xy_ascending", point_ids: [], criteria: { - day: { op: ">", days: 0 }, + day: { op: "<", days: 0 }, number_eq: {}, number_gt: {}, number_lt: {}, diff --git a/frontend/__test_support__/unmock_i18next.ts b/frontend/__test_support__/mock_i18next.ts similarity index 100% rename from frontend/__test_support__/unmock_i18next.ts rename to frontend/__test_support__/mock_i18next.ts diff --git a/frontend/__tests__/error_boundary_test.tsx b/frontend/__tests__/error_boundary_test.tsx index 224731b7e..6de0190cd 100644 --- a/frontend/__tests__/error_boundary_test.tsx +++ b/frontend/__tests__/error_boundary_test.tsx @@ -1,3 +1,5 @@ +jest.unmock("../error_boundary"); + jest.mock("../util/errors.ts", () => ({ catchErrors: jest.fn() })); import * as React from "react"; diff --git a/frontend/connectivity/__tests__/ping_mqtt_test.ts b/frontend/connectivity/__tests__/ping_mqtt_test.ts index 9e0de13a1..ea00a23cb 100644 --- a/frontend/connectivity/__tests__/ping_mqtt_test.ts +++ b/frontend/connectivity/__tests__/ping_mqtt_test.ts @@ -4,8 +4,6 @@ jest.mock("../index", () => ({ dispatchQosStart: jest.fn(), pingOK: jest.fn() })); -const mockTimestamp = 0; -jest.mock("../../util", () => ({ timestamp: () => mockTimestamp })); import { readPing, diff --git a/frontend/constants.ts b/frontend/constants.ts index 8617b8829..71388071f 100644 --- a/frontend/constants.ts +++ b/frontend/constants.ts @@ -572,12 +572,6 @@ export namespace Content { export const CONFIRM_PLANT_DELETION = trim(`Show a confirmation dialog when deleting a plant.`); - export const SORT_DESCRIPTION = - trim(`When executing a sequence over a Group of locations, FarmBot will - travel to each group member in the order of the chosen sort method. - If the random option is chosen, FarmBot will travel in a random order - every time, so the ordering shown below will only be representative.`); - // Device export const NOT_HTTPS = trim(`WARNING: Sending passwords via HTTP:// is not secure.`); @@ -824,6 +818,20 @@ export namespace Content { trim(`You haven't made any sequences or regimens yet. To add an event, first create a sequence or regimen.`); + // Groups + export const SORT_DESCRIPTION = + trim(`When executing a sequence over a Group of locations, FarmBot will + travel to each group member in the order of the chosen sort method. + If the random option is chosen, FarmBot will travel in a random order + every time, so the ordering shown below will only be representative.`); + + export const CRITERIA_SELECTION_COUNT = + trim(`Criteria additions can only be removed by changing criteria. + Click and drag in the map to modify zone selection criteria. + Criteria will be applied at the time of sequence execution. The final + selection at that time may differ from the selection currently + displayed.`); + // Farmware export const NO_IMAGES_YET = trim(`You haven't yet taken any photos with your FarmBot. @@ -912,12 +920,12 @@ export namespace DiagnosticMessages { network, a firewall may be blocking port 5672. Ensure that the blue LED communications light on the FarmBot electronics box is illuminated.`); - export const WIFI_OR_CONFIG = trim(`Your browser is connected correctly, but - we have no recent record of FarmBot connecting to the internet. This usually - happens because of poor WiFi connectivity in the garden, a bad password during - configuration, a very long power outage, or blocked ports on FarmBot's local - network. Please refer IT staff to - https://software.farm.bot/docs/for-it-security-professionals`); + export const WIFI_OR_CONFIG = trim(`Your browser is connected correctly, + but we have no recent record of FarmBot connecting to the internet. + This usually happens because of poor WiFi connectivity in the garden, + a bad password during configuration, a very long power outage, or + blocked ports on FarmBot's local network. Please refer IT staff to + https://software.farm.bot/docs/for-it-security-professionals`); export const NO_WS_AVAILABLE = trim(`You are either offline, using a web browser that does not support WebSockets, or are behind a firewall that diff --git a/frontend/css/farm_designer/farm_designer.scss b/frontend/css/farm_designer/farm_designer.scss index 4a6529760..74d11b8af 100644 --- a/frontend/css/farm_designer/farm_designer.scss +++ b/frontend/css/farm_designer/farm_designer.scss @@ -213,7 +213,7 @@ .groups-list-wrapper { padding: 0.5em 0em; } - .groups-delete-btn { + .group-delete-btn { float: left; margin-top: 1em; } @@ -332,6 +332,21 @@ } } +.zones-layer { + [id*="zones-1D-"] { + stroke: $black; + stroke-width: 5; + } + [id*="zones-"] { + opacity: 0.1; + &.current { + opacity: 0.25; + fill: $white; + stroke: $white; + } + } +} + .virtual-bot-trail, .virtual-peripherals { pointer-events: none; diff --git a/frontend/css/farm_designer/farm_designer_panels.scss b/frontend/css/farm_designer/farm_designer_panels.scss index f00163816..a1867cc96 100644 --- a/frontend/css/farm_designer/farm_designer_panels.scss +++ b/frontend/css/farm_designer/farm_designer_panels.scss @@ -738,6 +738,114 @@ } } +.group-detail-panel { + .panel-content { + .group-criteria { + margin-top: 1rem; + .criteria-heading { + margin-top: 0; + } + .fb-button { + margin-top: 0.5rem; + } + .group-criteria-presets { + input[type="radio"] { + width: auto; + margin-right: 1rem; + } + p { + display: inline; + text-transform: uppercase; + } + } + .criteria-string, + .criteria-pointer-type, + .criteria-plant-status, + .criteria-slug { + margin-top: 1rem; + } + .location-criteria { + .row { + margin-top: 1rem; + p { + font-size: 1.4rem; + font-weight: bold; + } + label { + margin-top: 0; + } + } + } + .day-criteria { + p { + display: inline; + vertical-align: bottom; + } + } + .string-eq-criteria { + margin-top: 1rem; + .row { + margin-top: 1rem; + } + } + .number-eq-criteria, + .number-gt-lt-criteria { + margin-top: 1rem; + .row { + margin-top: 1rem; + } + p { + text-align: center; + margin-top: 0.5rem; + } + } + .expandable-header { + margin-top: 3rem; + } + } + .criteria-point-count-breakdown { + margin-bottom: 1rem; + .manual-group-member-count, + .criteria-group-member-count { + margin-left: 2rem; + div { + display: inline; + padding: 0.25rem; + font-size: 1.2rem; + border: 1px solid $panel_light_blue; + } + p { + display: inline; + margin-left: 1rem; + } + } + .criteria-group-member-count { + div { + border: 1px solid gray; + border-radius: 5px; + } + } + } + } +} + +.zone-info-panel { + .panel-content { + .location-criteria { + .row { + margin-top: 1rem; + p { + font-size: 1.4rem; + font-weight: bold; + } + label { + margin-top: 0; + } + } + } + } +} + .weeds-inventory-panel, .zones-inventory-panel, .groups-panel { diff --git a/frontend/css/inputs.scss b/frontend/css/inputs.scss index 4e5d9d508..e31b27443 100644 --- a/frontend/css/inputs.scss +++ b/frontend/css/inputs.scss @@ -95,9 +95,9 @@ select { } } &.disabled { + pointer-events: none; button { background: darken($white, 10%) !important; - pointer-events: none; } } } diff --git a/frontend/devices/components/fbos_settings/__tests__/boot_sequence_selector_test.tsx b/frontend/devices/components/fbos_settings/__tests__/boot_sequence_selector_test.tsx index 71b2b1abe..410b12931 100644 --- a/frontend/devices/components/fbos_settings/__tests__/boot_sequence_selector_test.tsx +++ b/frontend/devices/components/fbos_settings/__tests__/boot_sequence_selector_test.tsx @@ -1,7 +1,13 @@ -import { sequence2ddi, mapStateToProps, RawBootSequenceSelector } from "../boot_sequence_selector"; -import { fakeSequence, fakeFbosConfig } from "../../../../__test_support__/fake_state/resources"; +import { + sequence2ddi, mapStateToProps, RawBootSequenceSelector +} from "../boot_sequence_selector"; +import { + fakeSequence, fakeFbosConfig +} from "../../../../__test_support__/fake_state/resources"; import { fakeState } from "../../../../__test_support__/fake_state"; -import { buildResourceIndex } from "../../../../__test_support__/resource_index_builder"; +import { + buildResourceIndex +} from "../../../../__test_support__/resource_index_builder"; import React from "react"; import { mount } from "enzyme"; import { FBSelect } from "../../../../ui"; diff --git a/frontend/devices/components/hardware_settings/pin_guard.tsx b/frontend/devices/components/hardware_settings/pin_guard.tsx index 21222a8f0..9bd49c83b 100644 --- a/frontend/devices/components/hardware_settings/pin_guard.tsx +++ b/frontend/devices/components/hardware_settings/pin_guard.tsx @@ -24,7 +24,8 @@ export function PinGuard(props: PinGuardProps) { - +