From f0fc050f127c8d8c4a308ed4250d7bb0dec54e56 Mon Sep 17 00:00:00 2001 From: bttf <2374625+bttf@users.noreply.github.com> Date: Fri, 23 Jun 2023 12:45:51 -0700 Subject: [PATCH 1/4] Add EditDOMMutations modal --- .../Experiment/EditDOMMutationsModal.tsx | 133 ++++++++++++++++++ .../components/Experiment/VariationsTable.tsx | 88 ++++++++++-- 2 files changed, 209 insertions(+), 12 deletions(-) create mode 100644 packages/front-end/components/Experiment/EditDOMMutationsModal.tsx diff --git a/packages/front-end/components/Experiment/EditDOMMutationsModal.tsx b/packages/front-end/components/Experiment/EditDOMMutationsModal.tsx new file mode 100644 index 00000000000..31647756ce8 --- /dev/null +++ b/packages/front-end/components/Experiment/EditDOMMutationsModal.tsx @@ -0,0 +1,133 @@ +import { VisualChange } from "back-end/types/visual-changeset"; +import { FC, useCallback, useState } from "react"; +import Code from "@/components/SyntaxHighlighting/Code"; +import Modal from "../Modal"; + +const EditDOMMutatonsModal: FC<{ + visualChange: VisualChange; + close: () => void; + onSave: (newVisualChange: VisualChange) => void; +}> = ({ close, visualChange, onSave }) => { + const [newVisualChange, setNewVisualChange] = useState( + visualChange + ); + + const deleteCustomJS = useCallback(() => { + setNewVisualChange({ + ...newVisualChange, + js: "", + }); + }, [newVisualChange, setNewVisualChange]); + + const deleteGlobalCSS = useCallback(() => { + setNewVisualChange({ + ...newVisualChange, + css: "", + }); + }, [newVisualChange, setNewVisualChange]); + + const deleteDOMMutation = useCallback( + (index: number) => { + setNewVisualChange({ + ...newVisualChange, + domMutations: newVisualChange.domMutations.filter( + (_m, i) => i !== index + ), + }); + }, + [newVisualChange, setNewVisualChange] + ); + + const onSubmit = () => { + onSave(newVisualChange); + }; + + return ( + +
+
+

+ Global CSS + {newVisualChange.css ? ( + + + delete + + + ) : null} +

+ {newVisualChange.css ? ( + + ) : ( +
(None)
+ )} +
+ +
+

+ Custom JS + {newVisualChange.js ? ( + + + delete + + + ) : null} +

+ {newVisualChange.js ? ( + + ) : ( +
(None)
+ )} +
+ +
+

DOM Mutations

+ + {newVisualChange.domMutations.length ? ( + newVisualChange.domMutations.map((m, i) => ( + + )) + ) : ( +
(None)
+ )} +
+
+
+ ); +}; + +export default EditDOMMutatonsModal; diff --git a/packages/front-end/components/Experiment/VariationsTable.tsx b/packages/front-end/components/Experiment/VariationsTable.tsx index 960242bc81b..2a11fe8ef7c 100644 --- a/packages/front-end/components/Experiment/VariationsTable.tsx +++ b/packages/front-end/components/Experiment/VariationsTable.tsx @@ -5,10 +5,11 @@ import { Variation, } from "back-end/types/experiment"; import { + VisualChange, VisualChangesetInterface, VisualChangesetURLPattern, } from "back-end/types/visual-changeset"; -import React, { FC, Fragment, useState } from "react"; +import React, { FC, Fragment, useCallback, useState } from "react"; import { FaPlusCircle, FaTimesCircle } from "react-icons/fa"; import { useAuth } from "@/services/auth"; import { useUser } from "@/services/UserContext"; @@ -22,6 +23,7 @@ import ScreenshotUpload from "../EditExperiment/ScreenshotUpload"; import { GBEdit } from "../Icons"; import OpenVisualEditorLink from "../OpenVisualEditorLink"; import VisualChangesetModal from "./VisualChangesetModal"; +import EditDOMMutatonsModal from "./EditDOMMutationsModal"; interface Props { experiment: ExperimentInterfaceStringDates; @@ -130,10 +132,57 @@ const VariationsTable: FC = ({ setEditingVisualChangeset, ] = useState(null); + const [editingVisualChange, setEditingVisualChange] = useState<{ + visualChangeset: VisualChangesetInterface; + visualChange: VisualChange; + visualChangeIndex: number; + } | null>(null); + const hasDescriptions = variations.some((v) => !!v.description?.trim()); const hasUniqueIDs = variations.some((v, i) => v.key !== i + ""); const hasLegacyVisualChanges = variations.some((v) => isLegacyVariation(v)); + const deleteVisualChangeset = useCallback( + async (id: string) => { + await apiCall(`/visual-changesets/${id}`, { + method: "DELETE", + }); + mutate(); + track("Delete visual changeset", { + source: "visual-editor-ui", + }); + }, + [apiCall, mutate] + ); + + const updateVisualChange = useCallback( + async ({ + visualChangeset, + visualChange, + index, + }: { + visualChangeset: VisualChangesetInterface; + visualChange: VisualChange; + index: number; + }) => { + const newVisualChangeset: VisualChangesetInterface = { + ...visualChangeset, + visualChanges: visualChangeset.visualChanges.map((c, i) => + i === index ? visualChange : c + ), + }; + await apiCall(`/visual-changesets/${visualChangeset.id}`, { + method: "PUT", + body: JSON.stringify(newVisualChangeset), + }); + mutate(); + track("Delete visual changeset", { + source: "visual-editor-ui", + }); + }, + [apiCall, mutate] + ); + return (
= ({ )} { - await apiCall(`/visual-changesets/${vc.id}`, { - method: "DELETE", - }); - mutate(); - track("Delete visual changeset", { - source: "visual-editor-ui", - }); - }} + onClick={() => deleteVisualChangeset(vc.id)} displayName="Visual Changes" />
@@ -373,10 +414,19 @@ const VariationsTable: FC = ({ return ( ); }; From 96d26e89472c14f711935d62ec9c894eee33b400 Mon Sep 17 00:00:00 2001 From: bttf <2374625+bttf@users.noreply.github.com> Date: Tue, 27 Jun 2023 11:06:02 -0700 Subject: [PATCH 2/4] Use edit link; Add bypass --- .../components/Experiment/VariationsTable.tsx | 46 +++++++++++-------- .../components/OpenVisualEditorLink.tsx | 26 +++++++---- 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/packages/front-end/components/Experiment/VariationsTable.tsx b/packages/front-end/components/Experiment/VariationsTable.tsx index 2a11fe8ef7c..8bd16b64535 100644 --- a/packages/front-end/components/Experiment/VariationsTable.tsx +++ b/packages/front-end/components/Experiment/VariationsTable.tsx @@ -414,32 +414,38 @@ const VariationsTable: FC = ({ return ( diff --git a/packages/front-end/components/OpenVisualEditorLink.tsx b/packages/front-end/components/OpenVisualEditorLink.tsx index 3ccb59f2852..b4adc269ce8 100644 --- a/packages/front-end/components/OpenVisualEditorLink.tsx +++ b/packages/front-end/components/OpenVisualEditorLink.tsx @@ -1,4 +1,4 @@ -import { FC, useMemo, useState } from "react"; +import { FC, useCallback, useMemo, useState } from "react"; import { FaExternalLinkAlt } from "react-icons/fa"; import { getApiHost } from "@/services/env"; import track from "@/services/track"; @@ -35,6 +35,14 @@ const OpenVisualEditorLink: FC<{ }); }, [visualEditorUrl, id, changeIndex, apiHost]); + const navigate = useCallback(() => { + track("Open visual editor", { + source: "visual-editor-ui", + status: "success", + }); + window.location.href = url; + }, [url]); + return ( <> @@ -120,8 +124,14 @@ const OpenVisualEditorLink: FC<{ } > {isChromeBrowser ? ( - `You'll need to install the GrowthBook DevTools Chrome extension - to use the visual editor.` + <> + You'll need to install the GrowthBook DevTools Chrome + extension to use the visual editor.{" "} + + Click here to proceed anyway + + . + ) : ( <> The Visual Editor is currently only supported in Chrome. We are From 493400c3bfe20bff1ceba2396f39a5631a507540 Mon Sep 17 00:00:00 2001 From: bttf <2374625+bttf@users.noreply.github.com> Date: Tue, 27 Jun 2023 19:57:29 -0700 Subject: [PATCH 3/4] Refine --- .../Experiment/EditDOMMutationsModal.tsx | 23 +++++------ .../components/Experiment/VariationsTable.tsx | 40 +++++++++---------- 2 files changed, 28 insertions(+), 35 deletions(-) diff --git a/packages/front-end/components/Experiment/EditDOMMutationsModal.tsx b/packages/front-end/components/Experiment/EditDOMMutationsModal.tsx index 31647756ce8..26185436d57 100644 --- a/packages/front-end/components/Experiment/EditDOMMutationsModal.tsx +++ b/packages/front-end/components/Experiment/EditDOMMutationsModal.tsx @@ -47,7 +47,7 @@ const EditDOMMutatonsModal: FC<{ open close={close} size="lg" - header="Edit Visual Changes" + header="Remove Visual Changes" submit={onSubmit} cta="Save" > @@ -101,24 +101,19 @@ const EditDOMMutatonsModal: FC<{ {newVisualChange.domMutations.length ? ( newVisualChange.domMutations.map((m, i) => ( -
- +
+
)) ) : ( diff --git a/packages/front-end/components/Experiment/VariationsTable.tsx b/packages/front-end/components/Experiment/VariationsTable.tsx index 8bd16b64535..b8fee58b91b 100644 --- a/packages/front-end/components/Experiment/VariationsTable.tsx +++ b/packages/front-end/components/Experiment/VariationsTable.tsx @@ -10,7 +10,7 @@ import { VisualChangesetURLPattern, } from "back-end/types/visual-changeset"; import React, { FC, Fragment, useCallback, useState } from "react"; -import { FaPlusCircle, FaTimesCircle } from "react-icons/fa"; +import { FaPencilAlt, FaPlusCircle, FaTimesCircle } from "react-icons/fa"; import { useAuth } from "@/services/auth"; import { useUser } from "@/services/UserContext"; import DeleteButton from "@/components/DeleteButton/DeleteButton"; @@ -414,13 +414,10 @@ const VariationsTable: FC = ({ return (
-
- {numChanges} visual change - {numChanges === 1 ? "" : "s"} -
+
+ + Preview - {" / "} -
From fca7e02b68d2bbbb2dd2dbde74a91966de83da2c Mon Sep 17 00:00:00 2001 From: bttf <2374625+bttf@users.noreply.github.com> Date: Wed, 28 Jun 2023 08:49:24 -0700 Subject: [PATCH 4/4] Try this --- .../Experiment/EditDOMMutationsModal.tsx | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/front-end/components/Experiment/EditDOMMutationsModal.tsx b/packages/front-end/components/Experiment/EditDOMMutationsModal.tsx index 26185436d57..4aaba1cf970 100644 --- a/packages/front-end/components/Experiment/EditDOMMutationsModal.tsx +++ b/packages/front-end/components/Experiment/EditDOMMutationsModal.tsx @@ -51,7 +51,7 @@ const EditDOMMutatonsModal: FC<{ submit={onSubmit} cta="Save" > -
+

Global CSS @@ -101,19 +101,21 @@ const EditDOMMutatonsModal: FC<{ {newVisualChange.domMutations.length ? ( newVisualChange.domMutations.map((m, i) => ( -
+
+ deleteDOMMutation(i)} + style={{ marginBottom: "-.5rem", fontSize: "0.75rem" }} + > + delete + -
)) ) : (