diff --git a/src/components/Admin/Reports/CodeIssues/IssuesSidebar/index.tsx b/src/components/Admin/Reports/CodeIssues/IssuesSidebar/index.tsx index 223679f70..7d0120c07 100644 --- a/src/components/Admin/Reports/CodeIssues/IssuesSidebar/index.tsx +++ b/src/components/Admin/Reports/CodeIssues/IssuesSidebar/index.tsx @@ -1,7 +1,12 @@ import { useEffect, useRef, useState } from "react"; import { CSSTransition } from "react-transition-group"; import { useTheme } from "styled-components"; +import { + useAdminDispatch, + useAdminSelector +} from "../../../../../containers/Admin/hooks"; import { useGetIssuesQuery } from "../../../../../redux/services/digma"; +import { setIsInsightJiraTicketHintShown } from "../../../../../redux/slices/persistSlice"; import { isUndefined } from "../../../../../typeGuards/isUndefined"; import type { Scope } from "../../../../common/App/types"; import { CrossIcon } from "../../../../common/icons/16px/CrossIcon"; @@ -15,30 +20,58 @@ import { EmptyState as InsightsPageEmptyState } from "../../../../Insights/Insig import { InsightCardRenderer } from "../../../../Insights/InsightsCatalog/InsightsPage/InsightCardRenderer"; import { ViewMode } from "../../../../Insights/InsightsCatalog/types"; import { InsightTicketRenderer } from "../../../../Insights/InsightTicketRenderer"; -import type { - GenericCodeObjectInsight, - InsightTicketInfo +import { + InsightType, + type CodeObjectInsight, + type GenericCodeObjectInsight, + type InsightTicketInfo } from "../../../../Insights/types"; import { ScopeBar } from "../../../../Navigation/ScopeBar"; import * as s from "./styles"; import { SuggestionBar } from "./SuggestionBar"; -import type { IssuesHeaderProps } from "./types"; +import type { IssuesSidebarProps } from "./types"; const PAGE_SIZE = 10; +const getInsightToShowJiraHint = (insights: CodeObjectInsight[]): number => { + const insightsWithJiraButton = [ + InsightType.EndpointSpanNPlusOne, + InsightType.SpaNPlusOne, + InsightType.SpanEndpointBottleneck, + InsightType.EndpointBottleneck, + InsightType.SpanQueryOptimization, + InsightType.EndpointHighNumberOfQueries, + InsightType.EndpointQueryOptimizationV2, + InsightType.SpanScaling + ]; + + return insights.findIndex((insight) => + insightsWithJiraButton.includes(insight.type) + ); +}; + export const IssuesSidebar = ({ onClose, scope, environmentId, - viewLevel -}: IssuesHeaderProps) => { + viewLevel, + isTransitioning, + isResizing +}: IssuesSidebarProps) => { const [infoToOpenJiraTicket, setInfoToOpenJiraTicket] = useState>(); const [viewMode, setViewMode] = useState(ViewMode.All); const [page, setPage] = useState(0); const [insightIdToOpenSuggestion, setInsightIdToOpenSuggestion] = useState(); + const [isDrawerTransitioning, setIsDrawerTransitioning] = useState(false); const drawerRef = useRef(null); + const dispatch = useAdminDispatch(); + const isInsightJiraTicketHintShown = useAdminSelector( + (state) => state.persist.isInsightJiraTicketHintShown + ); + const isDrawerOpen = Boolean(insightIdToOpenSuggestion); + const issuesListRef = useRef(null); const theme = useTheme(); const { data, isFetching, refetch } = useGetIssuesQuery( @@ -107,6 +140,7 @@ export const IssuesSidebar = ({ insight: GenericCodeObjectInsight, spanCodeObjectId?: string ) => { + dispatch(setIsInsightJiraTicketHintShown(true)); setInfoToOpenJiraTicket({ insight, spanCodeObjectId }); }; @@ -122,6 +156,14 @@ export const IssuesSidebar = ({ setInsightIdToOpenSuggestion(undefined); }; + const handleDrawerTransitionStart = () => { + setIsDrawerTransitioning(true); + }; + + const handleDrawerTransitionEnd = () => { + setIsDrawerTransitioning(false); + }; + const dismissedCount = data?.dismissedCount; const totalCount = data?.totalCount ?? 0; const pageStartItemNumber = page * PAGE_SIZE + 1; @@ -151,7 +193,7 @@ export const IssuesSidebar = ({ }; return ( - + Issues @@ -171,20 +213,27 @@ export const IssuesSidebar = ({ {data ? ( data.insights.length > 0 ? ( - + {environmentId && - data.insights.map((insight) => ( + data.insights.map((insight, i) => ( ))} @@ -246,12 +295,16 @@ export const IssuesSidebar = ({ )} ` background: ${({ theme }) => `linear-gradient(0deg, ${theme.colors.v3.surface.primary} 0%, ${theme.colors.v3.surface.primary} 100%), #fff`}; display: flex; flex-direction: column; border-radius: 8px 0 0 8px; height: 100%; + user-select: ${({ $isResizing }) => ($isResizing ? "none" : "auto")}; `; export const Header = styled.div` diff --git a/src/components/Admin/Reports/CodeIssues/IssuesSidebar/types.ts b/src/components/Admin/Reports/CodeIssues/IssuesSidebar/types.ts index f32e10640..9da549040 100644 --- a/src/components/Admin/Reports/CodeIssues/IssuesSidebar/types.ts +++ b/src/components/Admin/Reports/CodeIssues/IssuesSidebar/types.ts @@ -1,6 +1,6 @@ import type { IssuesReportViewLevel } from "../../../../../redux/slices/issuesReportSlice"; -export interface IssuesHeaderProps { +export interface IssuesSidebarProps { onClose: () => void; environmentId?: string; scope?: { @@ -8,9 +8,15 @@ export interface IssuesHeaderProps { displayName?: string; }; viewLevel: IssuesReportViewLevel; + isTransitioning: boolean; + isResizing?: boolean; } export interface DrawerContainerProps { $transitionDuration: number; $transitionClassName: string; } + +export interface ContainerProps { + $isResizing?: boolean; +} diff --git a/src/components/Admin/Reports/CodeIssues/index.tsx b/src/components/Admin/Reports/CodeIssues/index.tsx index c754e28b2..414c9ab29 100644 --- a/src/components/Admin/Reports/CodeIssues/index.tsx +++ b/src/components/Admin/Reports/CodeIssues/index.tsx @@ -1,4 +1,4 @@ -import { useRef, useState } from "react"; +import { useEffect, useRef, useState } from "react"; import { CSSTransition } from "react-transition-group"; import { useAdminDispatch, @@ -19,19 +19,44 @@ import { type IssuesReportViewLevel, type IssuesReportViewMode } from "../../../../redux/slices/issuesReportSlice"; +import { TwoVerticalLinesIcon } from "../../../common/icons/16px/TwoVerticalLinesIcon"; import { IssuesReport } from "../../../common/IssuesReport"; import type { TargetScope } from "../../../common/IssuesReport/types"; import { IssuesSidebar } from "./IssuesSidebar"; import * as s from "./styles"; +export const MIN_SIDEBAR_WIDTH = 382; // in pixels +export const MAX_SIDEBAR_WIDTH = 640; // in pixels +export const DEFAULT_SIDEBAR_WIDTH_RATIO = 0.33; + +export const getDefaultSidebarWidth = (windowWidth: number) => { + const defaultWidth = windowWidth * DEFAULT_SIDEBAR_WIDTH_RATIO; + if (defaultWidth > MAX_SIDEBAR_WIDTH) { + return MAX_SIDEBAR_WIDTH; + } + + if (defaultWidth < MIN_SIDEBAR_WIDTH) { + return MIN_SIDEBAR_WIDTH; + } + + return defaultWidth; +}; + export const CodeIssues = () => { - const [isSidebarOpen, setIsSidebarOpen] = useState(false); + const [isIssuesSidebarOpen, setIsIssuesSidebarOpen] = useState(false); const [scope, setScope] = useState<{ value: string; displayName?: string }>(); const [activeTileIds, setActiveTileIds] = useState( undefined ); const sidebarContainerRef = useRef(null); const overlayRef = useRef(null); + const [isIssuesSidebarTransitioning, setIsIssuesSidebarTransitioning] = + useState(false); + const defaultSidebarWidth = getDefaultSidebarWidth(window.innerWidth); + const [isResizeHandlePressed, setIsResizeHandlePressed] = useState(false); + const [startX, setStartX] = useState(0); + const [left, setLeft] = useState(window.innerWidth - defaultSidebarWidth); + const [startLeft, setStartLeft] = useState(0); const selectedEnvironmentId = useAdminSelector( (state) => state.codeIssuesReport.selectedEnvironmentId @@ -65,7 +90,7 @@ export const CodeIssues = () => { ) => { if (viewMode === "table" && viewLevel === "endpoints") { setScope(target); - setIsSidebarOpen(true); + setIsIssuesSidebarOpen(true); setActiveTileIds([target.value]); } }; @@ -75,7 +100,7 @@ export const CodeIssues = () => { target: TargetScope ) => { setScope(target); - setIsSidebarOpen(true); + setIsIssuesSidebarOpen(true); setActiveTileIds([target.value]); }; @@ -116,10 +141,52 @@ export const CodeIssues = () => { }; const handleIssuesSidebarClose = () => { - setIsSidebarOpen(false); + setIsIssuesSidebarOpen(false); setActiveTileIds(undefined); }; + const handleIssuesSidebarTransitionStart = () => { + setIsIssuesSidebarTransitioning(true); + }; + + const handleIssuesSidebarTransitionEnd = () => { + setIsIssuesSidebarTransitioning(false); + }; + + const handleResizeHandleMouseDown = (e: React.MouseEvent) => { + setIsResizeHandlePressed(true); + setStartX(e.clientX); + setStartLeft(left); + }; + + useEffect(() => { + if (!isResizeHandlePressed) { + return; + } + + const handleMouseMove = (e: MouseEvent) => { + const newLeft = startLeft + (e.clientX - startX); + if ( + newLeft >= window.innerWidth - MAX_SIDEBAR_WIDTH && + newLeft <= window.innerWidth - MIN_SIDEBAR_WIDTH + ) { + setLeft(newLeft); + } + }; + + const handleMouseUp = () => { + setIsResizeHandlePressed(false); + }; + + document.addEventListener("mousemove", handleMouseMove); + document.addEventListener("mouseup", handleMouseUp); + + return () => { + document.removeEventListener("mousemove", handleMouseMove); + document.removeEventListener("mouseup", handleMouseUp); + }; + }, [isResizeHandlePressed, startX, startLeft, left]); + return ( { activeTileIds={activeTileIds} /> { > + + + diff --git a/src/components/Admin/Reports/CodeIssues/styles.ts b/src/components/Admin/Reports/CodeIssues/styles.ts index e265df95f..de7c84827 100644 --- a/src/components/Admin/Reports/CodeIssues/styles.ts +++ b/src/components/Admin/Reports/CodeIssues/styles.ts @@ -43,7 +43,6 @@ export const IssuesSidebarContainer = styled.div` right: 0; top: 0; bottom: 0; - width: 382px; ${({ $transitionClassName, $transitionDuration }) => ` &.${$transitionClassName}-enter { @@ -65,3 +64,20 @@ export const IssuesSidebarContainer = styled.div` } `} `; + +export const ResizeHandle = styled.div` + width: 16px; + cursor: ew-resize; + position: absolute; + top: 0; + bottom: 0; + left: 0; + display: flex; + align-items: center; + justify-content: center; + color: ${({ theme }) => theme.colors.v3.icon.disabled}; + + &:hover { + color: ${({ theme }) => theme.colors.v3.icon.secondary}; + } +`; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/index.tsx index ad2c51ac0..66f6c1279 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/index.tsx @@ -66,7 +66,8 @@ export const InsightCardRenderer = ({ viewMode, environmentId, onDismissalChange, - onOpenSuggestion + onOpenSuggestion, + tooltipBoundaryRef }: InsightCardRendererProps) => { const [triggerSpanPercentilesHistogramFetch] = useLazyGetSpanPercentilesHistogramQuery(); @@ -203,6 +204,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -219,6 +221,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -236,6 +239,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -255,6 +259,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -274,6 +279,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -289,6 +295,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -308,6 +315,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -327,6 +335,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -346,6 +355,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -366,6 +376,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -382,6 +393,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -397,6 +409,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -414,6 +427,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -431,6 +445,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -449,6 +464,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -464,6 +480,7 @@ export const InsightCardRenderer = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -484,6 +501,7 @@ export const InsightCardRenderer = ({ viewMode={viewMode} onDismissalChange={onDismissalChange} onOpenSuggestion={onOpenSuggestion} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } @@ -504,6 +522,7 @@ export const InsightCardRenderer = ({ viewMode={viewMode} onDismissalChange={onDismissalChange} onOpenSuggestion={onOpenSuggestion} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); } diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBottleneckInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBottleneckInsightCard/index.tsx index 1988060ee..6a56bd7ed 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBottleneckInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBottleneckInsightCard/index.tsx @@ -17,7 +17,8 @@ export const EndpointBottleneckInsightCard = ({ onRefresh, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: EndpointBottleneckInsightCardProps) => { const { span, ticketLink } = insight; @@ -103,6 +104,7 @@ export const EndpointBottleneckInsightCard = ({ } onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBreakdownInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBreakdownInsightCard/index.tsx index 5536e778f..1e7dee514 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBreakdownInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBreakdownInsightCard/index.tsx @@ -97,7 +97,8 @@ export const EndpointBreakdownInsightCard = ({ onGoToSpan, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: EndpointBreakdownInsightCardProps) => { const theme = useTheme(); @@ -264,6 +265,7 @@ export const EndpointBreakdownInsightCard = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointChattyApiV2InsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointChattyApiV2InsightCard/index.tsx index 6f3005abd..d0df27dc4 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointChattyApiV2InsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointChattyApiV2InsightCard/index.tsx @@ -16,7 +16,8 @@ export const EndpointChattyApiV2InsightCard = ({ onGoToSpan, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: EndpointChattyApiV2InsightCardProps) => { const handleSpanLinkClick = (spanCodeObjectId: string) => { onAssetLinkClick(spanCodeObjectId, insight.type); @@ -74,6 +75,7 @@ export const EndpointChattyApiV2InsightCard = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointHighNumberOfQueriesInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointHighNumberOfQueriesInsightCard/index.tsx index eae38667b..ffb06d579 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointHighNumberOfQueriesInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointHighNumberOfQueriesInsightCard/index.tsx @@ -16,7 +16,8 @@ export const EndpointHighNumberOfQueriesInsightCard = ({ onGoToSpan, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: EndpointHighNumberOfQueriesInsightCardProps) => { const traceId = insight.traceId; @@ -89,6 +90,7 @@ export const EndpointHighNumberOfQueriesInsightCard = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointQueryOptimizationV2InsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointQueryOptimizationV2InsightCard/index.tsx index 705bbba6c..b6e6e353f 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointQueryOptimizationV2InsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointQueryOptimizationV2InsightCard/index.tsx @@ -19,7 +19,8 @@ export const EndpointQueryOptimizationV2InsightCard = ({ isMarkAsReadButtonEnabled, viewMode, onDismissalChange, - onOpenSuggestion + onOpenSuggestion, + tooltipBoundaryRef }: EndpointQueryOptimizationV2InsightCardProps) => { const handleSpanLinkClick = (spanCodeObjectId: string) => { onAssetLinkClick(spanCodeObjectId, insight.type); @@ -95,6 +96,7 @@ export const EndpointQueryOptimizationV2InsightCard = ({ } onDismissalChange={onDismissalChange} onOpenSuggestion={onOpenSuggestion} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointSessionInViewInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointSessionInViewInsightCard/index.tsx index 671613249..e88b5ff8b 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointSessionInViewInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointSessionInViewInsightCard/index.tsx @@ -22,7 +22,8 @@ export const EndpointSessionInViewInsightCard = ({ onGoToSpan, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: EndpointSessionInViewInsightCardProps) => { const { isJaegerEnabled } = useConfigSelector(); @@ -103,6 +104,7 @@ export const EndpointSessionInViewInsightCard = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointSlowdownSourceInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointSlowdownSourceInsightCard/index.tsx index c73e26f82..7e3abb918 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointSlowdownSourceInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointSlowdownSourceInsightCard/index.tsx @@ -14,7 +14,8 @@ export const EndpointSlowdownSourceInsightCard = ({ onGoToSpan, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: EndpointSlowdownSourceInsightCardProps) => { const handleSpanLinkClick = (spanCodeObjectId: string) => { onAssetLinkClick(spanCodeObjectId, insight.type); @@ -81,6 +82,7 @@ export const EndpointSlowdownSourceInsightCard = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointSpanNPlusOneInsightInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointSpanNPlusOneInsightInsightCard/index.tsx index f64f54a97..4aea1048f 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointSpanNPlusOneInsightInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointSpanNPlusOneInsightInsightCard/index.tsx @@ -18,7 +18,8 @@ export const EndpointSpanNPlusOneInsightCard = ({ onRefresh, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: EndpointSpanNPlusOneInsightCardProps) => { const { span } = insight; @@ -109,6 +110,7 @@ export const EndpointSpanNPlusOneInsightCard = ({ } onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointUsageInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointUsageInsightCard/index.tsx index bb2cb3fdb..4187825ce 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointUsageInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointUsageInsightCard/index.tsx @@ -49,7 +49,8 @@ export const EndpointUsageInsightCard = ({ onGoToSpan, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: EndpointUsageInsightCardProps) => { const valueString = `${getValueString(insight.maxCallsIn1Min)}/min`; @@ -74,6 +75,7 @@ export const EndpointUsageInsightCard = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SlowEndpointInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SlowEndpointInsightCard/index.tsx index 56627ca97..c8ee7945e 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SlowEndpointInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SlowEndpointInsightCard/index.tsx @@ -15,7 +15,8 @@ export const SlowEndpointInsightCard = ({ onGoToSpan, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: SlowEndpointInsightCardProps) => { const diff = (insight.median.raw / insight.endpointsMedianOfMedians.raw - 1) * 100; @@ -49,6 +50,7 @@ export const SlowEndpointInsightCard = ({ } onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpaNPlusOneInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpaNPlusOneInsightCard/index.tsx index aa6d6069c..69998667b 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpaNPlusOneInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpaNPlusOneInsightCard/index.tsx @@ -42,7 +42,8 @@ export const SpaNPlusOneInsightCard = ({ onGoToSpan, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: SpaNPlusOneInsightCardProps) => { const endpoints = useMemo( () => @@ -204,6 +205,7 @@ export const SpaNPlusOneInsightCard = ({ ) : undefined } onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanDurationBreakdownInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanDurationBreakdownInsightCard/index.tsx index fbcf91187..21df3a1a6 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanDurationBreakdownInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanDurationBreakdownInsightCard/index.tsx @@ -67,7 +67,8 @@ export const SpanDurationBreakdownInsightCard = ({ onGoToSpan, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: SpanDurationBreakdownInsightCardProps) => { const [percentileViewMode, setPercentileViewMode] = useState(DEFAULT_PERCENTILE); @@ -349,6 +350,7 @@ export const SpanDurationBreakdownInsightCard = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanDurationsInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanDurationsInsightCard/index.tsx index 6a5e77936..a068ac1c0 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanDurationsInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanDurationsInsightCard/index.tsx @@ -140,7 +140,8 @@ export const SpanDurationsInsightCard = ({ onGoToSpan, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: SpanDurationsInsightCardProps) => { const theme = useTheme(); const { observe, width } = useDimensions(); @@ -444,6 +445,7 @@ ${getDurationString(insight.average)}${ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanEndpointBottleneckInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanEndpointBottleneckInsightCard/index.tsx index f57ec8007..14c385220 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanEndpointBottleneckInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanEndpointBottleneckInsightCard/index.tsx @@ -46,7 +46,8 @@ export const SpanEndpointBottleneckInsightCard = ({ onGoToSpan, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: SpanEndpointBottleneckInsightCardProps) => { const { isJaegerEnabled } = useConfigSelector(); const slowEndpoints = useMemo( @@ -208,6 +209,7 @@ export const SpanEndpointBottleneckInsightCard = ({ ) : undefined } onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanNexusInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanNexusInsightCard/index.tsx index 96bc29cfb..fd7c6b5b2 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanNexusInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanNexusInsightCard/index.tsx @@ -17,7 +17,8 @@ export const SpanNexusInsightCard = ({ onGoToSpan, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: SpanNexusInsightCardProps) => { const { entries, @@ -72,6 +73,7 @@ export const SpanNexusInsightCard = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanQueryOptimizationInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanQueryOptimizationInsightCard/index.tsx index 1bf3a6570..d5f4f260b 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanQueryOptimizationInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanQueryOptimizationInsightCard/index.tsx @@ -27,7 +27,8 @@ export const SpanQueryOptimizationInsightCard = ({ onJiraTicketCreate, viewMode, onDismissalChange, - onOpenSuggestion + onOpenSuggestion, + tooltipBoundaryRef }: SpanQueryOptimizationInsightCardProps) => { const endpoints = insight.endpoints ?? []; const [pageItems, page, setPage] = usePagination( @@ -146,6 +147,7 @@ export const SpanQueryOptimizationInsightCard = ({ } onDismissalChange={onDismissalChange} onOpenSuggestion={onOpenSuggestion} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanScalingInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanScalingInsightCard/index.tsx index 7bd0d3d7e..3a7a802de 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanScalingInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanScalingInsightCard/index.tsx @@ -33,7 +33,8 @@ export const SpanScalingInsightCard = ({ onGoToSpan, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: SpanScalingInsightCardProps) => { const { isJaegerEnabled } = useConfigSelector(); const affectedEndpoints = insight.affectedEndpoints ?? []; @@ -83,6 +84,7 @@ export const SpanScalingInsightCard = ({ isHintEnabled={isJiraHintEnabled && i === 0} insightType={insight.type} type={"icon"} + boundaryRef={tooltipBoundaryRef} /> ]; @@ -189,6 +191,7 @@ export const SpanScalingInsightCard = ({ } onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanUsagesInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanUsagesInsightCard/index.tsx index a7902f6f8..93182ec3c 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanUsagesInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/SpanUsagesInsightCard/index.tsx @@ -42,7 +42,8 @@ export const SpanUsagesInsightCard = ({ onGoToSpan, isMarkAsReadButtonEnabled, viewMode, - onDismissalChange + onDismissalChange, + tooltipBoundaryRef }: SpanUsagesInsightCardProps) => { const { isJaegerEnabled } = useConfigSelector(); const [data, setData] = useState({ @@ -333,6 +334,7 @@ export const SpanUsagesInsightCard = ({ isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} onDismissalChange={onDismissalChange} + tooltipBoundaryRef={tooltipBoundaryRef} /> ); }; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/common/InsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/common/InsightCard/index.tsx index 92afd1e4d..17c962d39 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/common/InsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/common/InsightCard/index.tsx @@ -52,7 +52,8 @@ export const InsightCard = ({ viewMode, mainMetric, onDismissalChange, - onOpenSuggestion + onOpenSuggestion, + tooltipBoundaryRef }: InsightCardProps) => { const { isDismissalChangeInProgress, @@ -300,6 +301,7 @@ export const InsightCard = ({ label={"Ticket"} onTicketInfoOpen={openTicketInfo} insightType={insight.type} + boundaryRef={tooltipBoundaryRef} /> ); diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/common/InsightCard/types.ts b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/common/InsightCard/types.ts index 0df7ac8fb..b6468872a 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/common/InsightCard/types.ts +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/common/InsightCard/types.ts @@ -1,4 +1,4 @@ -import type { ReactNode } from "react"; +import type { ReactNode, RefObject } from "react"; import type { ScopeSpan } from "../../../../../../../common/App/types"; import type { CardProps } from "../../../../../../../common/v3/Card/types"; import type { @@ -38,6 +38,7 @@ export interface InsightCardProps { mainMetric?: ReactNode; onDismissalChange: (action: string, insightId: string) => void; onOpenSuggestion?: (insightId: string) => void; + tooltipBoundaryRef?: RefObject; } export interface StyledCardProps extends CardProps { @@ -91,6 +92,7 @@ export interface InsightCardCommonProps { viewMode: InsightCardViewMode; onDismissalChange: (action: string, insightId: string) => void; onOpenSuggestion?: (insightId: string) => void; + tooltipBoundaryRef?: RefObject; } export type Action = diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/types.ts b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/types.ts index c52533476..f3478c1ac 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/types.ts +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/types.ts @@ -1,3 +1,4 @@ +import type { RefObject } from "react"; import type { GenericCodeObjectInsight } from "../../../types"; import type { InsightCardViewMode } from "./insightCards/common/InsightCard/types"; @@ -15,4 +16,5 @@ export interface InsightCardRendererProps { environmentId: string; onDismissalChange: (action: string, insightId: string) => void; onOpenSuggestion?: (insightId: string) => void; + tooltipBoundaryRef?: RefObject; } diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/index.tsx index 988cc05cd..8b8cb50db 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/index.tsx @@ -30,8 +30,6 @@ import type { isInsightJiraTicketHintShownPayload } from "./types"; -export const INSIGHTS_PAGE_CONTAINER_ID = "insightsPageContainer"; - const getInsightToShowJiraHint = (insights: CodeObjectInsight[]): number => { const insightsWithJiraButton = [ InsightType.EndpointSpanNPlusOne, @@ -214,7 +212,7 @@ export const InsightsPage = ({ }; return ( - + {environment && insights.length > 0 ? insights.map((insight, j) => ( )) : renderEmptyState( diff --git a/src/components/common/AffectedEndpointsSelector/EndpointOption/index.tsx b/src/components/common/AffectedEndpointsSelector/EndpointOption/index.tsx index d12770d59..f052d0648 100644 --- a/src/components/common/AffectedEndpointsSelector/EndpointOption/index.tsx +++ b/src/components/common/AffectedEndpointsSelector/EndpointOption/index.tsx @@ -15,20 +15,32 @@ export const EndpointOption = ({ }: EndpointOptionProps) => { const title = `${serviceName} ${route}`; + const handleEndpointNameClick = () => { + if (onClick) { + onClick(); + } + }; + + const handleRouteLinkClick = () => { + if (onSpanLinkClick && spanCodeObjectId) { + onSpanLinkClick(spanCodeObjectId); + } + }; + return ( onClick && onClick()} + onClick={handleEndpointNameClick} > {serviceName} {spanCodeObjectId && onSpanLinkClick ? ( - onSpanLinkClick(spanCodeObjectId)}> + {route} - + ) : ( {route} )} diff --git a/src/components/common/AffectedEndpointsSelector/EndpointOption/styles.ts b/src/components/common/AffectedEndpointsSelector/EndpointOption/styles.ts index f450fe41d..fb3e8e6fd 100644 --- a/src/components/common/AffectedEndpointsSelector/EndpointOption/styles.ts +++ b/src/components/common/AffectedEndpointsSelector/EndpointOption/styles.ts @@ -2,7 +2,7 @@ import styled, { css } from "styled-components"; import { footnoteRegularTypography } from "../../App/typographies"; import { CopyButton } from "../../v3/CopyButton"; import { Link as CommonLink } from "../../v3/Link"; -import type { EndpointNameProps } from "./types"; +import type { EndpointNameProps, SpanLinkProps } from "./types"; export const StyledCopyButton = styled(CopyButton)` display: none; @@ -69,8 +69,13 @@ export const Route = styled.span` white-space: nowrap; `; -export const Link = styled(CommonLink)` - width: 100%; +export const RouteLink = styled(CommonLink)` + ${({ $selected }) => + $selected + ? css` + width: 100%; + ` + : ""} `; export const Duration = styled.span` diff --git a/src/components/common/AffectedEndpointsSelector/EndpointOption/types.ts b/src/components/common/AffectedEndpointsSelector/EndpointOption/types.ts index 0fe951736..60da40e6b 100644 --- a/src/components/common/AffectedEndpointsSelector/EndpointOption/types.ts +++ b/src/components/common/AffectedEndpointsSelector/EndpointOption/types.ts @@ -17,3 +17,7 @@ export interface EndpointNameProps { $selected?: boolean; $clickable?: boolean; } + +export interface SpanLinkProps { + $selected?: boolean; +} diff --git a/src/components/common/icons/16px/TwoVerticalLinesIcon.tsx b/src/components/common/icons/16px/TwoVerticalLinesIcon.tsx new file mode 100644 index 000000000..b87e4f709 --- /dev/null +++ b/src/components/common/icons/16px/TwoVerticalLinesIcon.tsx @@ -0,0 +1,26 @@ +import React from "react"; +import { useIconProps } from "../hooks"; +import type { IconProps } from "../types"; + +const TwoVerticalLinesIconComponent = (props: IconProps) => { + const { size, color } = useIconProps(props); + + return ( + + + + ); +}; + +export const TwoVerticalLinesIcon = React.memo(TwoVerticalLinesIconComponent); diff --git a/src/components/common/v3/JiraButton/index.tsx b/src/components/common/v3/JiraButton/index.tsx index 6c7024be5..2325109e7 100644 --- a/src/components/common/v3/JiraButton/index.tsx +++ b/src/components/common/v3/JiraButton/index.tsx @@ -3,7 +3,6 @@ import { forwardRef, useState } from "react"; import { useTheme } from "styled-components"; import { openURLInDefaultBrowser } from "../../../../utils/actions/openURLInDefaultBrowser"; import { sendUserActionTrackingEvent } from "../../../../utils/actions/sendUserActionTrackingEvent"; -import { INSIGHTS_PAGE_CONTAINER_ID } from "../../../Insights/InsightsCatalog/InsightsPage"; import { trackingEvents } from "../../../Insights/tracking"; import { MenuList } from "../../../Navigation/common/MenuList"; import { Popup } from "../../../Navigation/common/Popup"; @@ -25,7 +24,8 @@ export const JiraButtonComponent = ( spanCodeObjectId, type, label, - insightType + insightType, + boundaryRef }: JiraButtonProps, ref: ForwardedRef ) => { @@ -129,13 +129,10 @@ export const JiraButtonComponent = ( ); }; - const boundaryEl = - document.getElementById(INSIGHTS_PAGE_CONTAINER_ID) ?? undefined; - return (
; } diff --git a/src/components/common/v3/Tooltip/index.tsx b/src/components/common/v3/Tooltip/index.tsx index bfb732f96..aa0207c37 100644 --- a/src/components/common/v3/Tooltip/index.tsx +++ b/src/components/common/v3/Tooltip/index.tsx @@ -95,7 +95,10 @@ export const Tooltip = ({ flip({ boundary }), - shift() + shift({ + boundary, + padding: 16 + }) ]; if (!hideArrow) { middlewares.push( diff --git a/src/containers/Admin/store.ts b/src/containers/Admin/store.ts index de6d49274..8227e5ab8 100644 --- a/src/containers/Admin/store.ts +++ b/src/containers/Admin/store.ts @@ -8,10 +8,12 @@ import { digmaApi } from "../../redux/services/digma"; import { appSlice } from "../../redux/slices/appSlice"; import { authSlice } from "../../redux/slices/authSlice"; import issuesReportSlice from "../../redux/slices/issuesReportSlice"; +import { persistSlice } from "../../redux/slices/persistSlice"; import { getRememberEnhancer } from "../../redux/utils/getRememberEnhancer"; import { APP_ID } from "./constants"; -const rememberedKeys = platform === "Web" ? ["auth", "codeIssuesReport"] : []; +const rememberedKeys = + platform === "Web" ? ["auth", "codeIssuesReport", "persist"] : []; const persistPrefix = `${PERSIST_PREFIX}${APP_ID}-`; @@ -19,6 +21,7 @@ const reducer = rememberReducer({ app: appSlice.reducer, auth: authSlice.reducer, codeIssuesReport: issuesReportSlice, + persist: persistSlice.reducer, [authApi.reducerPath]: authApi.reducer, [digmaApi.reducerPath]: digmaApi.reducer }); diff --git a/src/redux/slices/appSlice.ts b/src/redux/slices/appSlice.ts index ccd3519d8..7c5eec331 100644 --- a/src/redux/slices/appSlice.ts +++ b/src/redux/slices/appSlice.ts @@ -4,11 +4,11 @@ import { globalClear } from "../actions"; import { STATE_VERSION } from "../constants"; import type { BaseState } from "./types"; -export interface GlobalState extends BaseState { +export interface AppState extends BaseState { isInitialized: boolean; } -const initialState: GlobalState = { +const initialState: AppState = { version: STATE_VERSION, isInitialized: false }; diff --git a/src/redux/slices/persistSlice.ts b/src/redux/slices/persistSlice.ts new file mode 100644 index 000000000..741833df3 --- /dev/null +++ b/src/redux/slices/persistSlice.ts @@ -0,0 +1,31 @@ +import type { PayloadAction } from "@reduxjs/toolkit"; +import { createSlice } from "@reduxjs/toolkit"; +import { STATE_VERSION } from "../constants"; +import type { BaseState } from "./types"; + +export interface PersistState extends BaseState { + isInsightJiraTicketHintShown: boolean; +} + +const initialState: PersistState = { + version: STATE_VERSION, + isInsightJiraTicketHintShown: false +}; + +export const persistSlice = createSlice({ + name: "persistSlice", + initialState, + reducers: { + setIsInsightJiraTicketHintShown: ( + state, + action: PayloadAction + ) => { + state.isInsightJiraTicketHintShown = action.payload; + }, + clear: () => initialState + } +}); + +export const { setIsInsightJiraTicketHintShown } = persistSlice.actions; + +export default persistSlice.reducer;