From 73e9daed05dcb8ce64a6d19706a24dd3a93a4c70 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Wed, 6 May 2020 15:03:15 -0700 Subject: [PATCH] dep updates (fe) --- frontend/devices/__tests__/reducer_test.ts | 2 + .../__tests__/board_type_test.tsx | 10 -- .../components/fbos_settings/board_type.tsx | 17 +-- .../__tests__/edit_fe_form_test.tsx | 5 +- .../__tests__/images_filter_menu_test.tsx | 122 +++++++++++++++--- .../map/layers/images/image_filter_menu.tsx | 91 +++++++++---- .../map/layers/spread/spread_layer.tsx | 2 +- .../points/__tests__/create_points_test.tsx | 8 +- .../farm_designer/points/create_points.tsx | 2 +- .../points/point_edit_actions.tsx | 6 +- frontend/farmware/index.tsx | 2 +- .../front_page/__tests__/front_page_test.tsx | 2 + .../__tests__/laptop_splash_test.tsx | 10 ++ frontend/regimens/index.tsx | 2 +- frontend/sequences/sequences.tsx | 2 +- package.json | 22 ++-- 16 files changed, 210 insertions(+), 95 deletions(-) create mode 100644 frontend/front_page/__tests__/laptop_splash_test.tsx diff --git a/frontend/devices/__tests__/reducer_test.ts b/frontend/devices/__tests__/reducer_test.ts index 5efd63e14..22ae27a46 100644 --- a/frontend/devices/__tests__/reducer_test.ts +++ b/frontend/devices/__tests__/reducer_test.ts @@ -1,3 +1,5 @@ +jest.mock("../../redux/store", () => ({ store: jest.fn() })); + import { botReducer, initialState } from "../reducer"; import { Actions } from "../../constants"; import { ControlPanelState, BotState } from "../interfaces"; diff --git a/frontend/devices/components/fbos_settings/__tests__/board_type_test.tsx b/frontend/devices/components/fbos_settings/__tests__/board_type_test.tsx index bc13219bc..4eee54d11 100644 --- a/frontend/devices/components/fbos_settings/__tests__/board_type_test.tsx +++ b/frontend/devices/components/fbos_settings/__tests__/board_type_test.tsx @@ -43,16 +43,6 @@ describe("", () => { expect(wrapper.text()).toContain("Farmduino"); }); - it("sets sending status", () => { - const wrapper = mount(); - expect(wrapper.state().sending).toBeFalsy(); - const p = fakeProps(); - p.sourceFbosConfig = () => ({ value: true, consistent: false }); - wrapper.setProps(p); - wrapper.mount(); - expect(wrapper.state().sending).toBeTruthy(); - }); - it("calls updateConfig", () => { const p = fakeProps(); const wrapper = mount(); diff --git a/frontend/devices/components/fbos_settings/board_type.tsx b/frontend/devices/components/fbos_settings/board_type.tsx index ccf459341..61af67f57 100644 --- a/frontend/devices/components/fbos_settings/board_type.tsx +++ b/frontend/devices/components/fbos_settings/board_type.tsx @@ -13,17 +13,7 @@ import { Highlight } from "../maybe_highlight"; import { DeviceSetting } from "../../../constants"; import { DevSettings } from "../../../account/dev/dev_support"; -interface BoardTypeState { sending: boolean } - -export class BoardType extends React.Component { - state = { - sending: this.sending - }; - - UNSAFE_componentWillReceiveProps() { - this.setState({ sending: this.sending }); - } - +export class BoardType extends React.Component { get sending() { return !this.props.sourceFbosConfig("firmware_hardware").consistent; } @@ -39,15 +29,14 @@ export class BoardType extends React.Component { if (selectedItem && isFwHardwareValue(firmware_hardware)) { info(t("Sending firmware configuration..."), t("Sending")); this.props.dispatch(updateConfig({ firmware_hardware })); - this.setState({ sending: true }); this.forceUpdate(); } } FirmwareSelection = () => diff --git a/frontend/farm_designer/farm_events/__tests__/edit_fe_form_test.tsx b/frontend/farm_designer/farm_events/__tests__/edit_fe_form_test.tsx index ff37f8017..ee67ac0bb 100644 --- a/frontend/farm_designer/farm_events/__tests__/edit_fe_form_test.tsx +++ b/frontend/farm_designer/farm_events/__tests__/edit_fe_form_test.tsx @@ -545,7 +545,10 @@ describe("", () => { const fakeProps = (): RepeatFormProps => ({ isRegimen: false, fieldGet: jest.fn(key => - "" + ({ endDate: "2017-07-26" } as FarmEventViewModel)[key]), + "" + ({ + endDate: "2017-07-26", endTime: "08:57", + startDate: "2017-07-25", startTime: "08:57" + } as FarmEventViewModel)[key]), fieldSet: jest.fn(), timeSettings: fakeTimeSettings(), }); diff --git a/frontend/farm_designer/map/layers/images/__tests__/images_filter_menu_test.tsx b/frontend/farm_designer/map/layers/images/__tests__/images_filter_menu_test.tsx index c040e80d1..efef4c2aa 100644 --- a/frontend/farm_designer/map/layers/images/__tests__/images_filter_menu_test.tsx +++ b/frontend/farm_designer/map/layers/images/__tests__/images_filter_menu_test.tsx @@ -1,24 +1,30 @@ -import * as React from "react"; -import { ImageFilterMenu, ImageFilterMenuProps } from "../image_filter_menu"; -import { shallow, mount } from "enzyme"; +jest.mock("../../../../../api/crud", () => ({ + edit: jest.fn(), + save: jest.fn(), +})); + import { fakeWebAppConfig, } from "../../../../../__test_support__/fake_state/resources"; -import { StringConfigKey } from "farmbot/dist/resources/configs/web_app"; -import { setWebAppConfigValue } from "../../../../../config_storage/actions"; -import { - fakeTimeSettings, -} from "../../../../../__test_support__/fake_time_settings"; - const mockConfig = fakeWebAppConfig(); jest.mock("../../../../../resources/selectors", () => ({ getWebAppConfig: () => mockConfig, assertUuid: jest.fn(), })); -jest.mock("../../../../../config_storage/actions", () => ({ - setWebAppConfigValue: jest.fn(), -})); +import * as React from "react"; +import { ImageFilterMenu, ImageFilterMenuProps } from "../image_filter_menu"; +import { shallow, mount } from "enzyme"; + +import { StringConfigKey } from "farmbot/dist/resources/configs/web_app"; +import { + fakeTimeSettings, +} from "../../../../../__test_support__/fake_time_settings"; +import { edit, save } from "../../../../../api/crud"; +import { fakeState } from "../../../../../__test_support__/fake_state"; +import { + buildResourceIndex, +} from "../../../../../__test_support__/resource_index_builder"; describe("", () => { mockConfig.body.photo_filter_begin = ""; @@ -45,13 +51,19 @@ describe("", () => { ["endDate", "photo_filter_end", 2], ])("sets filter: %s", (filter, key, i) => { const p = fakeProps(); + const state = fakeState(); + const config = fakeWebAppConfig(); + state.resources = buildResourceIndex([config]); + p.dispatch = jest.fn(x => x(jest.fn(), () => state)); const wrapper = shallow(); wrapper.find("BlurableInput").at(i).simulate("commit", { currentTarget: { value: "2001-01-03" } }); expect(wrapper.instance().state[filter]).toEqual("2001-01-03"); - expect(setWebAppConfigValue) - .toHaveBeenCalledWith(key, "2001-01-03T00:00:00.000Z"); + expect(edit).toHaveBeenCalledWith(config, { + [key]: "2001-01-03T00:00:00.000Z" + }); + expect(save).toHaveBeenCalledWith(config.uuid); }); it.each<[ @@ -61,14 +73,64 @@ describe("", () => { ["endTime", "photo_filter_end", 3], ])("sets filter: %s", (filter, key, i) => { const p = fakeProps(); + const state = fakeState(); + const config = fakeWebAppConfig(); + state.resources = buildResourceIndex([config]); + p.dispatch = jest.fn(x => x(jest.fn(), () => state)); const wrapper = shallow(); wrapper.setState({ beginDate: "2001-01-03", endDate: "2001-01-03" }); wrapper.find("BlurableInput").at(i).simulate("commit", { currentTarget: { value: "05:00" } }); expect(wrapper.instance().state[filter]).toEqual("05:00"); - expect(setWebAppConfigValue) - .toHaveBeenCalledWith(key, "2001-01-03T05:00:00.000Z"); + expect(edit).toHaveBeenCalledWith(config, { + [key]: "2001-01-03T05:00:00.000Z" + }); + expect(save).toHaveBeenCalledWith(config.uuid); + }); + + it.each<[ + "beginDate" | "endDate", + "photo_filter_begin" | "photo_filter_end", + number + ]>([ + ["beginDate", "photo_filter_begin", 0], + ["endDate", "photo_filter_end", 2], + ])("unsets filter: %s", (filter, key, i) => { + const p = fakeProps(); + const state = fakeState(); + const config = fakeWebAppConfig(); + state.resources = buildResourceIndex([config]); + p.dispatch = jest.fn(x => x(jest.fn(), () => state)); + const wrapper = shallow(); + wrapper.setState({ beginDate: "2001-01-03", endDate: "2001-01-03" }); + wrapper.find("BlurableInput").at(i).simulate("commit", { + currentTarget: { value: "" } + }); + expect(wrapper.instance().state[filter]).toEqual(undefined); + // tslint:disable-next-line:no-null-keyword + expect(edit).toHaveBeenCalledWith(config, { [key]: null }); + expect(save).toHaveBeenCalledWith(config.uuid); + }); + + it.each<[ + "beginTime" | "endTime", number + ]>([ + ["beginTime", 1], + ["endTime", 3], + ])("doesn't set filter: %s", (filter, i) => { + const p = fakeProps(); + const state = fakeState(); + const config = fakeWebAppConfig(); + state.resources = buildResourceIndex([config]); + p.dispatch = jest.fn(x => x(jest.fn(), () => state)); + const wrapper = shallow(); + wrapper.find("BlurableInput").at(i).simulate("commit", { + currentTarget: { value: "05:00" } + }); + expect(wrapper.instance().state[filter]).toEqual("05:00"); + expect(edit).not.toHaveBeenCalled(); + expect(save).not.toHaveBeenCalled(); }); it("loads values from config", () => { @@ -83,14 +145,34 @@ describe("", () => { it("changes slider", () => { const p = fakeProps(); + const state = fakeState(); + const config = fakeWebAppConfig(); + state.resources = buildResourceIndex([config]); + p.dispatch = jest.fn(x => x(jest.fn(), () => state)); + p.getConfigValue = () => undefined; p.imageAgeInfo.newestDate = "2001-01-03T05:00:00.000Z"; const wrapper = shallow(); wrapper.instance().sliderChange(1); expect(wrapper.instance().state.slider).toEqual(1); - expect(setWebAppConfigValue) - .toHaveBeenCalledWith("photo_filter_begin", "2001-01-02T00:00:00.000Z"); - expect(setWebAppConfigValue) - .toHaveBeenCalledWith("photo_filter_end", "2001-01-03T00:00:00.000Z"); + expect(edit).toHaveBeenCalledWith(config, { + photo_filter_begin: "2001-01-02T00:00:00.000Z", + photo_filter_end: "2001-01-03T00:00:00.000Z", + }); + expect(save).toHaveBeenCalledWith(config.uuid); + }); + + it("doesn't update config", () => { + const p = fakeProps(); + const state = fakeState(); + state.resources = buildResourceIndex([]); + p.dispatch = jest.fn(x => x(jest.fn(), () => state)); + p.getConfigValue = () => 1; + p.imageAgeInfo.newestDate = "2001-01-03T05:00:00.000Z"; + const wrapper = shallow(); + wrapper.instance().sliderChange(1); + expect(wrapper.instance().state.slider).toEqual(1); + expect(edit).not.toHaveBeenCalled(); + expect(save).not.toHaveBeenCalled(); }); it("displays slider labels", () => { diff --git a/frontend/farm_designer/map/layers/images/image_filter_menu.tsx b/frontend/farm_designer/map/layers/images/image_filter_menu.tsx index 7357df513..3a988c8bc 100644 --- a/frontend/farm_designer/map/layers/images/image_filter_menu.tsx +++ b/frontend/farm_designer/map/layers/images/image_filter_menu.tsx @@ -1,9 +1,7 @@ import * as React from "react"; import { BlurableInput } from "../../../../ui/index"; import { offsetTime } from "../../../farm_events/edit_fe_form"; -import { - setWebAppConfigValue, GetWebAppConfigValue, -} from "../../../../config_storage/actions"; +import { GetWebAppConfigValue } from "../../../../config_storage/actions"; import moment from "moment"; import { formatDate, formatTime, @@ -11,8 +9,13 @@ import { import { Slider } from "@blueprintjs/core"; import { t } from "../../../../i18next_wrapper"; import { TimeSettings } from "../../../../interfaces"; +import { StringConfigKey } from "farmbot/dist/resources/configs/web_app"; +import { GetState } from "../../../../redux/interfaces"; +import { getWebAppConfig } from "../../../../resources/getters"; +import { edit, save } from "../../../../api/crud"; +import { isString, isUndefined } from "lodash"; -interface ImageFilterMenuState { +interface FullImageFilterMenuState { beginDate: string | undefined; beginTime: string | undefined; endDate: string | undefined; @@ -20,6 +23,8 @@ interface ImageFilterMenuState { slider: number; } +type ImageFilterMenuState = Partial; + export interface ImageFilterMenuProps { timeSettings: TimeSettings; dispatch: Function; @@ -28,26 +33,48 @@ export interface ImageFilterMenuProps { } export class ImageFilterMenu - extends React.Component> { - constructor(props: ImageFilterMenuProps) { - super(props); - this.state = {}; - } + extends React.Component { + state: ImageFilterMenuState = {}; - UNSAFE_componentWillMount() { - const { newestDate, toOldest } = this.props.imageAgeInfo; + componentDidMount() { const beginDatetime = this.props.getConfigValue("photo_filter_begin"); - this.setState({ - slider: toOldest + 1 - (beginDatetime - ? Math.abs(moment(beginDatetime.toString()) - .diff(moment(newestDate).clone(), "days")) : 0) - }); + if (isString(beginDatetime) || isUndefined(beginDatetime)) { + this.updateSliderState(beginDatetime); + } this.updateState(); } - UNSAFE_componentWillReceiveProps() { - this.updateState(); - } + updateSliderState = (begin: string | undefined) => { + const { newestDate, toOldest } = this.props.imageAgeInfo; + const offset = begin ? Math.abs(moment(begin.toString()) + .diff(moment(newestDate).clone(), "days")) : 0; + this.setState({ slider: toOldest + 1 - offset }); + }; + + setValues = (update: StringValueUpdate) => { + Object.entries(update).map(([key, value]) => { + switch (key) { + case "photo_filter_begin": + this.updateSliderState(value); + value + ? this.setState({ + beginDate: formatDate(value.toString(), this.props.timeSettings), + beginTime: formatTime(value.toString(), this.props.timeSettings), + }) + : this.setState({ beginDate: undefined, beginTime: undefined }); + break; + case "photo_filter_end": + value + ? this.setState({ + endDate: formatDate(value.toString(), this.props.timeSettings), + endTime: formatTime(value.toString(), this.props.timeSettings), + }) + : this.setState({ endDate: undefined, endTime: undefined }); + break; + } + }); + this.props.dispatch(setWebAppConfigValues(update)); + }; updateState = () => { const beginDatetime = this.props.getConfigValue("photo_filter_begin"); @@ -70,27 +97,27 @@ export class ImageFilterMenu const input = e.currentTarget.value; this.setState({ [datetime]: input }); const { beginDate, beginTime, endDate, endTime } = this.state; - const { dispatch, timeSettings } = this.props; + const { timeSettings } = this.props; let value = undefined; switch (datetime) { case "beginDate": value = offsetTime(input, beginTime || "00:00", timeSettings); - dispatch(setWebAppConfigValue("photo_filter_begin", value)); + this.setValues({ photo_filter_begin: value }); break; case "beginTime": if (beginDate) { value = offsetTime(beginDate, input, timeSettings); - dispatch(setWebAppConfigValue("photo_filter_begin", value)); + this.setValues({ photo_filter_begin: value }); } break; case "endDate": value = offsetTime(input, endTime || "00:00", timeSettings); - dispatch(setWebAppConfigValue("photo_filter_end", value)); + this.setValues({ photo_filter_end: value }); break; case "endTime": if (endDate) { value = offsetTime(endDate, input, timeSettings); - dispatch(setWebAppConfigValue("photo_filter_end", value)); + this.setValues({ photo_filter_end: value }); } break; } @@ -100,13 +127,12 @@ export class ImageFilterMenu sliderChange = (slider: number) => { const { newestDate, toOldest } = this.props.imageAgeInfo; this.setState({ slider }); - const { dispatch, timeSettings } = this.props; + const { timeSettings } = this.props; const calcDate = (day: number) => moment(newestDate).subtract(toOldest - day, "days").toISOString(); const begin = offsetTime(calcDate(slider - 1), "00:00", timeSettings); const end = offsetTime(calcDate(slider), "00:00", timeSettings); - dispatch(setWebAppConfigValue("photo_filter_begin", begin)); - dispatch(setWebAppConfigValue("photo_filter_end", end)); + this.setValues({ photo_filter_begin: begin, photo_filter_end: end }); } renderLabel = (day: number) => { @@ -191,3 +217,14 @@ export class ImageFilterMenu ; } } + +type StringValueUpdate = Partial>; + +const setWebAppConfigValues = (update: StringValueUpdate) => + (dispatch: Function, getState: GetState) => { + const webAppConfig = getWebAppConfig(getState().resources.index); + if (webAppConfig) { + dispatch(edit(webAppConfig, update)); + dispatch(save(webAppConfig.uuid)); + } + }; diff --git a/frontend/farm_designer/map/layers/spread/spread_layer.tsx b/frontend/farm_designer/map/layers/spread/spread_layer.tsx index b31b9f56b..f186f576d 100644 --- a/frontend/farm_designer/map/layers/spread/spread_layer.tsx +++ b/frontend/farm_designer/map/layers/spread/spread_layer.tsx @@ -73,7 +73,7 @@ export class SpreadCircle extends React.Component { state: SpreadCircleState = { spread: undefined }; - UNSAFE_componentWillMount = () => { + componentDidMount = () => { cachedCrop(this.props.plant.body.openfarm_slug) .then(({ spread }) => this.setState({ spread })); } diff --git a/frontend/farm_designer/points/__tests__/create_points_test.tsx b/frontend/farm_designer/points/__tests__/create_points_test.tsx index f3a4926ba..e900fa27e 100644 --- a/frontend/farm_designer/points/__tests__/create_points_test.tsx +++ b/frontend/farm_designer/points/__tests__/create_points_test.tsx @@ -78,12 +78,12 @@ describe("", () => { it("updates specific fields", () => { const p = fakeProps(); p.drawnPoint = FAKE_POINT; - const i = new CreatePoints(p); - i.updateValue("color")(inputEvent("cheerful hue")); - expect(i.props.drawnPoint).toBeTruthy(); + const wrapper = mount(); + wrapper.instance().updateValue("color")(inputEvent("cheerful hue")); + expect(wrapper.instance().props.drawnPoint).toBeTruthy(); const expected = cloneDeep(FAKE_POINT); expected.color = "cheerful hue"; - expect(i.props.dispatch).toHaveBeenCalledWith({ + expect(wrapper.instance().props.dispatch).toHaveBeenCalledWith({ type: "SET_DRAWN_POINT_DATA", payload: expected, }); diff --git a/frontend/farm_designer/points/create_points.tsx b/frontend/farm_designer/points/create_points.tsx index 417b9ed1d..e5196e4be 100644 --- a/frontend/farm_designer/points/create_points.tsx +++ b/frontend/farm_designer/points/create_points.tsx @@ -122,7 +122,7 @@ export class RawCreatePoints }); } - UNSAFE_componentWillMount() { + componentDidMount() { this.loadDefaultPoint(); } diff --git a/frontend/farm_designer/points/point_edit_actions.tsx b/frontend/farm_designer/points/point_edit_actions.tsx index 123e338a6..bf0d92699 100644 --- a/frontend/farm_designer/points/point_edit_actions.tsx +++ b/frontend/farm_designer/points/point_edit_actions.tsx @@ -73,11 +73,11 @@ export const AdditionalWeedProperties = (props: AdditionalWeedPropertiesProps) = case "type": return
; case "created_by": - return + return {SOURCE_LOOKUP()[value || ""] || t("unknown")} ; case "removal_method": - return + return
{REMOVAL_METHODS.map(method =>
@@ -93,7 +93,7 @@ export const AdditionalWeedProperties = (props: AdditionalWeedPropertiesProps) =
; default: - return + return {value || ""} ; } diff --git a/frontend/farmware/index.tsx b/frontend/farmware/index.tsx index 751d8b558..858ba1175 100644 --- a/frontend/farmware/index.tsx +++ b/frontend/farmware/index.tsx @@ -124,7 +124,7 @@ export class RawFarmwarePage extends React.Component { return isBotOnline(this.props.syncStatus, this.props.botToMqttStatus); } - UNSAFE_componentWillMount() { + componentDidMount() { if (window.innerWidth > 450) { this.props.dispatch({ type: Actions.SELECT_FARMWARE, diff --git a/frontend/front_page/__tests__/front_page_test.tsx b/frontend/front_page/__tests__/front_page_test.tsx index 5a672c6bc..63ee8fe9d 100644 --- a/frontend/front_page/__tests__/front_page_test.tsx +++ b/frontend/front_page/__tests__/front_page_test.tsx @@ -26,6 +26,8 @@ jest.mock("../../api", () => ({ } })); +jest.mock("../laptop_splash", () => ({ LaptopSplash: () =>
})); + import * as React from "react"; import { mount, shallow } from "enzyme"; import { FrontPage, setField, PartialFormEvent } from "../front_page"; diff --git a/frontend/front_page/__tests__/laptop_splash_test.tsx b/frontend/front_page/__tests__/laptop_splash_test.tsx new file mode 100644 index 000000000..00547ecd5 --- /dev/null +++ b/frontend/front_page/__tests__/laptop_splash_test.tsx @@ -0,0 +1,10 @@ +import * as React from "react"; +import { shallow } from "enzyme"; +import { LaptopSplash } from "../laptop_splash"; + +describe("", () => { + it("renders", () => { + const wrapper = shallow(); + expect(wrapper.find("video").length).toEqual(1); + }); +}); diff --git a/frontend/regimens/index.tsx b/frontend/regimens/index.tsx index 14b2f2e72..5d70fba5d 100644 --- a/frontend/regimens/index.tsx +++ b/frontend/regimens/index.tsx @@ -28,7 +28,7 @@ export const RegimenBackButton = (props: RegimenBackButtonProps) => { }; export class RawRegimens extends React.Component { - UNSAFE_componentWillMount() { + componentDidMount() { if (!this.props.current) { setActiveRegimenByName(); } } diff --git a/frontend/sequences/sequences.tsx b/frontend/sequences/sequences.tsx index 05cf74823..0f91f8bfe 100644 --- a/frontend/sequences/sequences.tsx +++ b/frontend/sequences/sequences.tsx @@ -28,7 +28,7 @@ export const SequenceBackButton = (props: SequenceBackButtonProps) => { }; export class RawSequences extends React.Component { - UNSAFE_componentWillMount() { + componentDidMount() { if (!this.props.sequence) { setActiveSequenceByName(); } } diff --git a/package.json b/package.json index c17885701..de510f06e 100644 --- a/package.json +++ b/package.json @@ -24,16 +24,16 @@ "author": "farmbot.io", "license": "MIT", "dependencies": { - "@babel/core": "7.9.0", - "@blueprintjs/core": "3.26.0", - "@blueprintjs/datetime": "3.16.1", - "@blueprintjs/select": "3.12.2", + "@babel/core": "7.9.6", + "@blueprintjs/core": "3.26.1", + "@blueprintjs/datetime": "3.17.0", + "@blueprintjs/select": "3.12.3", "@types/enzyme": "3.10.5", "@types/jest": "25.2.1", "@types/lodash": "4.14.150", "@types/markdown-it": "10.0.1", "@types/moxios": "0.4.9", - "@types/node": "13.13.4", + "@types/node": "13.13.5", "@types/promise-timeout": "1.3.0", "@types/react": "16.9.34", "@types/react-color": "3.0.1", @@ -51,21 +51,21 @@ "lodash": "4.17.15", "markdown-it": "10.0.0", "markdown-it-emoji": "1.4.0", - "moment": "2.24.0", + "moment": "2.25.3", "moxios": "0.4.0", "mqtt": "4.0.0", - "npm": "6.14.4", + "npm": "6.14.5", "parcel-bundler": "1.12.4", "promise-timeout": "1.3.0", "raf": "3.4.1", "react": "16.13.1", "react-addons-test-utils": "15.6.2", - "react-color": "2.18.0", + "react-color": "2.18.1", "react-dom": "16.13.1", "react-joyride": "2.2.1", "react-redux": "7.2.0", "react-test-renderer": "16.13.1", - "react-transition-group": "4.3.0", + "react-transition-group": "4.4.1", "redux": "4.0.5", "redux-immutable-state-invariant": "2.1.0", "redux-thunk": "2.3.0", @@ -78,8 +78,8 @@ "which": "2.0.2" }, "devDependencies": { - "jest": "25.4.0", - "jest-cli": "25.4.0", + "jest": "25.5.4", + "jest-cli": "25.5.4", "jest-junit": "10.0.0", "jest-skipped-reporter": "0.0.5", "jshint": "2.11.0",