From 6f484ab2e344c18dc71bd4ebb1027452da0adff5 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Mon, 20 Apr 2020 14:07:40 -0700 Subject: [PATCH] minor fixes --- frontend/__test_support__/mock_fbtoaster.ts | 1 + .../__tests__/connect_device/index_test.ts | 22 ++-- frontend/connectivity/connect_device.ts | 31 +++--- .../farm_designer/farm_designer_panels.scss | 36 ++++++- .../plants/__tests__/select_plants_test.tsx | 38 ++++++- .../farm_designer/plants/select_plants.tsx | 62 ++++++++--- frontend/toast/__tests__/fb_toast_test.ts | 30 +++++- .../__tests__/toast_internal_support_test.ts | 22 +++- frontend/toast/__tests__/toast_test.ts | 100 +++++++++++------- frontend/toast/fb_toast.ts | 9 +- frontend/toast/toast.ts | 72 +++++++++---- frontend/toast/toast_internal_support.ts | 12 ++- 12 files changed, 323 insertions(+), 112 deletions(-) diff --git a/frontend/__test_support__/mock_fbtoaster.ts b/frontend/__test_support__/mock_fbtoaster.ts index 7a36fb062..3c8b1498d 100644 --- a/frontend/__test_support__/mock_fbtoaster.ts +++ b/frontend/__test_support__/mock_fbtoaster.ts @@ -7,4 +7,5 @@ jest.mock("../toast/toast", () => ({ error: jest.fn(), warning: jest.fn(), busy: jest.fn(), + removeToast: jest.fn(), })); diff --git a/frontend/connectivity/__tests__/connect_device/index_test.ts b/frontend/connectivity/__tests__/connect_device/index_test.ts index 917cdc167..7ea48159d 100644 --- a/frontend/connectivity/__tests__/connect_device/index_test.ts +++ b/frontend/connectivity/__tests__/connect_device/index_test.ts @@ -37,7 +37,9 @@ import { getDevice } from "../../../device"; import { talk } from "browser-speech"; import { MessageType } from "../../../sequences/interfaces"; import { FbjsEventName } from "farmbot/dist/constants"; -import { info, error, success, warning, fun, busy } from "../../../toast/toast"; +import { + info, error, success, warning, fun, busy, removeToast, +} from "../../../toast/toast"; import { onLogs } from "../../log_handlers"; import { fakeState } from "../../../__test_support__/fake_state"; import { globalQueue } from "../../batch_queue"; @@ -177,7 +179,8 @@ describe("onOffline", () => { jest.resetAllMocks(); onOffline(); expect(dispatchNetworkDown).toHaveBeenCalledWith("user.mqtt", ANY_NUMBER); - expect(error).toHaveBeenCalledWith(Content.MQTT_DISCONNECTED); + expect(error).toHaveBeenCalledWith( + Content.MQTT_DISCONNECTED, "Error", "red", "offline"); }); }); @@ -186,13 +189,17 @@ describe("onOnline", () => { jest.resetAllMocks(); onOnline(); expect(dispatchNetworkUp).toHaveBeenCalledWith("user.mqtt", ANY_NUMBER); + expect(removeToast).toHaveBeenCalledWith("offline"); }); }); -describe("onReconnect", () => { - onReconnect(); - expect(warning).toHaveBeenCalledWith( - "Attempting to reconnect to the message broker", "Offline", "yellow"); +describe("onReconnect()", () => { + it("sends reconnect toast", () => { + onReconnect(); + expect(warning).toHaveBeenCalledWith( + "Attempting to reconnect to the message broker", + "Offline", "yellow", "offline"); + }); }); describe("changeLastClientConnected", () => { @@ -268,7 +275,8 @@ describe("onPublicBroadcast", () => { console.log = jest.fn(); onPublicBroadcast({}); expectBroadcastLog(); - expect(window.alert).toHaveBeenCalledWith(Content.FORCE_REFRESH_CANCEL_WARNING); + expect(window.alert).toHaveBeenCalledWith( + Content.FORCE_REFRESH_CANCEL_WARNING); expect(location.assign).not.toHaveBeenCalled(); }); }); diff --git a/frontend/connectivity/connect_device.ts b/frontend/connectivity/connect_device.ts index c0ce91e2a..249502756 100644 --- a/frontend/connectivity/connect_device.ts +++ b/frontend/connectivity/connect_device.ts @@ -4,7 +4,9 @@ import { Log } from "farmbot/dist/resources/api_resources"; import { Farmbot, BotStateTree, TaggedResource } from "farmbot"; import { FbjsEventName } from "farmbot/dist/constants"; import { noop } from "lodash"; -import { success, error, info, warning, fun, busy } from "../toast/toast"; +import { + success, error, info, warning, fun, busy, removeToast, +} from "../toast/toast"; import { HardwareState } from "../devices/interfaces"; import { GetState, ReduxAction } from "../redux/interfaces"; import { Content, Actions } from "../constants"; @@ -102,11 +104,6 @@ export function readStatus() { .then(() => { commandOK(noun); }, commandErr(noun)); } -export const onOffline = () => { - dispatchNetworkDown("user.mqtt", now()); - error(t(Content.MQTT_DISCONNECTED)); -}; - export const changeLastClientConnected = (bot: Farmbot) => () => { bot.setUserEnv({ "LAST_CLIENT_CONNECTED": JSON.stringify(new Date()) @@ -157,14 +154,20 @@ export function onMalformed() { } } -export const onOnline = - () => { - success(t("Reconnected to the message broker."), t("Online")); - dispatchNetworkUp("user.mqtt", now()); - }; -export const onReconnect = - () => warning(t("Attempting to reconnect to the message broker"), - t("Offline"), "yellow"); +export const onOnline = () => { + removeToast("offline"); + success(t("Reconnected to the message broker."), t("Online")); + dispatchNetworkUp("user.mqtt", now()); +}; + +export const onReconnect = () => + warning(t("Attempting to reconnect to the message broker"), + t("Offline"), "yellow", "offline"); + +export const onOffline = () => { + dispatchNetworkDown("user.mqtt", now()); + error(t(Content.MQTT_DISCONNECTED), t("Error"), "red", "offline"); +}; export function onPublicBroadcast(payl: unknown) { console.log(FbjsEventName.publicBroadcast, payl); diff --git a/frontend/css/farm_designer/farm_designer_panels.scss b/frontend/css/farm_designer/farm_designer_panels.scss index e88368f5d..1c287a009 100644 --- a/frontend/css/farm_designer/farm_designer_panels.scss +++ b/frontend/css/farm_designer/farm_designer_panels.scss @@ -291,10 +291,19 @@ .panel-action-buttons { position: absolute; z-index: 9; - height: 25rem; + height: 16rem; width: 100%; background: $panel_medium_light_gray; padding: 0.5rem; + &.status { + height: 20rem; + } + &.more { + height: 23rem; + } + &.more.status { + height: 26rem; + } button { margin: 0.5rem; float: left; @@ -303,11 +312,12 @@ min-width: -webkit-fill-available; margin-bottom: 0px; margin-left: .5rem; - margin-top: 1rem; + margin-top: 0; } .button-row { float: left; width: 100%; + margin-bottom: 1rem; } .filter-search { padding-right: 1rem; @@ -324,15 +334,35 @@ line-height: 4.1rem; } } + .more { + float: right; + cursor: pointer; + margin-right: 1rem; + line-height: 2.5rem; + p { + display: inline; + font-size: 1.4rem; + margin-right: 1rem; + } + } } .panel-content { - padding-top: 25rem; + padding-top: 16rem; padding-right: 0; padding-left: 0; padding-bottom: 5rem; max-height: calc(100vh - 13rem); overflow-y: auto; overflow-x: hidden; + &.status { + padding-top: 20rem; + } + &.more { + padding-top: 23rem; + } + &.more.status { + padding-top: 26rem; + } } } diff --git a/frontend/farm_designer/plants/__tests__/select_plants_test.tsx b/frontend/farm_designer/plants/__tests__/select_plants_test.tsx index 5d724ebc4..595caf32a 100644 --- a/frontend/farm_designer/plants/__tests__/select_plants_test.tsx +++ b/frontend/farm_designer/plants/__tests__/select_plants_test.tsx @@ -215,6 +215,18 @@ describe("", () => { { payload: undefined, type: Actions.SELECT_POINT }); }); + it("toggles more", () => { + const p = fakeProps(); + const wrapper = mount(); + expect(wrapper.state().more).toEqual(false); + expect(wrapper.find(".select-more").props().hidden).toBeTruthy(); + expect(wrapper.html()).not.toContain(" more status"); + wrapper.find(".more").simulate("click"); + expect(wrapper.state().more).toEqual(true); + expect(wrapper.find(".select-more").props().hidden).toBeFalsy(); + expect(wrapper.html()).toContain(" more status"); + }); + it("selects group items", () => { const p = fakeProps(); p.selected = undefined; @@ -236,7 +248,7 @@ describe("", () => { expect(wrapper.state().group_id).toEqual(1); expect(dispatch).toHaveBeenCalledWith({ type: Actions.SET_SELECTION_POINT_TYPE, - payload: POINTER_TYPES, + payload: ["Plant"], }); expect(p.dispatch).toHaveBeenLastCalledWith({ type: Actions.SELECT_POINT, @@ -265,6 +277,30 @@ describe("", () => { }); }); + it("selects selection type without criteria", () => { + const p = fakeProps(); + const group = fakePointGroup(); + group.body.id = 1; + group.body.criteria.string_eq = {}; + const plant = fakePlant(); + plant.body.id = 1; + const weed = fakeWeed(); + weed.body.id = 2; + group.body.point_ids = [1, 2]; + p.groups = [group]; + const dispatch = jest.fn(); + p.dispatch = mockDispatch(dispatch); + const wrapper = mount(); + const actionsWrapper = shallow(wrapper.instance().ActionButtons()); + actionsWrapper.find("FBSelect").at(1).simulate("change", { + label: "", value: 1 + }); + expect(dispatch).toHaveBeenCalledWith({ + type: Actions.SET_SELECTION_POINT_TYPE, + payload: POINTER_TYPES, + }); + }); + const DELETE_BTN_INDEX = 4; it("confirms deletion of selected plants", () => { diff --git a/frontend/farm_designer/plants/select_plants.tsx b/frontend/farm_designer/plants/select_plants.tsx index a6acb7240..f5abf2c46 100644 --- a/frontend/farm_designer/plants/select_plants.tsx +++ b/frontend/farm_designer/plants/select_plants.tsx @@ -25,7 +25,8 @@ import { } from "farmbot"; import { UUID } from "../../resources/interfaces"; import { - selectAllActivePoints, selectAllToolSlotPointers, selectAllTools, selectAllPointGroups, + selectAllActivePoints, selectAllToolSlotPointers, selectAllTools, + selectAllPointGroups, } from "../../resources/selectors"; import { PointInventoryItem } from "../points/point_inventory_item"; import { ToolSlotInventoryItem } from "../tools"; @@ -108,11 +109,12 @@ export interface SelectPlantsProps { interface SelectPlantsState { group_id: number | undefined; + more: boolean; } export class RawSelectPlants extends React.Component { - state: SelectPlantsState = { group_id: undefined }; + state: SelectPlantsState = { group_id: undefined, more: false }; componentDidMount() { const { dispatch, selected } = this.props; @@ -163,16 +165,24 @@ export class RawSelectPlants this.setState({ group_id }); const group = this.props.groups .filter(pg => pg.body.id == group_id)[0]; - const pointUuids = pointsSelectedByGroup(group, this.props.allPoints) - .map(p => p.uuid); + const points = pointsSelectedByGroup(group, this.props.allPoints); + const pointUuids = points.map(p => p.uuid); const pointerTypes = group.body.criteria.string_eq.pointer_type as PointType[] | undefined; - this.props.dispatch(setSelectionPointType(pointerTypes || POINTER_TYPES)); + const uniqPointTypes = uniq(points.map(p => p.body.pointer_type)); + const pointTypes = + uniqPointTypes.length == 1 ? [uniqPointTypes[0]] : undefined; + this.props.dispatch(setSelectionPointType( + pointerTypes || pointTypes || POINTER_TYPES)); this.props.dispatch(selectPoint(pointUuids)); } ActionButtons = () => -
+
+ - - +
this.setState({ more: !this.state.more })}> +

{this.state.more ? t("Less") : t("More")}

+ +
+
@@ -273,7 +297,11 @@ export class RawSelectPlants description={Content.BOX_SELECT_DESCRIPTION} /> - + {this.selectedPointData.map(p => { if (p.kind == "PlantTemplate" || p.body.pointer_type == "Plant") { return { let count = 0; - const newToast = (): [FBToast, HTMLDivElement] => { + const newToast = (idPrefix = ""): [FBToast, HTMLDivElement] => { const parent = document.createElement("div"); - const child = new FBToast(parent, "title", "message" + (count++), "red"); + const child = + new FBToast(parent, "title", "message" + (count++), "red", idPrefix); + parent.appendChild(child.toastEl); return [child, parent]; }; @@ -90,6 +92,30 @@ describe("FBToast", () => { i.detach(); expect(FBToast.everyMessage[message]).toBeFalsy(); expect(p.removeChild).toHaveBeenCalledWith(i.toastEl); + expect(i.isAttached).toBeFalsy(); + }); + + it("doesn't detach from the DOM", () => { + const [i, p] = newToast(); + p.innerHTML = ""; + const { message } = i; + FBToast.everyMessage[message] = true; + p.removeChild = jest.fn(); + i.isAttached = true; + i.detach(); + expect(FBToast.everyMessage[message]).toBeFalsy(); + expect(p.removeChild).not.toHaveBeenCalled(); + expect(i.isAttached).toBeTruthy(); + }); + + it("sets id", () => { + const toast = newToast("id-prefix")[0]; + expect(toast.toastEl.id).toEqual(expect.stringMatching("^id-prefix-toast-")); + }); + + it("doesn't set id", () => { + const toast = newToast()[0]; + expect(toast.toastEl.id).toEqual(""); }); it("does polling", () => { diff --git a/frontend/toast/__tests__/toast_internal_support_test.ts b/frontend/toast/__tests__/toast_internal_support_test.ts index c9c86ce2d..3f1d9ab0e 100644 --- a/frontend/toast/__tests__/toast_internal_support_test.ts +++ b/frontend/toast/__tests__/toast_internal_support_test.ts @@ -20,20 +20,34 @@ describe("toast internal support files", () => { container.className = "toast-container"; document.body.appendChild(container); - createToastOnce(msg, "bar", "baz", fallback); + createToastOnce(msg, "bar", "baz", "id-prefix", fallback); expect(FBToast.everyMessage[msg]).toBe(true); expect(fallback).not.toHaveBeenCalled(); expect(mockRun).toHaveBeenCalled(); - createToastOnce(msg, "bar", "baz", fallback); + createToastOnce(msg, "bar", "baz", "id-prefix", fallback); expect(fallback).toHaveBeenCalled(); }); + it("uses default fallback logger", () => { + document.body.innerHTML = ""; + console.warn = jest.fn(); + const container = document.createElement("DIV"); + container.className = "toast-container"; + document.body.appendChild(container); + const msg = "foo"; + delete FBToast.everyMessage[msg]; + createToastOnce(msg, "bar", "baz", ""); + expect(console.warn).not.toHaveBeenCalled(); + expect(mockRun).toHaveBeenCalled(); + createToastOnce(msg, "bar", "baz", ""); + expect(console.warn).toHaveBeenCalled(); + }); + it("crashes if you don't attach .toast-container", () => { document.body.innerHTML = ""; - expect(() => createToast("x", "y", "z")) - .toThrow(); + expect(() => createToast("x", "y", "z", "id-prefix")).toThrow(); }); }); diff --git a/frontend/toast/__tests__/toast_test.ts b/frontend/toast/__tests__/toast_test.ts index 9822a399a..3f71c7ab3 100644 --- a/frontend/toast/__tests__/toast_test.ts +++ b/frontend/toast/__tests__/toast_test.ts @@ -14,93 +14,113 @@ const { info, fun, init, + removeToast, busy, }: typeof import("../toast") = jest.requireActual("../toast"); describe("toasts", () => { it("pops a warning() toast", () => { warning("test suite msg 1"); - expect(createToastOnce).toHaveBeenCalledWith("test suite msg 1", - "Warning", - "orange", - console.warn); + expect(createToastOnce).toHaveBeenCalledWith( + "test suite msg 1", "Warning", "orange", "", console.warn); }); it("pops a warning() toast with different title and color", () => { - warning("test suite msg", "new title", "purple"); - expect(createToastOnce) - .toHaveBeenCalledWith("test suite msg", "new title", "purple", - console.warn); + warning("test suite msg", "new title", "purple", "id-prefix"); + expect(createToastOnce).toHaveBeenCalledWith( + "test suite msg", "new title", "purple", "id-prefix", console.warn); }); it("pops a error() toast", () => { error("test suite msg 2"); - expect(createToastOnce).toHaveBeenCalledWith("test suite msg 2", - "Error", - "red", - console.error); + expect(createToastOnce).toHaveBeenCalledWith( + "test suite msg 2", "Error", "red", "", console.error); }); it("pops a error() toast with different title and color", () => { - error("test suite msg", "new title", "purple"); - expect(createToastOnce) - .toHaveBeenCalledWith("test suite msg", "new title", "purple", - console.error); + error("test suite msg", "new title", "purple", "id-prefix"); + expect(createToastOnce).toHaveBeenCalledWith( + "test suite msg", "new title", "purple", "id-prefix", console.error); }); it("pops a success() toast", () => { success("test suite msg"); - expect(createToast) - .toHaveBeenCalledWith("test suite msg", "Success", "green"); + expect(createToast).toHaveBeenCalledWith( + "test suite msg", "Success", "green", ""); }); it("pops a success() toast with different title and color", () => { - success("test suite msg", "new title", "purple"); - expect(createToast) - .toHaveBeenCalledWith("test suite msg", "new title", "purple"); + success("test suite msg", "new title", "purple", "id-prefix"); + expect(createToast).toHaveBeenCalledWith( + "test suite msg", "new title", "purple", "id-prefix"); }); it("pops a info() toast", () => { info("test suite msg"); - expect(createToast) - .toHaveBeenCalledWith("test suite msg", "FYI", "blue"); + expect(createToast).toHaveBeenCalledWith( + "test suite msg", "FYI", "blue", ""); }); it("pops a info() toast with different title and color", () => { - info("test suite msg", "new title", "purple"); - expect(createToast) - .toHaveBeenCalledWith("test suite msg", "new title", "purple"); + info("test suite msg", "new title", "purple", "id-prefix"); + expect(createToast).toHaveBeenCalledWith( + "test suite msg", "new title", "purple", "id-prefix"); }); it("pops a busy() toast", () => { busy("test suite msg"); - expect(createToast) - .toHaveBeenCalledWith("test suite msg", "Busy", "yellow"); + expect(createToast).toHaveBeenCalledWith( + "test suite msg", "Busy", "yellow", ""); }); it("pops a busy() toast with different title and color", () => { - busy("test suite msg", "new title", "purple"); - expect(createToast) - .toHaveBeenCalledWith("test suite msg", "new title", "purple"); + busy("test suite msg", "new title", "purple", "id-prefix"); + expect(createToast).toHaveBeenCalledWith( + "test suite msg", "new title", "purple", "id-prefix"); }); it("pops a fun() toast", () => { fun("test suite msg"); - expect(createToast) - .toHaveBeenCalledWith("test suite msg", "Did you know?", "dark-blue"); + expect(createToast).toHaveBeenCalledWith( + "test suite msg", "Did you know?", "dark-blue", ""); }); it("pops a fun() toast with different title and color", () => { - fun("test suite msg", "new title", "purple"); - expect(createToast) - .toHaveBeenCalledWith("test suite msg", "new title", "purple"); + fun("test suite msg", "new title", "purple", "id-prefix"); + expect(createToast).toHaveBeenCalledWith( + "test suite msg", "new title", "purple", "id-prefix"); }); + const getToastContainerCount = () => + Object.values(document.querySelectorAll(".toast-container")).length; + + const getToastCount = () => + document.querySelector(".toast-container")?.childElementCount; + it("adds the appropriate div to the DOM", () => { - const count1 = document.querySelectorAll(".toast-container").item.length; - expect(count1).toEqual(1); + document.body.innerHTML = ""; + expect(getToastContainerCount()).toEqual(0); init(); - const count2 = document.querySelectorAll(".toast-container").item.length; - expect(count2).toEqual(1); + expect(getToastContainerCount()).toEqual(1); + }); + + it("removes a toast message", () => { + document.body.innerHTML = ""; + init(); + expect(getToastCount()).toEqual(0); + const toast = document.createElement("div"); + toast.id = "id-prefix-123"; + document.querySelector(".toast-container")?.appendChild(toast); + expect(getToastCount()).toEqual(1); + removeToast("id-prefix"); + expect(getToastCount()).toEqual(0); + }); + + it("doesn't remove a toast message: parent missing", () => { + document.body.innerHTML = ""; + expect(getToastContainerCount()).toEqual(0); + console.error = jest.fn(); + removeToast("id-prefix"); + expect(console.error).toHaveBeenCalledWith("toast-container is null."); }); }); diff --git a/frontend/toast/fb_toast.ts b/frontend/toast/fb_toast.ts index 5343bf608..1cff0e7dd 100644 --- a/frontend/toast/fb_toast.ts +++ b/frontend/toast/fb_toast.ts @@ -1,3 +1,5 @@ +import { uuid } from "farmbot"; + /** This is a [surprisingly reliable] legacy component. * TODO: Convert this to React. */ export class FBToast { @@ -29,7 +31,10 @@ export class FBToast { constructor(public parent: Element, title: string, raw_message: string, - color: string) { + color: string, + idPrefix: string) { + + idPrefix && (this.toastEl.id = `${idPrefix}-toast-${uuid()}`); this.message = raw_message.replace(/\s+/g, " "); /** Fill contents. */ @@ -84,7 +89,7 @@ export class FBToast { detach = () => { clearInterval(this.intervalId); delete FBToast.everyMessage[this.message]; - if (this.isAttached) { + if (this.isAttached && this.parent.contains(this.toastEl)) { this.parent.removeChild(this.toastEl); this.isAttached = false; } diff --git a/frontend/toast/toast.ts b/frontend/toast/toast.ts index a6902da00..ca347f047 100644 --- a/frontend/toast/toast.ts +++ b/frontend/toast/toast.ts @@ -4,45 +4,70 @@ import { t } from "../i18next_wrapper"; /** * Orange message with "Warning" as the default title. */ -export const warning = - (message: string, title = t("Warning"), color = "orange") => { - createToastOnce(message, title, color, console.warn); - }; +export const warning = ( + message: string, + title = t("Warning"), + color = "orange", + idPrefix = "", +) => { + createToastOnce(message, title, color, idPrefix, console.warn); +}; /** * Red message with "Error" as the default title. */ -export const error = (message: string, title = t("Error"), color = "red") => { - createToastOnce(message, title, color, console.error); +export const error = ( + message: string, + title = t("Error"), + color = "red", + idPrefix = "", +) => { + createToastOnce(message, title, color, idPrefix, console.error); }; /** * Green message with "Success" as the default title. */ -export const success = - (message: string, title = t("Success"), color = "green") => - createToast(message, title, color); +export const success = ( + message: string, + title = t("Success"), + color = "green", + idPrefix = "", +) => + createToast(message, title, color, idPrefix); /** * Blue message with "FYI" as the default title. */ -export const info = - (message: string, title = t("FYI"), color = "blue") => - createToast(message, title, color); +export const info = ( + message: string, + title = t("FYI"), + color = "blue", + idPrefix = "", +) => + createToast(message, title, color, idPrefix); /** * Yellow message with "Busy" as the default title. */ -export const busy = - (message: string, title = t("Busy"), color = "yellow") => - createToast(message, title, color); +export const busy = ( + message: string, + title = t("Busy"), + color = "yellow", + idPrefix = "", +) => + createToast(message, title, color, idPrefix); /** * Dark blue message with "Did you know?" as the default title. */ -export const fun = - (message: string, title = t("Did you know?"), color = "dark-blue") => - createToast(message, title, color); +export const fun = ( + message: string, + title = t("Did you know?"), + color = "dark-blue", + idPrefix = "", +) => + createToast(message, title, color, idPrefix); /** * Adds a hidden container div for holding toast messages. @@ -52,3 +77,14 @@ export const init = () => { toastContainer.classList.add("toast-container"); document.body.appendChild(toastContainer); }; + +/** Remove all toast messages that match the provided id prefix. */ +export const removeToast = (idPrefix: string) => { + const parent = document.querySelector(".toast-container"); + const toasts = document.querySelectorAll(`[id^="${idPrefix}-"]`); + if (parent) { + Object.values(toasts).map(toast => parent.removeChild(toast)); + } else { + console.error("toast-container is null."); + } +}; diff --git a/frontend/toast/toast_internal_support.ts b/frontend/toast/toast_internal_support.ts index 9f82b1afe..403ba5103 100644 --- a/frontend/toast/toast_internal_support.ts +++ b/frontend/toast/toast_internal_support.ts @@ -3,7 +3,9 @@ import { FBToast } from "./fb_toast"; /** * The function responsible for attaching the messages to the container. */ -export const createToast = (message: string, title: string, color: string) => { +export const createToast = ( + message: string, title: string, color: string, idPrefix: string, +) => { /** * Container element for all of the messages created from init(). @@ -17,18 +19,20 @@ export const createToast = (message: string, title: string, color: string) => { /** * Create elements. */ - const t = new FBToast(parent, title, message, color); + const t = new FBToast(parent, title, message, color, idPrefix); t.run(); }; export const createToastOnce = (message: string, title: string, color: string, - fallbackLogger = console.warn) => { + idPrefix: string, + fallbackLogger = console.warn, +) => { if (FBToast.everyMessage[message]) { fallbackLogger(message); } else { - createToast(message, title, color); + createToast(message, title, color, idPrefix); FBToast.everyMessage[message] = true; } };