diff --git a/src/panel/components/EvaluationsPanel.spec.tsx b/src/panel/components/EvaluationsPanel.spec.tsx index 749e341..cd2ef17 100644 --- a/src/panel/components/EvaluationsPanel.spec.tsx +++ b/src/panel/components/EvaluationsPanel.spec.tsx @@ -7,6 +7,7 @@ import { PropItem } from "./PropList"; jest.mock("../libs/EvaluationsContext"); const setEvaluations = jest.fn(); +const savePreserveLogs = jest.fn(); (useEvaluationsContext as jest.Mock).mockReturnValue({ evaluations: [ { @@ -29,6 +30,7 @@ const setEvaluations = jest.fn(); }, ], setEvaluations, + savePreserveLogs, }); describe("EvaluationsPanel", () => { @@ -44,7 +46,7 @@ describe("EvaluationsPanel", () => { it("should toggle string-wrap", () => { const wrapper = shallow(); expect(wrapper.hasClass("string-wrap")).toBe(false); - wrapper.find(Switch).invoke("onChange")({ + wrapper.find("[label='String Wrap']").invoke("onChange")({ target: { checked: true, }, @@ -58,6 +60,16 @@ describe("EvaluationsPanel", () => { expect(setEvaluations).toBeCalledWith([]); }); + it("should toggle preserveLogs", () => { + const wrapper = shallow(); + wrapper.find("[label='Preserve logs']").invoke("onChange")({ + target: { + checked: true, + }, + } as any); + expect(savePreserveLogs).toBeCalledWith(true); + }); + it("should handle filter", () => { const wrapper = shallow(); wrapper.find(InputGroup).invoke("onChange")({ diff --git a/src/panel/components/EvaluationsPanel.tsx b/src/panel/components/EvaluationsPanel.tsx index 339aa80..2c7aeff 100644 --- a/src/panel/components/EvaluationsPanel.tsx +++ b/src/panel/components/EvaluationsPanel.tsx @@ -10,9 +10,15 @@ import classNames from "classnames"; import { PanelSelector } from "./PanelSelector"; import { useEvaluationsContext } from "../libs/EvaluationsContext"; import { PropList, PropItem } from "./PropList"; +import { Storage } from "../libs/Storage"; export function EvaluationsPanel(): React.ReactElement { - const { evaluations, setEvaluations } = useEvaluationsContext(); + const { + evaluations, + setEvaluations, + preserveLogs, + savePreserveLogs, + } = useEvaluationsContext(); const [stringWrap, setStringWrap] = React.useState(false); const [q, setQ] = React.useState(); @@ -43,6 +49,17 @@ export function EvaluationsPanel(): React.ReactElement { [] ); + const handleToggleLogs = React.useCallback( + (event: React.FormEvent) => { + savePreserveLogs((event.target as HTMLInputElement).checked); + // Storage.setItem( + // "preserveLogs", + // (event.target as HTMLInputElement).checked + // ); + }, + [] + ); + return (
+ EvaluationsPanel ({evaluations.length})
; + const { evaluations, savePreserveLogs } = useEvaluationsContext(); + return ( +
{ + savePreserveLogs(e.target.value); + }} + id="EvaluationsPanel" + > + EvaluationsPanel ({evaluations.length}) +
+ ); } function MockTransformationsPanel(): React.ReactElement { @@ -126,4 +135,42 @@ describe("Layout", () => { expect(wrapper.text()).toBe("TransformationsPanel (1)"); wrapper.unmount(); }); + + it.each([ + [undefined, 1], + [false, 0], + ])("locationChange should work", async (value, length) => { + storageGetItem.mockReturnValue("Evaluations"); + const wrapper = mount(); + await act(async () => { + window.postMessage( + { + source: MESSAGE_SOURCE_HOOK, + payload: { + type: "evaluation", + payload: "good", + }, + }, + location.origin + ); + await new Promise((resolve) => setTimeout(resolve)); + }); + wrapper.find("#EvaluationsPanel").first().invoke("onChange")({ + target: { value }, + }); + await act(async () => { + window.postMessage( + { + source: MESSAGE_SOURCE_HOOK, + payload: { + type: "locationChange", + }, + }, + location.origin + ); + await new Promise((resolve) => setTimeout(resolve)); + }); + expect(wrapper.text()).toBe(`EvaluationsPanel (${length})`); + wrapper.unmount(); + }); }); diff --git a/src/panel/components/Layout.tsx b/src/panel/components/Layout.tsx index 01d0c8a..c8ec498 100644 --- a/src/panel/components/Layout.tsx +++ b/src/panel/components/Layout.tsx @@ -21,6 +21,7 @@ export function Layout(): React.ReactElement { Storage.getItem("selectedPanel") ?? "Bricks" ); const [evaluations, setEvaluations] = React.useState([]); + const [preserveLogs, savePreserveLogs] = React.useState(true); const [transformations, setTransformations] = React.useState< Transformation[] >([]); @@ -33,11 +34,17 @@ export function Layout(): React.ReactElement { ((data = event.data.payload), data?.type === "evaluation") ) { setEvaluations((prev) => prev.concat(hydrate(data.payload, data.repo))); + } else if ( + event.data?.source === MESSAGE_SOURCE_HOOK && + ((data = event.data.payload), data?.type === "locationChange") && + !(preserveLogs ?? true) + ) { + setEvaluations([]); } } window.addEventListener("message", onMessage); return (): void => window.removeEventListener("message", onMessage); - }, []); + }, [preserveLogs]); React.useEffect(() => { function onMessage(event: MessageEvent): void { @@ -49,11 +56,17 @@ export function Layout(): React.ReactElement { setTransformations((prev) => prev.concat(hydrate(data.payload, data.repo)) ); + } else if ( + event.data?.source === MESSAGE_SOURCE_HOOK && + ((data = event.data.payload), data?.type === "locationChange") && + !(preserveLogs ?? true) + ) { + setTransformations([]); } } window.addEventListener("message", onMessage); return (): void => window.removeEventListener("message", onMessage); - }, []); + }, [preserveLogs]); React.useEffect(() => { Storage.setItem("selectedPanel", selectedPanel); @@ -73,13 +86,23 @@ export function Layout(): React.ReactElement { > {selectedPanel === "Evaluations" ? ( ) : selectedPanel === "Transformations" ? ( diff --git a/src/panel/components/TransformationsPanel.spec.tsx b/src/panel/components/TransformationsPanel.spec.tsx index b69dd67..2daa309 100644 --- a/src/panel/components/TransformationsPanel.spec.tsx +++ b/src/panel/components/TransformationsPanel.spec.tsx @@ -6,6 +6,7 @@ import { useTransformationsContext } from "../libs/TransformationsContext"; jest.mock("../libs/TransformationsContext"); const setTransformations = jest.fn(); +const savePreserveLogs = jest.fn(); (useTransformationsContext as jest.Mock).mockReturnValue({ transformations: [ { @@ -21,6 +22,7 @@ const setTransformations = jest.fn(); }, ], setTransformations, + savePreserveLogs, }); describe("TransformationsPanel", () => { @@ -36,7 +38,7 @@ describe("TransformationsPanel", () => { it("should toggle string-wrap", () => { const wrapper = shallow(); expect(wrapper.hasClass("string-wrap")).toBe(false); - wrapper.find(Switch).invoke("onChange")({ + wrapper.find("[label='String Wrap']").invoke("onChange")({ target: { checked: true, }, @@ -44,6 +46,16 @@ describe("TransformationsPanel", () => { expect(wrapper.hasClass("string-wrap")).toBe(true); }); + it("should toggle preserveLogs", () => { + const wrapper = shallow(); + wrapper.find("[label='Preserve logs']").invoke("onChange")({ + target: { + checked: true, + }, + } as any); + expect(savePreserveLogs).toBeCalledWith(true); + }); + it("should handle clear", () => { const wrapper = shallow(); wrapper.find(Button).invoke("onClick")(null); diff --git a/src/panel/components/TransformationsPanel.tsx b/src/panel/components/TransformationsPanel.tsx index 45549b6..034dc1b 100644 --- a/src/panel/components/TransformationsPanel.tsx +++ b/src/panel/components/TransformationsPanel.tsx @@ -4,9 +4,15 @@ import classNames from "classnames"; import { PanelSelector } from "./PanelSelector"; import { useTransformationsContext } from "../libs/TransformationsContext"; import { PropItem } from "./PropList"; +import { Storage } from "../libs/Storage"; export function TransformationsPanel(): React.ReactElement { - const { transformations, setTransformations } = useTransformationsContext(); + const { + transformations, + setTransformations, + preserveLogs, + savePreserveLogs, + } = useTransformationsContext(); const [stringWrap, setStringWrap] = React.useState(false); const handleClear = React.useCallback(() => { @@ -20,6 +26,17 @@ export function TransformationsPanel(): React.ReactElement { [] ); + const handleToggleLogs = React.useCallback( + (event: React.FormEvent) => { + savePreserveLogs((event.target as HTMLInputElement).checked); + // Storage.setItem( + // "preserveLogs", + // (event.target as HTMLInputElement).checked + // ); + }, + [] + ); + return (
+ >; + preserveLogs?: boolean; + savePreserveLogs?: React.Dispatch>; } export const EvaluationsContext = React.createContext({}); diff --git a/src/panel/libs/TransformationsContext.ts b/src/panel/libs/TransformationsContext.ts index ad996cb..f9ddba4 100644 --- a/src/panel/libs/TransformationsContext.ts +++ b/src/panel/libs/TransformationsContext.ts @@ -4,6 +4,8 @@ import { Transformation } from "../../shared/interfaces"; export interface ContextOfTransformations { transformations?: Transformation[]; setTransformations?: React.Dispatch>; + preserveLogs?: boolean; + savePreserveLogs?: React.Dispatch>; } export const TransformationsContext = React.createContext<