diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fd00fe0..598ca126 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +## Monday, October 28th, 2024 + +### Added + +- Added a `postMessageToLimelight` function which uses the `window.postMessage` utility to open Limelight and send message JSON for editing +- Added a link to edit messages to Spotlights and Infobars in the production table +- Added a "Create a New Message" link to the navigation header, which links to the New Message page in Limelight + +### Fixed + +- Fixed a missing message ID in the local JSON, and added a function to safeguard similar errors + ## Wednesday, October 23rd, 2024 ### Added diff --git a/app/columns.tsx b/app/columns.tsx index e83e2113..47266baf 100644 --- a/app/columns.tsx +++ b/app/columns.tsx @@ -70,6 +70,7 @@ export type FxMSMessageInfo = { ctrPercent?: number; ctrPercentChange?: number; ctrDashboardLink?: string; + editableJson?: string; previewLink?: string; metrics: string; impressions?: number; @@ -126,6 +127,31 @@ export type BranchInfo = { export type RecipeOrBranchInfo = RecipeInfo | BranchInfo; +/** + * Opens the Limelight utility using window.postMessage, waits for a response, + * and sends message JSON as a payload for editing. + */ +function postMessageToLimelight(editableJson: string) { + let win = window.open("https://mozilla.github.io/limelight/?postMessage"); + + window.addEventListener( + "message", + (event) => { + if (event.origin !== "https://mozilla.github.io/limelight/") { + return; + } + (win as WindowProxy | null)?.postMessage( + { + type: "import", + value: editableJson, + }, + "https://mozilla.github.io/limelight/", + ); + }, + false, + ); +} + /** * @returns an OffsiteLink linking to the Looker dashboard link if it exists, * labelled with either the CTR percent or "Dashboard" @@ -215,9 +241,42 @@ export const fxmsMessageColumns: ColumnDef[] = [ }, }, { - // accessorKey: "segment", - // header: "Segment", - // }, { + accessorKey: "segment", + header: "", + cell: (props: any) => { + const supportedTypes = ["infobar", "spotlight"]; + if ( + supportedTypes.includes(props.row.original.template) && + props.row.original.editableJson + ) { + return ( + + ); + } + return <>; + }, + }, + { accessorKey: "metrics", header: () => (
diff --git a/app/page.tsx b/app/page.tsx index 6a70ed0b..2aac51b0 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -17,6 +17,7 @@ import { getTemplateFromMessage, _isAboutWelcomeTemplate, maybeCreateWelcomePreview, + getEditableJSON, getPreviewLink, messageHasMicrosurvey, compareSurfacesFn, @@ -74,6 +75,7 @@ async function getASRouterLocalColumnFromJSON( metrics: "some metrics", ctrPercent: undefined, // may be populated from Looker data ctrPercentChange: undefined, // may be populated from Looker data + editableJson: getEditableJSON(messageDef), // message JSON for Limelight previewLink: getPreviewLink(maybeCreateWelcomePreview(messageDef)), impressions: undefined, // may be populated from Looker data hasMicrosurvey: messageHasMicrosurvey(messageDef.id), diff --git a/components/ui/menubutton.tsx b/components/ui/menubutton.tsx index dcce937a..4a260296 100644 --- a/components/ui/menubutton.tsx +++ b/components/ui/menubutton.tsx @@ -12,7 +12,15 @@ import { navigationMenuTriggerStyle, navigationMenuItemStyle, } from "@/components/ui/navigation-menu"; -import { Menu, Hash, Book, AppWindow, Table, FileSearch } from "lucide-react"; +import { + Menu, + Hash, + Book, + AppWindow, + Table, + FileSearch, + Lightbulb, +} from "lucide-react"; import { cn } from "@/lib/utils"; const ListItem = React.forwardRef< @@ -63,6 +71,17 @@ export function MenuButton({ isComplete }: MenuButtonProps) { + + + + + Create A New Message + + + { + if (!screen.id) { + screen.id = message.content.id; + } + }); + return message; + } catch (e) { + console.log("Could not generate editable JSON: ", e); + } + break; + case "infobar": + try { + if (message.content && message.content.buttons) { + return message; + } + } catch (e) { + console.log("Could note generate editable JSON: ", e); + } + break; + default: + return undefined; + } +} + export function getPreviewLink(message: any): string { let previewLink = `about:messagepreview?json=${encodeURIComponent( toBinary(JSON.stringify(message)),