From 11fd44af0f27253be1dd8b1c7f4ea04ceed23c1d Mon Sep 17 00:00:00 2001 From: "Wei-Chun, Chang" Date: Mon, 30 Dec 2024 09:53:59 +0700 Subject: [PATCH 1/2] Add hint after preview change success Signed-off-by: Wei-Chun, Chang --- .../components/lineage/PreviewChangeView.tsx | 22 +++-- js/src/lib/api/localStorageKeys.ts | 1 + .../lib/hooks/useFeedbackCollectionToast.tsx | 22 ++++- js/src/lib/hooks/useGuideToast.tsx | 80 +++++++++++++++++++ 4 files changed, 117 insertions(+), 8 deletions(-) create mode 100644 js/src/lib/hooks/useGuideToast.tsx diff --git a/js/src/components/lineage/PreviewChangeView.tsx b/js/src/components/lineage/PreviewChangeView.tsx index 48c74489..38a0f28f 100644 --- a/js/src/components/lineage/PreviewChangeView.tsx +++ b/js/src/components/lineage/PreviewChangeView.tsx @@ -37,6 +37,7 @@ import { trackPreviewChange, trackPreviewChangeFeedback, } from "@/lib/api/track"; +import { useGuideToast } from "@/lib/hooks/useGuideToast"; interface PreviewChangeViewProps { isOpen: boolean; @@ -52,7 +53,6 @@ function PreviewChangeTopBar({ onRunResultOpen, runQuery, isPending, - feedbackToast, }: { current?: NodeData; primaryKeys: string[]; @@ -60,7 +60,6 @@ function PreviewChangeTopBar({ onRunResultOpen: () => void; runQuery: () => void; isPending: boolean; - feedbackToast: () => void; }) { return ( { onRunResultOpen(); runQuery(); - setTimeout(() => feedbackToast(), 3000); }} colorScheme="blue" isLoading={isPending} @@ -165,6 +163,7 @@ export function PreviewChangeView({ return await waitRun(run_id); }; + const { mutate: runQuery, isPending } = useMutation({ mutationFn: queryFn, onSuccess(data, variables) { @@ -180,9 +179,12 @@ export function PreviewChangeView({ node: current?.name, status: "success", }); + setTimeout(() => feedbackToast(), 1000); + setTimeout(() => prepareEnvToast(), 3000); } }, }); + const { feedbackToast, closeToast } = useFeedbackCollectionToast({ feedbackId: localStorageKeys.previewChangeFeedbackID, description: "Enjoy preview change?", @@ -210,6 +212,13 @@ export function PreviewChangeView({ externalLinkText: "Give us feedback", }); + const { guideToast: prepareEnvToast, closeGuideToast } = useGuideToast({ + guideId: localStorageKeys.prepareEnvGuideID, + description: "Want to compare data changes with production data?", + externalLink: "https://datarecce.io/docs", + externalLinkText: "Learn how.", + }); + useEffect(() => { if (isOpen) { setModifiedCode(current?.raw_code || ""); @@ -225,6 +234,7 @@ export function PreviewChangeView({ onRunResultClose(); clearRunResult(); closeToast(); + closeGuideToast(); trackPreviewChange({ action: "close", node: current?.name }); }} > @@ -276,7 +286,6 @@ export function PreviewChangeView({ onRunResultOpen={onRunResultOpen} runQuery={runQuery} isPending={isPending} - feedbackToast={feedbackToast} /> @@ -296,7 +305,10 @@ export function PreviewChangeView({ icon={} variant={"ghost"} size={"md"} - onClick={() => feedbackToast(true)} + onClick={() => { + feedbackToast(true); + prepareEnvToast(true); + }} /> diff --git a/js/src/lib/api/localStorageKeys.ts b/js/src/lib/api/localStorageKeys.ts index 6161e36e..25d44f43 100644 --- a/js/src/lib/api/localStorageKeys.ts +++ b/js/src/lib/api/localStorageKeys.ts @@ -3,4 +3,5 @@ const prefix = "recce-"; export const localStorageKeys = { bypassSaveOverwrite: `${prefix}-bypass-save-overwrite`, previewChangeFeedbackID: `${prefix}-preview-change-feedback`, + prepareEnvGuideID: `${prefix}-prepare-env`, }; diff --git a/js/src/lib/hooks/useFeedbackCollectionToast.tsx b/js/src/lib/hooks/useFeedbackCollectionToast.tsx index 4ab3ea02..5d401700 100644 --- a/js/src/lib/hooks/useFeedbackCollectionToast.tsx +++ b/js/src/lib/hooks/useFeedbackCollectionToast.tsx @@ -9,6 +9,8 @@ import { HStack, CloseButton, } from "@chakra-ui/react"; +import { useGuideToast } from "./useGuideToast"; +import { localStorageKeys } from "../api/localStorageKeys"; function ReactionFeedback({ description, @@ -71,6 +73,12 @@ export function useFeedbackCollectionToast(options: { externalLinkText?: string; }) { const toast = useToast(); + const { guideToast: prepareEnvToast } = useGuideToast({ + guideId: localStorageKeys.prepareEnvGuideID, + description: "Want to compare data changes with production data?", + externalLink: "https://datarecce.io/docs", + externalLinkText: "Learn how.", + }); const { feedbackId, description, @@ -110,21 +118,29 @@ export function useFeedbackCollectionToast(options: { description={description} onLike={() => { onFeedbackSubmit("like"); - toast.closeAll(); + onClose(); + prepareEnvToast(); localStorage.setItem(feedbackId, "true"); }} onDislike={() => { onFeedbackSubmit("dislike"); - toast.closeAll(); + onClose(); + prepareEnvToast(); localStorage.setItem(feedbackId, "true"); }} externalLink={externalLink} externalLinkText={externalLinkText} onClickLink={() => { onFeedbackSubmit("link"); + prepareEnvToast(); + }} + /> + { + onClose(); + prepareEnvToast(); }} /> - diff --git a/js/src/lib/hooks/useGuideToast.tsx b/js/src/lib/hooks/useGuideToast.tsx new file mode 100644 index 00000000..69d2f272 --- /dev/null +++ b/js/src/lib/hooks/useGuideToast.tsx @@ -0,0 +1,80 @@ +import { + useToast, + Alert, + AlertDescription, + Link, + HStack, + CloseButton, + Text, +} from "@chakra-ui/react"; + +export function useGuideToast(options: { + guideId: string; + description: string; + externalLink?: string; + externalLinkText?: string; +}) { + const toast = useToast(); + const { guideId, description, externalLink, externalLinkText } = options; + + function guideToast(skipBypassGuide: boolean = false) { + const isSkipGuide = localStorage.getItem(guideId); + if (isSkipGuide === "true" && skipBypassGuide === false) { + return; + } + + if (toast.isActive(guideId)) { + // Don't show the toast again if it's already active + return; + } + + toast({ + id: guideId, + position: "bottom-right", + duration: null, + description: "some text", + render: ({ id, onClose }) => ( + + + + + {description}{" "} + { + onClose(); + localStorage.setItem(guideId, "true"); + }} + > + {externalLinkText} + + + { + onClose(); + localStorage.setItem(guideId, "true"); + }} + /> + + + + ), + }); + } + + return { + guideToast: guideToast, + closeGuideToast: () => toast.closeAll(), + }; +} From e249fac6a7eee8f8e6f18c446975f87a48d3d020 Mon Sep 17 00:00:00 2001 From: "Wei-Chun, Chang" Date: Tue, 31 Dec 2024 14:24:39 +0700 Subject: [PATCH 2/2] Update prepare env toast behavior Signed-off-by: Wei-Chun, Chang --- js/src/components/lineage/PreviewChangeView.tsx | 9 +++++++-- js/src/lib/hooks/useFeedbackCollectionToast.tsx | 12 ------------ js/src/lib/hooks/useGuideToast.tsx | 11 ++--------- 3 files changed, 9 insertions(+), 23 deletions(-) diff --git a/js/src/components/lineage/PreviewChangeView.tsx b/js/src/components/lineage/PreviewChangeView.tsx index 38a0f28f..d0124472 100644 --- a/js/src/components/lineage/PreviewChangeView.tsx +++ b/js/src/components/lineage/PreviewChangeView.tsx @@ -38,6 +38,7 @@ import { trackPreviewChangeFeedback, } from "@/lib/api/track"; import { useGuideToast } from "@/lib/hooks/useGuideToast"; +import { useRecceServerFlag } from "@/lib/hooks/useRecceServerFlag"; interface PreviewChangeViewProps { isOpen: boolean; @@ -146,6 +147,7 @@ export function PreviewChangeView({ ); const { showRunId, clearRunResult } = useRecceActionContext(); const { primaryKeys, setPrimaryKeys } = useRecceQueryContext(); + const { data: flags, isLoading } = useRecceServerFlag(); const queryFn = async () => { const sqlTemplate = modifiedCode; @@ -180,7 +182,11 @@ export function PreviewChangeView({ status: "success", }); setTimeout(() => feedbackToast(), 1000); - setTimeout(() => prepareEnvToast(), 3000); + setTimeout(() => { + if (!isLoading && flags?.single_env_onboarding) { + prepareEnvToast(); + } + }, 2000); } }, }); @@ -307,7 +313,6 @@ export function PreviewChangeView({ size={"md"} onClick={() => { feedbackToast(true); - prepareEnvToast(true); }} /> diff --git a/js/src/lib/hooks/useFeedbackCollectionToast.tsx b/js/src/lib/hooks/useFeedbackCollectionToast.tsx index 5d401700..175c04de 100644 --- a/js/src/lib/hooks/useFeedbackCollectionToast.tsx +++ b/js/src/lib/hooks/useFeedbackCollectionToast.tsx @@ -9,8 +9,6 @@ import { HStack, CloseButton, } from "@chakra-ui/react"; -import { useGuideToast } from "./useGuideToast"; -import { localStorageKeys } from "../api/localStorageKeys"; function ReactionFeedback({ description, @@ -73,12 +71,6 @@ export function useFeedbackCollectionToast(options: { externalLinkText?: string; }) { const toast = useToast(); - const { guideToast: prepareEnvToast } = useGuideToast({ - guideId: localStorageKeys.prepareEnvGuideID, - description: "Want to compare data changes with production data?", - externalLink: "https://datarecce.io/docs", - externalLinkText: "Learn how.", - }); const { feedbackId, description, @@ -119,26 +111,22 @@ export function useFeedbackCollectionToast(options: { onLike={() => { onFeedbackSubmit("like"); onClose(); - prepareEnvToast(); localStorage.setItem(feedbackId, "true"); }} onDislike={() => { onFeedbackSubmit("dislike"); onClose(); - prepareEnvToast(); localStorage.setItem(feedbackId, "true"); }} externalLink={externalLink} externalLinkText={externalLinkText} onClickLink={() => { onFeedbackSubmit("link"); - prepareEnvToast(); }} /> { onClose(); - prepareEnvToast(); }} /> diff --git a/js/src/lib/hooks/useGuideToast.tsx b/js/src/lib/hooks/useGuideToast.tsx index 69d2f272..3ff151a1 100644 --- a/js/src/lib/hooks/useGuideToast.tsx +++ b/js/src/lib/hooks/useGuideToast.tsx @@ -17,12 +17,7 @@ export function useGuideToast(options: { const toast = useToast(); const { guideId, description, externalLink, externalLinkText } = options; - function guideToast(skipBypassGuide: boolean = false) { - const isSkipGuide = localStorage.getItem(guideId); - if (isSkipGuide === "true" && skipBypassGuide === false) { - return; - } - + function guideToast() { if (toast.isActive(guideId)) { // Don't show the toast again if it's already active return; @@ -31,7 +26,7 @@ export function useGuideToast(options: { toast({ id: guideId, position: "bottom-right", - duration: null, + duration: 3000, description: "some text", render: ({ id, onClose }) => ( { onClose(); - localStorage.setItem(guideId, "true"); }} > {externalLinkText} @@ -63,7 +57,6 @@ export function useGuideToast(options: { { onClose(); - localStorage.setItem(guideId, "true"); }} />