From da3680df7511243113f2a0938391d6b30d3d4908 Mon Sep 17 00:00:00 2001 From: Kyrylo Shmidt Date: Fri, 28 Feb 2025 18:43:26 +0100 Subject: [PATCH 1/2] Keep select items order, make filter selector in Web admin always visible --- .../Header/Greeting/Greeting.stories.tsx | 18 +----- .../Admin/Header/Greeting/index.tsx | 15 ++++- .../EnvironmentSelect/index.tsx | 26 ++++----- .../EnvironmentSelect/styles.ts | 3 +- .../FilterMenu/FilterButton/index.tsx | 12 ++-- .../FilterMenu/FilterButton/types.ts | 4 ++ .../{ => HeaderContent}/FilterMenu/index.tsx | 24 ++++++-- .../Admin/Header/HeaderContent/index.tsx | 23 ++++++++ .../Admin/Header/HeaderContent/styles.ts | 17 ++++++ .../Admin/Header/HeaderContent/types.ts | 5 ++ src/components/Admin/Header/index.tsx | 53 ++++++++--------- src/components/Admin/Header/styles.ts | 18 +----- .../Dashboard/MetricsReport/index.tsx | 2 + .../EnvironmentSelector/index.tsx | 27 ++++++--- .../Navigation/EnvironmentBar/index.tsx | 11 +++- .../RecentActivity/EnvironmentPanel/index.tsx | 9 ++- .../common/IssuesReport/Header/index.tsx | 48 +++++++++------- .../common/IssuesReport/Header/types.ts | 2 + src/components/common/IssuesReport/index.tsx | 6 +- src/components/common/IssuesReport/types.ts | 2 + src/components/common/v3/Select/index.tsx | 57 +++++++++++++------ 21 files changed, 238 insertions(+), 144 deletions(-) rename src/components/Admin/Header/{ => HeaderContent}/EnvironmentSelect/index.tsx (72%) rename src/components/Admin/Header/{ => HeaderContent}/EnvironmentSelect/styles.ts (90%) rename src/components/Admin/Header/{ => HeaderContent}/FilterMenu/FilterButton/index.tsx (52%) create mode 100644 src/components/Admin/Header/HeaderContent/FilterMenu/FilterButton/types.ts rename src/components/Admin/Header/{ => HeaderContent}/FilterMenu/index.tsx (59%) create mode 100644 src/components/Admin/Header/HeaderContent/index.tsx create mode 100644 src/components/Admin/Header/HeaderContent/styles.ts create mode 100644 src/components/Admin/Header/HeaderContent/types.ts diff --git a/src/components/Admin/Header/Greeting/Greeting.stories.tsx b/src/components/Admin/Header/Greeting/Greeting.stories.tsx index 8e24fdaf6..0101b70e3 100644 --- a/src/components/Admin/Header/Greeting/Greeting.stories.tsx +++ b/src/components/Admin/Header/Greeting/Greeting.stories.tsx @@ -16,20 +16,4 @@ export default meta; type Story = StoryObj; // More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args -export const Morning: Story = { - args: { - currentDateTime: new Date("1970-01-01T09:00:00Z").valueOf() - } -}; - -export const Afternoon: Story = { - args: { - currentDateTime: new Date("1970-01-01T14:00:00Z").valueOf() - } -}; - -export const Evening: Story = { - args: { - currentDateTime: new Date("1970-01-01T19:00:00Z").valueOf() - } -}; +export const Default: Story = {}; diff --git a/src/components/Admin/Header/Greeting/index.tsx b/src/components/Admin/Header/Greeting/index.tsx index 70eff4007..8693bed65 100644 --- a/src/components/Admin/Header/Greeting/index.tsx +++ b/src/components/Admin/Header/Greeting/index.tsx @@ -1,6 +1,8 @@ +import { useEffect, useState } from "react"; import { useGetUserProfileQuery } from "../../../../redux/services/digma"; import * as s from "./styles"; -import type { GreetingProps } from "./types"; + +const REFRESH_INTERVAL = 60 * 1000; // in milliseconds const getGreetingText = (dateTime: number) => { const currentHour = new Date(dateTime).getHours(); @@ -16,10 +18,19 @@ const getGreetingText = (dateTime: number) => { return `Good ${timeOfDay}`; }; -export const Greeting = ({ currentDateTime }: GreetingProps) => { +export const Greeting = () => { const { data: userProfile } = useGetUserProfileQuery(); + const [currentDateTime, setCurrentDateTime] = useState(Date.now()); const greetingText = getGreetingText(currentDateTime); + useEffect(() => { + const intervalId = setInterval(() => { + setCurrentDateTime(Date.now()); + }, REFRESH_INTERVAL); + + return () => clearInterval(intervalId); + }, []); + if (!userProfile) { return null; } diff --git a/src/components/Admin/Header/EnvironmentSelect/index.tsx b/src/components/Admin/Header/HeaderContent/EnvironmentSelect/index.tsx similarity index 72% rename from src/components/Admin/Header/EnvironmentSelect/index.tsx rename to src/components/Admin/Header/HeaderContent/EnvironmentSelect/index.tsx index 9f1fc4179..211083397 100644 --- a/src/components/Admin/Header/EnvironmentSelect/index.tsx +++ b/src/components/Admin/Header/HeaderContent/EnvironmentSelect/index.tsx @@ -2,19 +2,19 @@ import { useEffect, useMemo, useState } from "react"; import { useAdminDispatch, useAdminSelector -} from "../../../../containers/Admin/hooks"; -import { useGetEnvironmentsQuery } from "../../../../redux/services/digma"; -import { setSelectedEnvironmentId } from "../../../../redux/slices/issuesReportSlice"; -import { setEnvironmentId } from "../../../../redux/slices/scopeSlice"; -import { sendUserActionTrackingEvent } from "../../../../utils/actions/sendUserActionTrackingEvent"; -import { EnvironmentIcon } from "../../../common/EnvironmentIcon"; -import { ChevronIcon } from "../../../common/icons/16px/ChevronIcon"; -import { Direction } from "../../../common/icons/types"; -import { sortEnvironments } from "../../../common/IssuesReport/utils"; -import { NewPopover } from "../../../common/NewPopover"; -import { Tooltip } from "../../../common/v3/Tooltip"; -import { EnvironmentMenu } from "../../../Navigation/EnvironmentBar/EnvironmentMenu"; -import { trackingEvents } from "../../tracking"; +} from "../../../../../containers/Admin/hooks"; +import { useGetEnvironmentsQuery } from "../../../../../redux/services/digma"; +import { setSelectedEnvironmentId } from "../../../../../redux/slices/issuesReportSlice"; +import { setEnvironmentId } from "../../../../../redux/slices/scopeSlice"; +import { sendUserActionTrackingEvent } from "../../../../../utils/actions/sendUserActionTrackingEvent"; +import { EnvironmentIcon } from "../../../../common/EnvironmentIcon"; +import { ChevronIcon } from "../../../../common/icons/16px/ChevronIcon"; +import { Direction } from "../../../../common/icons/types"; +import { sortEnvironments } from "../../../../common/IssuesReport/utils"; +import { NewPopover } from "../../../../common/NewPopover"; +import { Tooltip } from "../../../../common/v3/Tooltip"; +import { EnvironmentMenu } from "../../../../Navigation/EnvironmentBar/EnvironmentMenu"; +import { trackingEvents } from "../../../tracking"; import * as s from "./styles"; export const EnvironmentSelect = () => { diff --git a/src/components/Admin/Header/EnvironmentSelect/styles.ts b/src/components/Admin/Header/HeaderContent/EnvironmentSelect/styles.ts similarity index 90% rename from src/components/Admin/Header/EnvironmentSelect/styles.ts rename to src/components/Admin/Header/HeaderContent/EnvironmentSelect/styles.ts index 8d7afe313..a7e399ed5 100644 --- a/src/components/Admin/Header/EnvironmentSelect/styles.ts +++ b/src/components/Admin/Header/HeaderContent/EnvironmentSelect/styles.ts @@ -1,6 +1,5 @@ import styled from "styled-components"; - -import { subscriptBoldTypography } from "../../../common/App/typographies"; +import { subscriptBoldTypography } from "../../../../common/App/typographies"; export const Button = styled.button` width: 180px; diff --git a/src/components/Admin/Header/FilterMenu/FilterButton/index.tsx b/src/components/Admin/Header/HeaderContent/FilterMenu/FilterButton/index.tsx similarity index 52% rename from src/components/Admin/Header/FilterMenu/FilterButton/index.tsx rename to src/components/Admin/Header/HeaderContent/FilterMenu/FilterButton/index.tsx index 8b6bf3b15..4c1eeae33 100644 --- a/src/components/Admin/Header/FilterMenu/FilterButton/index.tsx +++ b/src/components/Admin/Header/HeaderContent/FilterMenu/FilterButton/index.tsx @@ -1,10 +1,11 @@ import { type ForwardedRef, forwardRef } from "react"; -import { FunnelIcon } from "../../../../common/icons/16px/FunnelIcon"; -import { NewIconButton } from "../../../../common/v3/NewIconButton"; -import { Tooltip } from "../../../../common/v3/Tooltip"; +import { FunnelIcon } from "../../../../../common/icons/16px/FunnelIcon"; +import { NewIconButton } from "../../../../../common/v3/NewIconButton"; +import { Tooltip } from "../../../../../common/v3/Tooltip"; +import type { FilterButtonProps } from "./types"; const FilterButtonComponent = ( - props: { onClick: () => void; disabled?: boolean }, + props: FilterButtonProps, ref: ForwardedRef ) => (
@@ -13,7 +14,8 @@ const FilterButtonComponent = ( buttonType={"secondary"} icon={FunnelIcon} size={"large"} - {...props} + isDisabled={props.disabled} + onClick={props.onClick} />
diff --git a/src/components/Admin/Header/HeaderContent/FilterMenu/FilterButton/types.ts b/src/components/Admin/Header/HeaderContent/FilterMenu/FilterButton/types.ts new file mode 100644 index 000000000..bdf31f699 --- /dev/null +++ b/src/components/Admin/Header/HeaderContent/FilterMenu/FilterButton/types.ts @@ -0,0 +1,4 @@ +export interface FilterButtonProps { + onClick: () => void; + disabled?: boolean; +} diff --git a/src/components/Admin/Header/FilterMenu/index.tsx b/src/components/Admin/Header/HeaderContent/FilterMenu/index.tsx similarity index 59% rename from src/components/Admin/Header/FilterMenu/index.tsx rename to src/components/Admin/Header/HeaderContent/FilterMenu/index.tsx index 5cedda34e..e0fbdc1a6 100644 --- a/src/components/Admin/Header/FilterMenu/index.tsx +++ b/src/components/Admin/Header/HeaderContent/FilterMenu/index.tsx @@ -1,12 +1,14 @@ +import { useEffect } from "react"; import { useAdminDispatch, useAdminSelector -} from "../../../../containers/Admin/hooks"; -import { useGetEnvironmentServicesQuery } from "../../../../redux/services/digma"; -import { setSelectedServices } from "../../../../redux/slices/issuesReportSlice"; -import { sendUserActionTrackingEvent } from "../../../../utils/actions/sendUserActionTrackingEvent"; -import { Select } from "../../../common/v3/Select"; -import { trackingEvents } from "../../tracking"; +} from "../../../../../containers/Admin/hooks"; +import { usePrevious } from "../../../../../hooks/usePrevious"; +import { useGetEnvironmentServicesQuery } from "../../../../../redux/services/digma"; +import { setSelectedServices } from "../../../../../redux/slices/issuesReportSlice"; +import { sendUserActionTrackingEvent } from "../../../../../utils/actions/sendUserActionTrackingEvent"; +import { Select } from "../../../../common/v3/Select"; +import { trackingEvents } from "../../../tracking"; import { FilterButton } from "./FilterButton"; export const FilterMenu = () => { @@ -28,6 +30,16 @@ export const FilterMenu = () => { skip: !selectedEnvironmentId } ); + const previousServices = usePrevious(services); + + useEffect(() => { + if (services && previousServices !== services) { + const newSelectedServices = services.filter((x) => + selectedServices.includes(x) + ); + dispatch(setSelectedServices(newSelectedServices)); + } + }, [services, previousServices, selectedServices, dispatch]); const handleSelectedServicesChange = (option: string | string[]) => { const newItem = Array.isArray(option) ? option : [option]; diff --git a/src/components/Admin/Header/HeaderContent/index.tsx b/src/components/Admin/Header/HeaderContent/index.tsx new file mode 100644 index 000000000..e6577ce99 --- /dev/null +++ b/src/components/Admin/Header/HeaderContent/index.tsx @@ -0,0 +1,23 @@ +import { useAdminSelector } from "../../../../containers/Admin/hooks"; +import { EnvironmentSelect } from "./EnvironmentSelect"; +import { FilterMenu } from "./FilterMenu"; +import * as s from "./styles"; +import type { HeaderContentProps } from "./types"; + +export const HeaderContent = ({ children }: HeaderContentProps) => { + const environmentId = useAdminSelector( + (state) => state.codeIssuesReport.selectedEnvironmentId + ); + + return ( + + {children} + {environmentId && ( + + + + + )} + + ); +}; diff --git a/src/components/Admin/Header/HeaderContent/styles.ts b/src/components/Admin/Header/HeaderContent/styles.ts new file mode 100644 index 000000000..45f106ae5 --- /dev/null +++ b/src/components/Admin/Header/HeaderContent/styles.ts @@ -0,0 +1,17 @@ +import styled from "styled-components"; + +export const Container = styled.div` + display: flex; + justify-content: space-between; + align-items: center; + gap: 8px; +`; + +export const FilterContainer = styled.div` + display: flex; + padding: 8px; + align-items: center; + gap: 8px; + border-radius: 12px; + background: ${({ theme }) => theme.colors.v3.surface.primary}; +`; diff --git a/src/components/Admin/Header/HeaderContent/types.ts b/src/components/Admin/Header/HeaderContent/types.ts new file mode 100644 index 000000000..157f93be7 --- /dev/null +++ b/src/components/Admin/Header/HeaderContent/types.ts @@ -0,0 +1,5 @@ +import type { ReactNode } from "react"; + +export interface HeaderContentProps { + children: ReactNode; +} diff --git a/src/components/Admin/Header/index.tsx b/src/components/Admin/Header/index.tsx index 3af8db4a1..5ebb7c6be 100644 --- a/src/components/Admin/Header/index.tsx +++ b/src/components/Admin/Header/index.tsx @@ -1,34 +1,27 @@ import { Route, Routes } from "react-router-dom"; -import { useAdminSelector } from "../../../containers/Admin/hooks"; -import { EnvironmentSelect } from "./EnvironmentSelect"; -import { FilterMenu } from "./FilterMenu"; import { Greeting } from "./Greeting"; +import { HeaderContent } from "./HeaderContent"; import * as s from "./styles"; -export const Header = () => { - const environmentId = useAdminSelector( - (state) => state.codeIssuesReport.selectedEnvironmentId - ); - - return ( - - - - - {environmentId && ( - - - - - )} - - } - /> - Reports} /> - - - ); -}; +export const Header = () => ( + + + + + + } + /> + + Reports + + } + /> + + +); diff --git a/src/components/Admin/Header/styles.ts b/src/components/Admin/Header/styles.ts index f19aeb204..546193787 100644 --- a/src/components/Admin/Header/styles.ts +++ b/src/components/Admin/Header/styles.ts @@ -4,24 +4,8 @@ import { heading1SemiboldTypography } from "../../common/App/typographies"; export const Header = styled.header` ${heading1SemiboldTypography} - padding: 44px 44px 24px 24px; + padding: 44px 24px 24px; border-bottom: 1px solid ${({ theme }) => theme.colors.v3.stroke.tertiary}; box-sizing: border-box; color: ${({ theme }) => theme.colors.v3.text.primary}; `; - -export const HomeHeader = styled.div` - display: flex; - justify-content: space-between; - align-items: center; - gap: 8px; -`; - -export const FilterContainer = styled.div` - display: flex; - padding: 8px; - align-items: center; - gap: 8px; - border-radius: 12px; - background: ${({ theme }) => theme.colors.v3.surface.primary}; -`; diff --git a/src/components/Dashboard/MetricsReport/index.tsx b/src/components/Dashboard/MetricsReport/index.tsx index 0fe8c3a63..a4b7fc63f 100644 --- a/src/components/Dashboard/MetricsReport/index.tsx +++ b/src/components/Dashboard/MetricsReport/index.tsx @@ -198,6 +198,8 @@ export const MetricsReport = () => { onTimeModeChange={handleTimeModeChange} onViewModeChange={handleViewModeChange} onSelectedServiceChange={handleSelectedServiceChange} + showEnvironmentSelect={false} + showServicesSelect={false} /> diff --git a/src/components/Insights/InsightsCatalog/EnvironmentSelector/index.tsx b/src/components/Insights/InsightsCatalog/EnvironmentSelector/index.tsx index 61174081d..c142fcd27 100644 --- a/src/components/Insights/InsightsCatalog/EnvironmentSelector/index.tsx +++ b/src/components/Insights/InsightsCatalog/EnvironmentSelector/index.tsx @@ -62,10 +62,17 @@ export const EnvironmentSelector = ({ const { scope, environment } = useConfigSelector(); const [isMenuOpen, setIsMenuOpen] = useState(false); const { observe, width } = useDimensions(); - const sortedEnvironments = useMemo( + const sortedEnvironmentsByCriticalIssues = useMemo( () => [...environments].sort(sortEnvironmentsByCriticalIssues), [environments] ); + const sortedEnvironmentsByName = useMemo( + () => + [...environments].sort((a, b) => + a.environment.name.localeCompare(b.environment.name) + ), + [environments] + ); const changeEnvironment = (environmentId: string) => { sendUserActionTrackingEvent(trackingEvents.ENVIRONMENT_SELECTED); @@ -99,24 +106,26 @@ export const EnvironmentSelector = ({ setIsMenuOpen(!isMenuOpen); }; - const environmentIndex = sortedEnvironments.findIndex( + const environmentIndex = sortedEnvironmentsByCriticalIssues.findIndex( (x) => x.environment.id === environment?.id ); const environmentsWithChips = - sortedEnvironments.length > ENVIRONMENT_CHIP_COUNT + sortedEnvironmentsByCriticalIssues.length > ENVIRONMENT_CHIP_COUNT ? getSlidingWindow( - sortedEnvironments, + sortedEnvironmentsByCriticalIssues, environmentIndex - 1, ENVIRONMENT_CHIP_COUNT ) - : sortedEnvironments; + : sortedEnvironmentsByCriticalIssues; const renderEnvironmentMenuButton = () => ( ); @@ -133,7 +142,7 @@ export const EnvironmentSelector = ({ /> ))} - {sortedEnvironments.length > ENVIRONMENT_CHIP_COUNT && ( + {sortedEnvironmentsByName.length > ENVIRONMENT_CHIP_COUNT && ( <> {/* // TODO: refactor this to use only popover */} {isMenuOpen ? ( @@ -141,7 +150,9 @@ export const EnvironmentSelector = ({ content={ x.environment)} + environments={sortedEnvironmentsByName.map( + (x) => x.environment + )} onMenuItemClick={handleMenuItemClick} /> } diff --git a/src/components/Navigation/EnvironmentBar/index.tsx b/src/components/Navigation/EnvironmentBar/index.tsx index 26b9ab891..ab1cb7d3b 100644 --- a/src/components/Navigation/EnvironmentBar/index.tsx +++ b/src/components/Navigation/EnvironmentBar/index.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useMemo, useState } from "react"; import { sendUserActionTrackingEvent } from "../../../utils/actions/sendUserActionTrackingEvent"; import type { Environment } from "../../common/App/types"; import { EnvironmentIcon } from "../../common/EnvironmentIcon"; @@ -19,7 +19,12 @@ export const EnvironmentBar = ({ }: EnvironmentBarProps) => { const [isMenuOpen, setIsMenuOpen] = useState(false); - const isDisabled = environments.length === 0; + const sortedEnvironments = useMemo( + () => [...environments].sort((a, b) => a.name.localeCompare(b.name)), + [environments] + ); + + const isDisabled = sortedEnvironments.length === 0; const handleMenuItemClick = (environment: Environment) => { setIsMenuOpen(false); @@ -80,7 +85,7 @@ export const EnvironmentBar = ({ content={ } diff --git a/src/components/RecentActivity/EnvironmentPanel/index.tsx b/src/components/RecentActivity/EnvironmentPanel/index.tsx index 4393187c9..25aacad1a 100644 --- a/src/components/RecentActivity/EnvironmentPanel/index.tsx +++ b/src/components/RecentActivity/EnvironmentPanel/index.tsx @@ -1,4 +1,4 @@ -import { useContext, useEffect, useState } from "react"; +import { useContext, useEffect, useMemo, useState } from "react"; import useDimensions from "react-cool-dimensions"; import { RECENT_ACTIVITY_CONTAINER_ID } from ".."; import { actions as globalActions } from "../../../actions"; @@ -46,6 +46,11 @@ export const EnvironmentPanel = ({ const [isKebabMenuOpen, setIsKebabMenuOpen] = useState(false); const config = useContext(ConfigContext); + const sortedEnvironments = useMemo( + () => [...environments].sort((a, b) => a.name.localeCompare(b.name)), + [environments] + ); + useEffect(() => { const entry = environmentListContainerDimensions.entry; if (entry) { @@ -269,7 +274,7 @@ export const EnvironmentPanel = ({ ref={environmentListContainerDimensions.observe} > - {environments.map((environment) => ( + {sortedEnvironments.map((environment) => ( { const { data: about } = useGetAboutQuery(); @@ -224,25 +226,27 @@ export const Header = ({ - ({ - label: x.name, - value: x.id, - enabled: true, - selected: x.id === selectedEnvironmentId - }))} - showSelectedState={true} - icon={(props) => - selectedEnvironment?.type === "Public" ? ( - - ) : ( - - ) - } - onChange={handleSelectedEnvironmentChange} - placeholder={selectedEnvironment?.name ?? "Select Environments"} - disabled={environmentsToSelect.length === 0} - /> + {showEnvironmentSelect && ( + ({ + label: x.name, + value: x.id, + enabled: true, + selected: x.id === selectedEnvironmentId + }))} + showSelectedState={true} + icon={(props) => + selectedEnvironment?.type === "Public" ? ( + + ) : ( + + ) + } + onChange={handleSelectedEnvironmentChange} + placeholder={selectedEnvironment?.name ?? "Select Environments"} + disabled={environmentsToSelect.length === 0} + /> + )} {viewLevel === "endpoints" ? ( - ) : ( + ) : showServicesSelect ? ( ({ label: service, @@ -289,7 +293,7 @@ export const Header = ({ } disabled={!services || services.length === 0} /> - )} + ) : null} {timeMode === "changes" && ( ({ diff --git a/src/components/common/IssuesReport/Header/types.ts b/src/components/common/IssuesReport/Header/types.ts index 7ab016647..699b6d8da 100644 --- a/src/components/common/IssuesReport/Header/types.ts +++ b/src/components/common/IssuesReport/Header/types.ts @@ -27,4 +27,6 @@ export interface HeaderProps { onViewModeChange: (viewMode: IssuesReportViewMode) => void; onGoBack: () => void; defaultTitle: string; + showEnvironmentSelect?: boolean; + showServicesSelect?: boolean; } diff --git a/src/components/common/IssuesReport/index.tsx b/src/components/common/IssuesReport/index.tsx index 79f262fb2..21672d361 100644 --- a/src/components/common/IssuesReport/index.tsx +++ b/src/components/common/IssuesReport/index.tsx @@ -55,7 +55,9 @@ export const IssuesReport = ({ onTileTitleClick, onTileIssuesStatsClick, onSelectedServiceChange, - activeTileIds + activeTileIds, + showEnvironmentSelect = true, + showServicesSelect = true }: IssuesReportProps) => { const { data: about } = useGetAboutQuery(); const { data: environments } = useGetEnvironmentsQuery(); @@ -271,6 +273,8 @@ export const IssuesReport = ({ sortedEnvironments && sortedEnvironments.length > 0 ? ( <>
void; onSelectedServiceChange: (service: string | null) => void; activeTileIds?: string[]; + showEnvironmentSelect?: boolean; + showServicesSelect?: boolean; } export type ScoreCriterion = "impact" | "criticality"; diff --git a/src/components/common/v3/Select/index.tsx b/src/components/common/v3/Select/index.tsx index c699ecfa3..75cc4b518 100644 --- a/src/components/common/v3/Select/index.tsx +++ b/src/components/common/v3/Select/index.tsx @@ -1,5 +1,5 @@ import type { ChangeEvent } from "react"; -import { useCallback, useEffect, useRef, useState } from "react"; +import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import useDimensions from "react-cool-dimensions"; import { isString } from "../../../../typeGuards/isString"; import { isUndefined } from "../../../../typeGuards/isUndefined"; @@ -12,6 +12,9 @@ import { Tooltip } from "../Tooltip"; import * as s from "./styles"; import type { SelectItem, SelectProps } from "./types"; +const filterItemsBySearchValue = (value: string) => (item: SelectItem) => + item.label.toLowerCase().includes(value.toLowerCase()); + const sortItemsBySelectedState = (a: SelectItem, b: SelectItem) => { if (a.selected && !b.selected) { return -1; @@ -43,6 +46,28 @@ export const Select = ({ const [searchValue, setSearchValue] = useState(""); const optionListRef = useRef(null); const { observe } = useDimensions(); + const [itemOrder, setItemOrder] = useState([]); + + const filteredItems = useMemo( + () => items.filter(filterItemsBySearchValue(searchValue)), + [items, searchValue] + ); + + const sortedItems = useMemo(() => { + if (multiselect) { + return [...filteredItems].sort((a, b) => { + const aIndex = itemOrder.indexOf(a.value); + const bIndex = itemOrder.indexOf(b.value); + if (aIndex !== -1 && bIndex === -1) { + return 1; + } + + return aIndex - bIndex; + }); + } + + return filteredItems; + }, [filteredItems, multiselect, itemOrder]); const getOptionListRef = useCallback( (el: HTMLUListElement | null) => { @@ -82,21 +107,22 @@ export const Select = ({ setSearchValue(e.target.value); }; + useEffect(() => { + if (!isOpen) { + const sortedItems = multiselect + ? [...items].sort(sortItemsBySelectedState) + : items; + setItemOrder(sortedItems.map((item) => item.value)); + } + }, [isOpen, multiselect, items]); + useEffect(() => { if (!isOpen) { setSearchValue(""); } }, [isOpen]); - const selectedValues = items.filter((x) => x.selected).map((x) => x.value); - - const filteredItems = items.filter((x) => - x.label.toLocaleLowerCase().includes(searchValue) - ); - - const sortedItems = multiselect - ? filteredItems.sort(sortItemsBySelectedState) - : filteredItems; + const selectedValuesCount = sortedItems.filter((x) => x.selected).length; const isSelectedStateEnabled = isUndefined(showSelectedState) || showSelectedState; @@ -109,7 +135,8 @@ export const Select = ({ (Boolean(searchable) || (isUndefined(searchable) && items.length > 10)) && (optionListHasVerticalScrollbar || searchValue.length > 0); const isActive = - isOpen || (isSelectedStateEnabled && selectedValues.length > 0); + isOpen || (isSelectedStateEnabled && selectedValuesCount > 0); + return ( {placeholder} )} - {multiselect && - isSelectedStateEnabled && - selectedValues.length > 0 && ( - {selectedValues.length} - )} + {multiselect && isSelectedStateEnabled && selectedValuesCount > 0 && ( + {selectedValuesCount} + )} Date: Mon, 3 Mar 2025 09:50:45 +0100 Subject: [PATCH 2/2] Migrate to REST API calls --- .../IssuesSidebar/index.tsx | 4 +- src/components/Assets/AssetList/index.tsx | 17 +- .../Dashboard/Report/ReportHeader/index.tsx | 4 +- .../ErrorDetailsCardContent/index.tsx | 10 +- .../Insights/InsightTicketRenderer/index.tsx | 13 +- .../EndpointBottleneckInsightTicket/index.tsx | 20 +-- .../index.tsx | 2 - .../index.tsx | 20 +-- .../index.tsx | 20 +-- .../SpaNPlusOneInsightTicket/index.tsx | 2 - .../index.tsx | 2 - .../index.tsx | 2 - .../index.tsx | 2 - .../index.tsx | 20 +-- .../SpanScalingInsightTicket/index.tsx | 2 - .../common/InsightJiraTicket/index.tsx | 34 ++-- .../common/InsightJiraTicket/types.ts | 2 - .../common/useEndpointDataSource.ts | 9 +- .../insightTickets/types.ts | 1 - .../Insights/InsightTicketRenderer/types.ts | 1 - .../InsightCardRenderer/index.tsx | 58 +------ .../EndpointBottleneckInsightCard/index.tsx | 4 - .../EndpointBottleneckInsightCard/types.ts | 2 +- .../EndpointBreakdownInsightCard/index.tsx | 4 - .../EndpointBreakdownInsightCard/types.ts | 2 +- .../EndpointChattyApiV2InsightCard/index.tsx | 4 - .../EndpointChattyApiV2InsightCard/types.ts | 2 +- .../index.tsx | 4 - .../types.ts | 2 +- .../index.tsx | 34 ++-- .../types.ts | 2 +- .../index.tsx | 34 ++-- .../EndpointSessionInViewInsightCard/types.ts | 2 +- .../index.tsx | 4 - .../types.ts | 2 +- .../index.tsx | 34 ++-- .../types.ts | 2 +- .../EndpointUsageInsightCard/index.tsx | 4 - .../EndpointUsageInsightCard/types.ts | 2 +- .../SlowEndpointInsightCard/index.tsx | 4 - .../SlowEndpointInsightCard/types.ts | 2 +- .../SpaNPlusOneInsightCard/index.tsx | 34 ++-- .../SpaNPlusOneInsightCard/types.ts | 2 +- .../index.tsx | 4 - .../SpanDurationBreakdownInsightCard/types.ts | 2 +- .../SpanDurationsInsightCard/index.tsx | 4 - .../SpanDurationsInsightCard/types.ts | 2 +- .../index.tsx | 56 +++---- .../types.ts | 2 +- .../SpanNexusInsightCard/index.tsx | 5 +- .../SpanNexusInsightCard/types.ts | 2 +- .../index.tsx | 4 - .../types.ts | 2 +- .../index.tsx | 4 - .../SpanQueryOptimizationInsightCard/types.ts | 2 +- .../SpanScalingInsightCard/index.tsx | 34 ++-- .../SpanScalingInsightCard/types.ts | 2 +- .../SpanUsagesInsightCard/index.tsx | 50 +++--- .../SpanUsagesInsightCard/types.ts | 2 +- .../common/InsightCard/hooks/useDismissal.ts | 14 +- .../InsightCard/hooks/useMarkingAsRead.ts | 46 ----- .../insightCards/common/InsightCard/index.tsx | 157 +++++++++--------- .../insightCards/common/InsightCard/types.ts | 51 ------ .../InsightCardRenderer/insightCards/types.ts | 18 ++ .../InsightsPage/InsightCardRenderer/types.ts | 1 - .../InsightsCatalog/InsightsPage/index.tsx | 6 +- .../Insights/InsightsCatalog/index.tsx | 40 ++--- .../InsightsCatalog/useMarkingAllAsRead.ts | 43 ----- src/components/Insights/actions.ts | 10 +- .../Insights/deprecated/InsightList/index.tsx | 10 +- .../insightCards/ErrorsInsight/types.ts | 2 +- .../NoScalingIssueInsight/types.ts | 2 +- .../PerformanceAtScaleInsight/types.ts | 2 +- .../Insights/deprecated/InsightList/types.ts | 28 +++- src/components/Insights/index.tsx | 1 - .../InstallationWizard/InstallStep/index.tsx | 15 +- .../CreateEnvironmentPanel/index.tsx | 13 +- .../ErrorCard/index.tsx | 23 ++- .../CreateEnvironmentWizard/index.tsx | 40 +++-- .../RecentActivityTable/index.tsx | 17 +- src/components/common/FilterMenu/index.tsx | 4 +- src/components/common/JiraTicket/index.tsx | 14 +- src/components/common/Menu/index.tsx | 19 +-- src/components/common/Menu/types.ts | 22 +-- src/containers/Admin/store.ts | 2 +- src/redux/services/digma.ts | 66 ++++++-- src/redux/services/types.ts | 21 ++- 87 files changed, 512 insertions(+), 783 deletions(-) delete mode 100644 src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/common/InsightCard/hooks/useMarkingAsRead.ts create mode 100644 src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/types.ts delete mode 100644 src/components/Insights/InsightsCatalog/useMarkingAllAsRead.ts diff --git a/src/components/Admin/common/IssuesSidebarOverlay/IssuesSidebar/index.tsx b/src/components/Admin/common/IssuesSidebarOverlay/IssuesSidebar/index.tsx index 11c93329f..f944307b8 100644 --- a/src/components/Admin/common/IssuesSidebarOverlay/IssuesSidebar/index.tsx +++ b/src/components/Admin/common/IssuesSidebarOverlay/IssuesSidebar/index.tsx @@ -20,10 +20,10 @@ import { TwoVerticalLinesIcon } from "../../../../common/icons/16px/TwoVerticalL import { Pagination } from "../../../../common/Pagination"; import { NewButton } from "../../../../common/v3/NewButton"; import { NewIconButton } from "../../../../common/v3/NewIconButton"; -import { actions } from "../../../../Insights/actions"; import { EmptyState } from "../../../../Insights/EmptyState"; import { EmptyState as InsightsPageEmptyState } from "../../../../Insights/InsightsCatalog/InsightsPage/EmptyState"; import { InsightCardRenderer } from "../../../../Insights/InsightsCatalog/InsightsPage/InsightCardRenderer"; +import { actions } from "../../../../Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/common/InsightCard/hooks/useDismissal"; import { ViewMode } from "../../../../Insights/InsightsCatalog/types"; import { InsightTicketRenderer } from "../../../../Insights/InsightTicketRenderer"; import { @@ -265,7 +265,6 @@ export const IssuesSidebar = ({ !isTransitioning && i === getInsightToShowJiraHint(data.insights) } - onRefresh={refresh} isMarkAsReadButtonEnabled={false} viewMode={"full"} onDismissalChange={handleDismissalChange} @@ -328,7 +327,6 @@ export const IssuesSidebar = ({ diff --git a/src/components/Assets/AssetList/index.tsx b/src/components/Assets/AssetList/index.tsx index 3cbcf36ac..48d359445 100644 --- a/src/components/Assets/AssetList/index.tsx +++ b/src/components/Assets/AssetList/index.tsx @@ -282,12 +282,13 @@ export const AssetList = ({ }); }; - const handleSortingOrderToggleOptionButtonClick = (order: SORTING_ORDER) => { - setSorting({ - ...sorting, - order - }); - }; + const handleSortingOrderToggleOptionButtonClick = + (order: SORTING_ORDER) => () => { + setSorting({ + ...sorting, + order + }); + }; const renderContent = () => { if (isInitialLoading) { @@ -390,9 +391,7 @@ export const AssetList = ({ - handleSortingOrderToggleOptionButtonClick(order) - } + onClick={handleSortingOrderToggleOptionButtonClick(order)} > diff --git a/src/components/Dashboard/Report/ReportHeader/index.tsx b/src/components/Dashboard/Report/ReportHeader/index.tsx index 1c6bb0a4e..b43cc9c9b 100644 --- a/src/components/Dashboard/Report/ReportHeader/index.tsx +++ b/src/components/Dashboard/Report/ReportHeader/index.tsx @@ -80,9 +80,7 @@ export const ReportHeader = ({ onDownload={() => { // TODO: implement }} - onRefresh={() => { - handleRefresh(); - }} + onRefresh={handleRefresh} /> diff --git a/src/components/Errors/ErrorDetails/ErrorDetailsCardContent/index.tsx b/src/components/Errors/ErrorDetails/ErrorDetailsCardContent/index.tsx index 2ddb468ee..71a71e613 100644 --- a/src/components/Errors/ErrorDetails/ErrorDetailsCardContent/index.tsx +++ b/src/components/Errors/ErrorDetails/ErrorDetailsCardContent/index.tsx @@ -46,7 +46,7 @@ export const ErrorDetailsCardContent = ({ const isPreviousFlowButtonDisabled = currentFlowStack === 0; const isNextFlowButtonDisabled = currentFlowStack === flows.length - 1; - const handleFlowPaginationButtonClick = (flowNumber: number) => { + const handleFlowPaginationButtonClick = (flowNumber: number) => () => { sendUserActionTrackingEvent(trackingEvents.FLOW_PAGINATION_BUTTON_CLICKED); setCurrentFlowStack(flowNumber); @@ -87,9 +87,7 @@ export const ErrorDetailsCardContent = ({ - handleFlowPaginationButtonClick(currentFlowStack - 1) - } + onClick={handleFlowPaginationButtonClick(currentFlowStack - 1)} disabled={isPreviousFlowButtonDisabled} > - handleFlowPaginationButtonClick(currentFlowStack + 1) - } + onClick={handleFlowPaginationButtonClick(currentFlowStack + 1)} disabled={isNextFlowButtonDisabled} > { @@ -45,7 +44,6 @@ export const InsightTicketRenderer = ({ return ( @@ -57,7 +55,6 @@ export const InsightTicketRenderer = ({ return ( @@ -69,7 +66,6 @@ export const InsightTicketRenderer = ({ return ( @@ -81,7 +77,6 @@ export const InsightTicketRenderer = ({ return ( @@ -93,7 +88,6 @@ export const InsightTicketRenderer = ({ return ( @@ -106,7 +100,6 @@ export const InsightTicketRenderer = ({ return ( @@ -119,7 +112,6 @@ export const InsightTicketRenderer = ({ return ( @@ -136,7 +128,6 @@ export const InsightTicketRenderer = ({ @@ -145,7 +136,6 @@ export const InsightTicketRenderer = ({ return ( @@ -158,7 +148,6 @@ export const InsightTicketRenderer = ({ return ( diff --git a/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointBottleneckInsightTicket/index.tsx b/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointBottleneckInsightTicket/index.tsx index 78af346b5..b9fb2b45e 100644 --- a/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointBottleneckInsightTicket/index.tsx +++ b/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointBottleneckInsightTicket/index.tsx @@ -16,22 +16,16 @@ import type { InsightTicketProps } from "../types"; export const EndpointBottleneckInsightTicket = ({ data, - refreshInsights, onClose }: InsightTicketProps) => { const span = data.insight.span; - const { - commitInfos, - isLoading, - spanInsight, - onReloadSpanInsight, - codeLocations - } = useEndpointDataSource( - span?.spanInfo || null, - InsightType.SpanEndpointBottleneck, - data.insight.environment - ); + const { commitInfos, isLoading, spanInsight, codeLocations } = + useEndpointDataSource( + span?.spanInfo || null, + InsightType.SpanEndpointBottleneck, + data.insight.environment + ); const services = [ ...new Set( @@ -83,9 +77,7 @@ export const EndpointBottleneckInsightTicket = ({ }} insight={data.insight} relatedInsight={spanInsight} - onReloadSpanInsight={onReloadSpanInsight} onClose={onClose} - refreshInsights={refreshInsights} /> ); }; diff --git a/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointHighNumberOfQueriesInsightTicket/index.tsx b/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointHighNumberOfQueriesInsightTicket/index.tsx index 7579c9985..39184ef8c 100644 --- a/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointHighNumberOfQueriesInsightTicket/index.tsx +++ b/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointHighNumberOfQueriesInsightTicket/index.tsx @@ -9,7 +9,6 @@ import type { InsightTicketProps } from "../types"; export const EndpointHighNumberOfQueriesInsightTicket = ({ data, - refreshInsights, onClose }: InsightTicketProps) => { const { commitInfos, isLoading } = @@ -70,7 +69,6 @@ export const EndpointHighNumberOfQueriesInsightTicket = ({ }} insight={data.insight} onClose={onClose} - refreshInsights={refreshInsights} /> ); }; diff --git a/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointQueryOptimizationV2InsightTicket/index.tsx b/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointQueryOptimizationV2InsightTicket/index.tsx index 8b3cce84c..09ae8654b 100644 --- a/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointQueryOptimizationV2InsightTicket/index.tsx +++ b/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointQueryOptimizationV2InsightTicket/index.tsx @@ -20,24 +20,18 @@ import type { InsightTicketProps } from "../types"; export const EndpointQueryOptimizationV2InsightTicket = ({ data, - refreshInsights, onClose }: InsightTicketProps) => { const { jaegerApiPath } = useConfigSelector(); const span = data.insight.span; const spanInfo = span?.spanInfo || null; - const { - commitInfos, - spanInsight, - isLoading, - codeLocations, - onReloadSpanInsight - } = useEndpointDataSource( - spanInfo, - InsightType.SpanQueryOptimization, - data.insight.environment - ); + const { commitInfos, spanInsight, isLoading, codeLocations } = + useEndpointDataSource( + spanInfo, + InsightType.SpanQueryOptimization, + data.insight.environment + ); const services = [ ...new Set( @@ -123,8 +117,6 @@ export const EndpointQueryOptimizationV2InsightTicket = ({ insight={data.insight} relatedInsight={spanInsight} onClose={onClose} - onReloadSpanInsight={onReloadSpanInsight} - refreshInsights={refreshInsights} /> ); }; diff --git a/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointSpanNPlusOneInsightTicket/index.tsx b/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointSpanNPlusOneInsightTicket/index.tsx index 0b96d7cb2..3bcfa91f5 100644 --- a/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointSpanNPlusOneInsightTicket/index.tsx +++ b/src/components/Insights/InsightTicketRenderer/insightTickets/EndpointSpanNPlusOneInsightTicket/index.tsx @@ -20,24 +20,18 @@ import type { InsightTicketProps } from "../types"; export const EndpointSpanNPlusOneInsightTicket = ({ data, - refreshInsights, onClose }: InsightTicketProps) => { const { jaegerApiPath } = useConfigSelector(); const span = data.insight.span; const spanInfo = span?.internalSpan ?? span?.clientSpan; - const { - commitInfos, - spanInsight, - isLoading, - codeLocations, - onReloadSpanInsight - } = useEndpointDataSource( - spanInfo, - InsightType.SpaNPlusOne, - data.insight.environment - ); + const { commitInfos, spanInsight, isLoading, codeLocations } = + useEndpointDataSource( + spanInfo, + InsightType.SpaNPlusOne, + data.insight.environment + ); const services = [ ...new Set( @@ -106,8 +100,6 @@ export const EndpointSpanNPlusOneInsightTicket = ({ insight={data.insight} relatedInsight={spanInsight} onClose={onClose} - onReloadSpanInsight={onReloadSpanInsight} - refreshInsights={refreshInsights} /> ); }; diff --git a/src/components/Insights/InsightTicketRenderer/insightTickets/SpaNPlusOneInsightTicket/index.tsx b/src/components/Insights/InsightTicketRenderer/insightTickets/SpaNPlusOneInsightTicket/index.tsx index cd85a0eff..14b99c4e5 100644 --- a/src/components/Insights/InsightTicketRenderer/insightTickets/SpaNPlusOneInsightTicket/index.tsx +++ b/src/components/Insights/InsightTicketRenderer/insightTickets/SpaNPlusOneInsightTicket/index.tsx @@ -16,7 +16,6 @@ import type { InsightTicketProps } from "../types"; export const SpaNPlusOneInsightTicket = ({ data, - refreshInsights, onClose }: InsightTicketProps) => { const spanInsight = data.insight; @@ -93,7 +92,6 @@ export const SpaNPlusOneInsightTicket = ({ attachments={attachments} insight={data.insight} onClose={onClose} - refreshInsights={refreshInsights} /> ); }; diff --git a/src/components/Insights/InsightTicketRenderer/insightTickets/SpanEndpointBottleneckInsightTicket/index.tsx b/src/components/Insights/InsightTicketRenderer/insightTickets/SpanEndpointBottleneckInsightTicket/index.tsx index 4f688270e..4388e9eab 100644 --- a/src/components/Insights/InsightTicketRenderer/insightTickets/SpanEndpointBottleneckInsightTicket/index.tsx +++ b/src/components/Insights/InsightTicketRenderer/insightTickets/SpanEndpointBottleneckInsightTicket/index.tsx @@ -12,7 +12,6 @@ import type { InsightTicketProps } from "../types"; export const SpanEndpointBottleneckInsightTicket = ({ data, - refreshInsights, onClose }: InsightTicketProps) => { const { commitInfos, codeLocations, isLoading } = @@ -69,7 +68,6 @@ export const SpanEndpointBottleneckInsightTicket = ({ }} insight={data.insight} onClose={onClose} - refreshInsights={refreshInsights} /> ); }; diff --git a/src/components/Insights/InsightTicketRenderer/insightTickets/SpanPerformanceAnomalyInsightTicket/index.tsx b/src/components/Insights/InsightTicketRenderer/insightTickets/SpanPerformanceAnomalyInsightTicket/index.tsx index ec4177c69..654dbf1b9 100644 --- a/src/components/Insights/InsightTicketRenderer/insightTickets/SpanPerformanceAnomalyInsightTicket/index.tsx +++ b/src/components/Insights/InsightTicketRenderer/insightTickets/SpanPerformanceAnomalyInsightTicket/index.tsx @@ -17,7 +17,6 @@ import type { InsightTicketProps } from "../types"; export const SpanPerformanceAnomalyInsightTicket = ({ data, - refreshInsights, onClose, backendInfo }: InsightTicketProps) => { @@ -105,7 +104,6 @@ export const SpanPerformanceAnomalyInsightTicket = ({ attachments={attachments} insight={data.insight} onClose={onClose} - refreshInsights={refreshInsights} /> ); }; diff --git a/src/components/Insights/InsightTicketRenderer/insightTickets/SpanQueryOptimizationInsightTicket/index.tsx b/src/components/Insights/InsightTicketRenderer/insightTickets/SpanQueryOptimizationInsightTicket/index.tsx index 92e01e4dc..aeed1ca6e 100644 --- a/src/components/Insights/InsightTicketRenderer/insightTickets/SpanQueryOptimizationInsightTicket/index.tsx +++ b/src/components/Insights/InsightTicketRenderer/insightTickets/SpanQueryOptimizationInsightTicket/index.tsx @@ -15,7 +15,6 @@ import type { InsightTicketProps } from "../types"; export const SpanQueryOptimizationInsightTicket = ({ data, - refreshInsights, onClose }: InsightTicketProps) => { const { isLoading, commitInfos } = useCommitInfos(data.insight); @@ -98,7 +97,6 @@ export const SpanQueryOptimizationInsightTicket = ({ attachments={attachments} insight={data.insight} onClose={onClose} - refreshInsights={refreshInsights} /> ); }; diff --git a/src/components/Insights/InsightTicketRenderer/insightTickets/SpanScalingByRootCauseInsightTicket/index.tsx b/src/components/Insights/InsightTicketRenderer/insightTickets/SpanScalingByRootCauseInsightTicket/index.tsx index c923de818..7fe8b2c10 100644 --- a/src/components/Insights/InsightTicketRenderer/insightTickets/SpanScalingByRootCauseInsightTicket/index.tsx +++ b/src/components/Insights/InsightTicketRenderer/insightTickets/SpanScalingByRootCauseInsightTicket/index.tsx @@ -23,7 +23,6 @@ import type { InsightTicketProps } from "../types"; export const SpanScalingByRootCauseInsightTicket = ({ data, - refreshInsights, onClose, rootCauseSpanInfo, backendInfo @@ -34,17 +33,12 @@ export const SpanScalingByRootCauseInsightTicket = ({ const spanInfo = rootCauseSpanInfo; - const { - commitInfos, - spanInsight, - isLoading, - codeLocations, - onReloadSpanInsight - } = useEndpointDataSource( - spanInfo, - InsightType.SpanScaling, - data.insight.environment - ); + const { commitInfos, spanInsight, isLoading, codeLocations } = + useEndpointDataSource( + spanInfo, + InsightType.SpanScaling, + data.insight.environment + ); const renderDescription = () => { return ( @@ -116,8 +110,6 @@ export const SpanScalingByRootCauseInsightTicket = ({ insight={data.insight} relatedInsight={spanInsight} onClose={onClose} - onReloadSpanInsight={onReloadSpanInsight} - refreshInsights={refreshInsights} /> ); }; diff --git a/src/components/Insights/InsightTicketRenderer/insightTickets/SpanScalingInsightTicket/index.tsx b/src/components/Insights/InsightTicketRenderer/insightTickets/SpanScalingInsightTicket/index.tsx index 274be7f80..bcfe1f1f3 100644 --- a/src/components/Insights/InsightTicketRenderer/insightTickets/SpanScalingInsightTicket/index.tsx +++ b/src/components/Insights/InsightTicketRenderer/insightTickets/SpanScalingInsightTicket/index.tsx @@ -22,7 +22,6 @@ import type { InsightTicketProps } from "../types"; export const SpanScalingInsightTicket = ({ data, - refreshInsights, onClose, backendInfo }: InsightTicketProps) => { @@ -107,7 +106,6 @@ export const SpanScalingInsightTicket = ({ attachments={attachments} insight={data.insight} onClose={onClose} - refreshInsights={refreshInsights} /> ); }; diff --git a/src/components/Insights/InsightTicketRenderer/insightTickets/common/InsightJiraTicket/index.tsx b/src/components/Insights/InsightTicketRenderer/insightTickets/common/InsightJiraTicket/index.tsx index 3e8490e7c..a20849ef9 100644 --- a/src/components/Insights/InsightTicketRenderer/insightTickets/common/InsightJiraTicket/index.tsx +++ b/src/components/Insights/InsightTicketRenderer/insightTickets/common/InsightJiraTicket/index.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { useLinkTicketToIssueMutation, useUnlinkTicketFromIssueMutation @@ -11,17 +11,25 @@ import type { InsightJiraTicketProps } from "./types"; export const InsightJiraTicket = ({ insight, relatedInsight, - onReloadSpanInsight, description, summary, attachments, - onClose, - refreshInsights + onClose }: InsightJiraTicketProps) => { const [errorMessage, setErrorMessage] = useState(); - const [ticketLink, setTicketLink] = useState( - relatedInsight?.ticketLink ?? insight.ticketLink + const link = useMemo( + () => relatedInsight?.ticketLink ?? insight.ticketLink, + [relatedInsight?.ticketLink, insight.ticketLink] ); + const [ticketLink, setTicketLink] = useState(link); + const ticketLinkData = useMemo( + () => ({ + link: ticketLink, + errorMessage + }), + [ticketLink, errorMessage] + ); + const [triggerLink] = useLinkTicketToIssueMutation(); const [triggerUnlink] = useUnlinkTicketFromIssueMutation(); @@ -31,12 +39,6 @@ export const InsightJiraTicket = ({ } else { setErrorMessage(response.message); } - - refreshInsights(); - - if (onReloadSpanInsight) { - onReloadSpanInsight(); - } }; const linkTicket = (link: string) => { @@ -70,10 +72,8 @@ export const InsightJiraTicket = ({ }; useEffect(() => { - if (relatedInsight) { - setTicketLink(relatedInsight.ticketLink); - } - }, [relatedInsight]); + setTicketLink(link); + }, [link]); return ( diff --git a/src/components/Insights/InsightTicketRenderer/insightTickets/common/InsightJiraTicket/types.ts b/src/components/Insights/InsightTicketRenderer/insightTickets/common/InsightJiraTicket/types.ts index 5b51d3f02..0411143e8 100644 --- a/src/components/Insights/InsightTicketRenderer/insightTickets/common/InsightJiraTicket/types.ts +++ b/src/components/Insights/InsightTicketRenderer/insightTickets/common/InsightJiraTicket/types.ts @@ -13,6 +13,4 @@ export interface InsightJiraTicketProps { insight: GenericCodeObjectInsight; relatedInsight?: GenericCodeObjectInsight | null; onClose: () => void; - onReloadSpanInsight?: () => void; - refreshInsights: () => void; } diff --git a/src/components/Insights/InsightTicketRenderer/insightTickets/common/useEndpointDataSource.ts b/src/components/Insights/InsightTicketRenderer/insightTickets/common/useEndpointDataSource.ts index 703c022e3..ad4029db2 100644 --- a/src/components/Insights/InsightTicketRenderer/insightTickets/common/useEndpointDataSource.ts +++ b/src/components/Insights/InsightTicketRenderer/insightTickets/common/useEndpointDataSource.ts @@ -8,7 +8,7 @@ export const useEndpointDataSource = ( insightType: InsightType, environmentId: string ) => { - const { data, isFetching, refetch } = useGetSpanInsightQuery( + const { data, isFetching } = useGetSpanInsightQuery( { spanCodeObjectId: spanInfo?.spanCodeObjectId ?? "", insightType, @@ -25,15 +25,10 @@ export const useEndpointDataSource = ( commitInfos } = useSpanDataSource(spanInfo, (data as T) ?? null, environmentId); - const handleReloadSpanInsight = () => { - void refetch(); - }; - return { isLoading: isFetching || isInsightMetaIsLoading, codeLocations, spanInsight: (data as T) ?? null, - commitInfos, - onReloadSpanInsight: handleReloadSpanInsight + commitInfos }; }; diff --git a/src/components/Insights/InsightTicketRenderer/insightTickets/types.ts b/src/components/Insights/InsightTicketRenderer/insightTickets/types.ts index 659e5b6fb..c2a9806b9 100644 --- a/src/components/Insights/InsightTicketRenderer/insightTickets/types.ts +++ b/src/components/Insights/InsightTicketRenderer/insightTickets/types.ts @@ -8,7 +8,6 @@ export interface CodeLocationsData { export interface InsightTicketProps { data: InsightTicketInfo; - refreshInsights: () => void; onClose: () => void; backendInfo: BackendInfo | GetAboutResponse | null; } diff --git a/src/components/Insights/InsightTicketRenderer/types.ts b/src/components/Insights/InsightTicketRenderer/types.ts index e1779706a..1d638a82f 100644 --- a/src/components/Insights/InsightTicketRenderer/types.ts +++ b/src/components/Insights/InsightTicketRenderer/types.ts @@ -4,7 +4,6 @@ import type { GenericCodeObjectInsight, InsightTicketInfo } from "../types"; export interface InsightTicketRendererProps { data: InsightTicketInfo; - refreshInsights: () => void; onClose: () => void; backendInfo: BackendInfo | GetAboutResponse | null; } diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/index.tsx index 06d53e29c..91a5201da 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/index.tsx @@ -34,11 +34,7 @@ import { isSpanUsagesInsight } from "../../../typeGuards"; import { InsightType, type Trace } from "../../../types"; -import type { - OpenHistogramPayload, - OpenLiveViewPayload, - RecalculatePayload -} from "../types"; +import type { OpenHistogramPayload, OpenLiveViewPayload } from "../types"; import { EndpointBottleneckInsightCard } from "./insightCards/EndpointBottleneckInsightCard"; import { EndpointBreakdownInsightCard } from "./insightCards/EndpointBreakdownInsightCard"; import { EndpointChattyApiV2InsightCard } from "./insightCards/EndpointChattyApiV2InsightCard"; @@ -60,12 +56,11 @@ import { SpanScalingInsightCard } from "./insightCards/SpanScalingInsightCard"; import { SpanUsagesInsightCard } from "./insightCards/SpanUsagesInsightCard"; import type { InsightCardRendererProps } from "./types"; -// TODO: move all Digma message/request sending to the parent component and move this one common +// TODO: move to common export const InsightCardRenderer = ({ insight, onJiraTicketCreate, isJiraHintEnabled, - onRefresh, isMarkAsReadButtonEnabled, viewMode, onDismissalChange, @@ -126,7 +121,7 @@ export const InsightCardRenderer = ({ action: actions.OPEN_HISTOGRAM, payload: { spanCodeObjectId, - // TODO: Remove after the plugin supports other insights types besides SpanDurations and SpanScaling + // TODO: remove after the plugin supports other insights types besides SpanDurations and SpanScaling insightType: [ InsightType.SpanPerformanceAnomaly, InsightType.EndpointSlowdownSource @@ -194,15 +189,6 @@ export const InsightCardRenderer = ({ }); }; - const handleRecalculate = (insightId: string) => { - window.sendMessageToDigma({ - action: actions.RECALCULATE, - payload: { - id: insightId - } - }); - }; - const handleGoToSpan = (spanCodeObjectId: string) => { changeScope({ span: { spanCodeObjectId }, @@ -220,8 +206,6 @@ export const InsightCardRenderer = ({ insight={insight} onHistogramButtonClick={handleHistogramButtonClick} onLiveButtonClick={handleLiveButtonClick} - onRecalculate={handleRecalculate} - onRefresh={onRefresh} onGoToSpan={handleGoToSpan} isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} @@ -237,8 +221,6 @@ export const InsightCardRenderer = ({ key={insight.id} insight={insight} onAssetLinkClick={handleAssetLinkClick} - onRecalculate={handleRecalculate} - onRefresh={onRefresh} onGoToSpan={handleGoToSpan} isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} @@ -255,8 +237,6 @@ export const InsightCardRenderer = ({ insight={insight} onAssetLinkClick={handleAssetLinkClick} onTraceButtonClick={handleTraceButtonClick} - onRecalculate={handleRecalculate} - onRefresh={onRefresh} onGoToSpan={handleGoToSpan} isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} viewMode={viewMode} @@ -272,8 +252,6 @@ export const InsightCardRenderer = ({ key={insight.id} insight={insight} onAssetLinkClick={handleAssetLinkClick} - onRecalculate={handleRecalculate} - onRefresh={onRefresh} onJiraTicketCreate={onJiraTicketCreate} isJiraHintEnabled={isJiraHintEnabled} onGoToSpan={handleGoToSpan} @@ -292,8 +270,6 @@ export const InsightCardRenderer = ({ key={insight.id} insight={insight} onAssetLinkClick={handleAssetLinkClick} - onRecalculate={handleRecalculate} - onRefresh={onRefresh} onJiraTicketCreate={onJiraTicketCreate} isJiraHintEnabled={isJiraHintEnabled} onGoToSpan={handleGoToSpan} @@ -311,8 +287,6 @@ export const InsightCardRenderer = ({ } - onRecalculate={onRecalculate} - onRefresh={onRefresh} onJiraButtonClick={handleTicketInfoButtonClick} onGoToSpan={onGoToSpan} onGoToTrace={span.traceId ? handleTraceButtonClick : undefined} diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBottleneckInsightCard/types.ts b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBottleneckInsightCard/types.ts index 655a9688f..76d1d03e4 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBottleneckInsightCard/types.ts +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBottleneckInsightCard/types.ts @@ -3,7 +3,7 @@ import type { InsightType, Trace } from "../../../../../types"; -import type { InsightCardCommonProps } from "../common/InsightCard/types"; +import type { InsightCardCommonProps } from "../types"; export interface EndpointBottleneckInsightCardProps extends InsightCardCommonProps { 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 1e7dee514..809df3c66 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBreakdownInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBreakdownInsightCard/index.tsx @@ -92,8 +92,6 @@ const columnHelper = createColumnHelper(); export const EndpointBreakdownInsightCard = ({ insight, - onRecalculate, - onRefresh, onGoToSpan, isMarkAsReadButtonEnabled, viewMode, @@ -258,8 +256,6 @@ export const EndpointBreakdownInsightCard = ({ {insight.hasAsyncSpans ? renderTable() : renderPieChart()} } - onRecalculate={onRecalculate} - onRefresh={onRefresh} isAsync={insight.hasAsyncSpans} onGoToSpan={onGoToSpan} isMarkAsReadButtonEnabled={isMarkAsReadButtonEnabled} diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBreakdownInsightCard/types.ts b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBreakdownInsightCard/types.ts index 99e85eccd..98ba60b1b 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBreakdownInsightCard/types.ts +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointBreakdownInsightCard/types.ts @@ -1,5 +1,5 @@ import type { EndpointBreakdownInsight } from "../../../../../types"; -import type { InsightCardCommonProps } from "../common/InsightCard/types"; +import type { InsightCardCommonProps } from "../types"; export interface EndpointBreakdownInsightCardProps extends InsightCardCommonProps { 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 b993085c1..aa2a3a97d 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointChattyApiV2InsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointChattyApiV2InsightCard/index.tsx @@ -11,8 +11,6 @@ export const EndpointChattyApiV2InsightCard = ({ insight, onAssetLinkClick, onTraceButtonClick, - onRecalculate, - onRefresh, onGoToSpan, isMarkAsReadButtonEnabled, viewMode, @@ -56,8 +54,6 @@ export const EndpointChattyApiV2InsightCard = ({ } - onRecalculate={onRecalculate} - onRefresh={onRefresh} onGoToSpan={onGoToSpan} onGoToTrace={ traceId diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointChattyApiV2InsightCard/types.ts b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointChattyApiV2InsightCard/types.ts index e2af8378b..2086a7eb4 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointChattyApiV2InsightCard/types.ts +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointChattyApiV2InsightCard/types.ts @@ -3,7 +3,7 @@ import type { InsightType, Trace } from "../../../../../types"; -import type { InsightCardCommonProps } from "../common/InsightCard/types"; +import type { InsightCardCommonProps } from "../types"; export interface EndpointChattyApiV2InsightCardProps extends InsightCardCommonProps { 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 ffb06d579..6653324e3 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointHighNumberOfQueriesInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointHighNumberOfQueriesInsightCard/index.tsx @@ -10,8 +10,6 @@ export const EndpointHighNumberOfQueriesInsightCard = ({ insight, onTraceButtonClick, onJiraTicketCreate, - onRecalculate, - onRefresh, isJiraHintEnabled, onGoToSpan, isMarkAsReadButtonEnabled, @@ -66,8 +64,6 @@ export const EndpointHighNumberOfQueriesInsightCard = ({ } - onRecalculate={onRecalculate} - onRefresh={onRefresh} onJiraButtonClick={handleTicketInfoButtonClick} jiraTicketInfo={{ ticketLink: insight.ticketLink, diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointHighNumberOfQueriesInsightCard/types.ts b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointHighNumberOfQueriesInsightCard/types.ts index 48baf71ba..ff6b3f043 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointHighNumberOfQueriesInsightCard/types.ts +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointHighNumberOfQueriesInsightCard/types.ts @@ -3,7 +3,7 @@ import type { InsightType, Trace } from "../../../../../types"; -import type { InsightCardCommonProps } from "../common/InsightCard/types"; +import type { InsightCardCommonProps } from "../types"; export interface EndpointHighNumberOfQueriesInsightCardProps extends InsightCardCommonProps { 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 c09830422..24f5f175a 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointQueryOptimizationV2InsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointQueryOptimizationV2InsightCard/index.tsx @@ -13,8 +13,6 @@ export const EndpointQueryOptimizationV2InsightCard = ({ onTraceButtonClick, onJiraTicketCreate, isJiraHintEnabled, - onRecalculate, - onRefresh, onGoToSpan, isMarkAsReadButtonEnabled, viewMode, @@ -35,13 +33,11 @@ export const EndpointQueryOptimizationV2InsightCard = ({ } }; - const handleTraceButtonClick = ( - trace: Trace, - insightType: InsightType, - spanCodeObjectId: string - ) => { - onTraceButtonClick(trace, insightType, spanCodeObjectId); - }; + const handleTraceButtonClick = + (trace: Trace, insightType: InsightType, spanCodeObjectId: string) => + () => { + onTraceButtonClick(trace, insightType, spanCodeObjectId); + }; const spanName = insight.span.spanInfo.displayName; const spanCodeObjectId = insight.span.spanInfo.spanCodeObjectId; @@ -68,18 +64,14 @@ export const EndpointQueryOptimizationV2InsightCard = ({ } - onRecalculate={onRecalculate} - onRefresh={onRefresh} - onGoToTrace={() => - handleTraceButtonClick( - { - name: spanName, - id: insight.span.traceId - }, - insight.type, - spanCodeObjectId - ) - } + onGoToTrace={handleTraceButtonClick( + { + name: spanName, + id: insight.span.traceId + }, + insight.type, + spanCodeObjectId + )} onJiraButtonClick={handleTicketInfoButtonClick} jiraTicketInfo={{ ticketLink: insight.span.ticketLink, diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointQueryOptimizationV2InsightCard/types.ts b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointQueryOptimizationV2InsightCard/types.ts index 3134217d3..7a72f8094 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointQueryOptimizationV2InsightCard/types.ts +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointQueryOptimizationV2InsightCard/types.ts @@ -3,7 +3,7 @@ import type { InsightType, Trace } from "../../../../../types"; -import type { InsightCardCommonProps } from "../common/InsightCard/types"; +import type { InsightCardCommonProps } from "../types"; export interface EndpointQueryOptimizationV2InsightCardProps extends InsightCardCommonProps { 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 b40b36c1e..75a7917b9 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointSessionInViewInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/InsightCardRenderer/insightCards/EndpointSessionInViewInsightCard/index.tsx @@ -17,8 +17,6 @@ export const EndpointSessionInViewInsightCard = ({ insight, onAssetLinkClick, onTraceButtonClick, - onRecalculate, - onRefresh, onGoToSpan, isMarkAsReadButtonEnabled, viewMode, @@ -37,13 +35,11 @@ export const EndpointSessionInViewInsightCard = ({ onAssetLinkClick(spanCodeObjectId, insight.type); }; - const handleTraceButtonClick = ( - trace: Trace, - insightType: InsightType, - spanCodeObjectId: string - ) => { - onTraceButtonClick(trace, insightType, spanCodeObjectId); - }; + const handleTraceButtonClick = + (trace: Trace, insightType: InsightType, spanCodeObjectId: string) => + () => { + onTraceButtonClick(trace, insightType, spanCodeObjectId); + }; return (