-
Notifications
You must be signed in to change notification settings - Fork 3.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
chore: Side by Side exits beta phase #38347
base: release
Are you sure you want to change the base?
Changes from all commits
897f7f2
559613d
4c2664f
f105539
af69363
3e673c8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import React, { useEffect, useState } from "react"; | ||
import { Flex, Popover, Text } from "@appsmith/ads"; | ||
import * as Styled from "./styles"; | ||
import type { Align, Side } from "@radix-ui/react-popper"; | ||
|
||
interface Props { | ||
trigger: React.ReactNode; | ||
onDismissClick: () => void; | ||
message: string; | ||
align?: Align; | ||
side?: Side; | ||
delayOpen?: number; | ||
} | ||
|
||
export const Nudge = (props: Props) => { | ||
const [open, setOpen] = useState(false); | ||
|
||
useEffect( | ||
function handleDelayOpenOnMount() { | ||
const timer = setTimeout(() => { | ||
setOpen(true); | ||
}, props.delayOpen || 0); | ||
|
||
return () => clearTimeout(timer); | ||
}, | ||
[props.delayOpen], | ||
); | ||
|
||
return ( | ||
<Popover open={open}> | ||
<Styled.PopoverTrigger data-active={open}> | ||
{props.trigger} | ||
</Styled.PopoverTrigger> | ||
<Styled.PopoverContent align={props.align} side={props.side} size="sm"> | ||
<Flex | ||
alignItems="flex-start" | ||
backgroundColor="var(--ads-v2-color-bg-emphasis-max)" | ||
gap="spaces-2" | ||
> | ||
<Text color="#fff" kind="heading-xs"> | ||
{props.message} | ||
</Text> | ||
<Styled.CloseIcon | ||
name="close-line" | ||
onClick={props.onDismissClick} | ||
size="md" | ||
/> | ||
</Flex> | ||
</Styled.PopoverContent> | ||
</Popover> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { Nudge } from "./Nudge"; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
import styled from "styled-components"; | ||
import { | ||
Icon, | ||
PopoverContent as ADSPopoverContent, | ||
PopoverTrigger as ADSPopoverTrigger, | ||
} from "@appsmith/ads"; | ||
|
||
export const PopoverContent = styled(ADSPopoverContent)` | ||
background: var(--ads-v2-color-bg-emphasis-max); | ||
box-shadow: 0 1px 20px 0 #4c56641c; | ||
border: none; | ||
`; | ||
|
||
export const PopoverTrigger = styled(ADSPopoverTrigger)` | ||
border: 2px solid transparent !important; | ||
|
||
&[data-active="true"] { | ||
border: 2px solid var(--ads-v2-color-blue-300) !important; | ||
} | ||
|
||
transition: border 0.2s cubic-bezier(0.22, 0.61, 0.36, 1); | ||
`; | ||
|
||
export const CloseIcon = styled(Icon)` | ||
svg { | ||
path { | ||
fill: #ffffff; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we use ADS color variables for this one? |
||
} | ||
} | ||
|
||
padding: var(--ads-v2-spaces-2); | ||
cursor: pointer; | ||
border-radius: var(--ads-v2-border-radius); | ||
|
||
&:hover { | ||
background-color: #ffffff33; | ||
} | ||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
import React, { useCallback } from "react"; | ||
import React, { useCallback, useMemo } from "react"; | ||
import { useDispatch, useSelector } from "react-redux"; | ||
import { Button, Tooltip } from "@appsmith/ads"; | ||
|
||
|
@@ -14,6 +14,8 @@ import { setIdeEditorViewMode } from "actions/ideActions"; | |
import type { AppState } from "ee/reducers"; | ||
import { selectFeatureFlagCheck } from "ee/selectors/featureFlagsSelectors"; | ||
import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; | ||
import { Nudge } from "IDE/Components/Nudge"; | ||
import { useShowSideBySideNudge } from "../hooks"; | ||
|
||
export const ScreenModeToggle = () => { | ||
const dispatch = useDispatch(); | ||
|
@@ -41,19 +43,38 @@ export const ScreenModeToggle = () => { | |
} | ||
}, [dispatch, isAnimatedIDEEnabled]); | ||
|
||
const [showNudge, dismissNudge] = useShowSideBySideNudge(); | ||
|
||
const switchToSplitScreen = useCallback(() => { | ||
AnalyticsUtil.logEvent("EDITOR_MODE_CHANGE", { | ||
to: EditorViewMode.SplitScreen, | ||
}); | ||
|
||
dismissNudge(); | ||
|
||
if ("startViewTransition" in document && isAnimatedIDEEnabled) { | ||
document.startViewTransition(() => { | ||
dispatch(setIdeEditorViewMode(EditorViewMode.SplitScreen)); | ||
}); | ||
} else { | ||
dispatch(setIdeEditorViewMode(EditorViewMode.SplitScreen)); | ||
} | ||
}, [dispatch, isAnimatedIDEEnabled]); | ||
}, [dispatch, dismissNudge, isAnimatedIDEEnabled]); | ||
|
||
const maximiseButton = useMemo( | ||
() => ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thats a miss. The name should be minimiseButton |
||
<Button | ||
className="ml-auto !min-w-[24px]" | ||
data-testid={"t--ide-minimize"} | ||
id={"editor-mode-minimize"} | ||
isIconButton | ||
kind="tertiary" | ||
onClick={switchToSplitScreen} | ||
startIcon={"minimize-v3"} | ||
/> | ||
), | ||
[switchToSplitScreen], | ||
); | ||
|
||
if (ideViewMode === EditorViewMode.SplitScreen) { | ||
return ( | ||
|
@@ -74,20 +95,26 @@ export const ScreenModeToggle = () => { | |
); | ||
} | ||
|
||
if (showNudge) { | ||
return ( | ||
<Nudge | ||
align="center" | ||
delayOpen={500} | ||
message="Write code and configure UI elements side by side" | ||
onDismissClick={dismissNudge} | ||
side="left" | ||
trigger={maximiseButton} | ||
/> | ||
); | ||
} | ||
|
||
return ( | ||
<Tooltip | ||
content={createMessage(MINIMIZE_BUTTON_TOOLTIP)} | ||
key={createMessage(MINIMIZE_BUTTON_TOOLTIP)} | ||
placement="left" | ||
> | ||
<Button | ||
className="ml-auto !min-w-[24px]" | ||
data-testid={"t--ide-minimize"} | ||
id={"editor-mode-minimize"} | ||
isIconButton | ||
kind="tertiary" | ||
onClick={switchToSplitScreen} | ||
startIcon={"minimize-v3"} | ||
/> | ||
{maximiseButton} | ||
</Tooltip> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,11 @@ import { getCurrentBasePageId } from "selectors/editorSelectors"; | |
import { getCurrentEntityInfo } from "../utils"; | ||
import { useEditorType } from "ee/hooks"; | ||
import { useParentEntityInfo } from "ee/hooks/datasourceEditorHooks"; | ||
import { useBoolean } from "usehooks-ts"; | ||
import { isWidgetActionConnectionPresent } from "selectors/onboardingSelectors"; | ||
import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; | ||
import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; | ||
import localStorage, { LOCAL_STORAGE_KEYS } from "utils/localStorage"; | ||
|
||
export const useCurrentEditorState = () => { | ||
const [selectedSegment, setSelectedSegment] = useState<EditorEntityTab>( | ||
|
@@ -198,3 +203,25 @@ export const useIDETabClickHandlers = () => { | |
|
||
return { addClickHandler, tabClickHandler, closeClickHandler }; | ||
}; | ||
|
||
export const useShowSideBySideNudge: () => [boolean, () => void] = () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not a big deal at this point, but I would suggest to put hooks in separate files. [nit] |
||
const widgetBindingsExist = useSelector(isWidgetActionConnectionPresent); | ||
|
||
const localStorageFlag = | ||
localStorage.getItem(LOCAL_STORAGE_KEYS.NUDGE_SHOWN_SPLIT_PANE) || "false"; | ||
|
||
const isActionRedesignEnabled = useFeatureFlag( | ||
FEATURE_FLAG.release_actions_redesign_enabled, | ||
); | ||
|
||
const { setFalse, value } = useBoolean( | ||
widgetBindingsExist && isActionRedesignEnabled && !localStorageFlag, | ||
); | ||
|
||
const dismissNudge = useCallback(() => { | ||
setFalse(); | ||
localStorage.setItem(LOCAL_STORAGE_KEYS.NUDGE_SHOWN_SPLIT_PANE, "true"); | ||
}, [setFalse]); | ||
|
||
return [value, dismissNudge]; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ADS color variable?