From a65ad94eba8b9127815a3fad1103f3a1d6965d75 Mon Sep 17 00:00:00 2001 From: opoliarush Date: Tue, 29 Oct 2024 16:54:02 +0200 Subject: [PATCH 1/4] Added days filter --- .../DaysFilter/DaysFilter.stories.tsx | 25 +++ .../GlobalErrorsList/DaysFilter/index.tsx | 158 ++++++++++++++++++ .../GlobalErrorsList/DaysFilter/styles.ts | 76 +++++++++ .../GlobalErrorsList/DaysFilter/types.ts | 33 ++++ .../Errors/GlobalErrorsList/index.tsx | 25 ++- .../Errors/GlobalErrorsList/styles.ts | 2 +- .../Errors/GlobalErrorsList/types.ts | 1 + src/components/Errors/tracking.ts | 10 ++ .../Navigation/common/MenuList/index.tsx | 5 +- .../Navigation/common/MenuList/types.ts | 1 + .../common/icons/12px/CalendarIcon.tsx | 20 +++ src/components/common/icons/16px/PlusIcon.tsx | 27 +++ src/featureFlags.ts | 3 +- src/store/errors/errorsSlice.ts | 3 + src/types.ts | 3 +- 15 files changed, 383 insertions(+), 9 deletions(-) create mode 100644 src/components/Errors/GlobalErrorsList/DaysFilter/DaysFilter.stories.tsx create mode 100644 src/components/Errors/GlobalErrorsList/DaysFilter/index.tsx create mode 100644 src/components/Errors/GlobalErrorsList/DaysFilter/styles.ts create mode 100644 src/components/Errors/GlobalErrorsList/DaysFilter/types.ts create mode 100644 src/components/common/icons/12px/CalendarIcon.tsx create mode 100644 src/components/common/icons/16px/PlusIcon.tsx diff --git a/src/components/Errors/GlobalErrorsList/DaysFilter/DaysFilter.stories.tsx b/src/components/Errors/GlobalErrorsList/DaysFilter/DaysFilter.stories.tsx new file mode 100644 index 000000000..8e3e272a3 --- /dev/null +++ b/src/components/Errors/GlobalErrorsList/DaysFilter/DaysFilter.stories.tsx @@ -0,0 +1,25 @@ +import { Meta, StoryObj } from "@storybook/react"; + +import { fn } from "@storybook/test"; +import { DaysFilter } from "."; + +// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction +const meta: Meta = { + title: "Errors/GlobalErrorsList/DaysFilter", + component: DaysFilter, + parameters: { + // More on how to position stories at: https://storybook.js.org/docs/react/configure/story-layout + layout: "fullscreen" + } +}; + +export default meta; + +type Story = StoryObj; + +// More on writing stories with args: https://storybook.js.org/docs/react/writing-stories/args +export const Default: Story = { + args: { + onChanged: fn() + } +}; diff --git a/src/components/Errors/GlobalErrorsList/DaysFilter/index.tsx b/src/components/Errors/GlobalErrorsList/DaysFilter/index.tsx new file mode 100644 index 000000000..19dc4c88e --- /dev/null +++ b/src/components/Errors/GlobalErrorsList/DaysFilter/index.tsx @@ -0,0 +1,158 @@ +import { ChangeEvent, useCallback, useEffect, useMemo, useState } from "react"; +import { usePrevious } from "../../../../hooks/usePrevious"; +import { isUndefined } from "../../../../typeGuards/isUndefined"; +import { sendUserActionTrackingEvent } from "../../../../utils/actions/sendUserActionTrackingEvent"; +import { formatUnit } from "../../../../utils/formatUnit"; +import { CalendarIcon } from "../../../common/icons/12px/CalendarIcon"; +import { MinusIcon } from "../../../common/icons/MinusIcon"; +import { PlusIcon } from "../../../common/icons/PlusIcon"; +import { NewPopover } from "../../../common/NewPopover"; +import { NewIconButton } from "../../../common/v3/NewIconButton"; +import { MenuList } from "../../../Navigation/common/MenuList"; +import { trackingEvents } from "../../tracking"; +import * as s from "./styles"; +import { DaysFilterProps } from "./types"; + +const MAX_VALUE = 14; +const MIN_VALUE = 1; + +const DEFAULT_LIST_OPTIONS = [7, 14]; + +const getOptionLabel = (days: number) => `${days} ${formatUnit(days, "Day")}`; + +export const DaysFilter = ({ onChanged }: DaysFilterProps) => { + const [isDateMenuOpen, setIsDateMenuOpen] = useState(false); + const [selectedDays, setSelectedDays] = useState(); + const [currentValue, setCurrentValue] = useState(); + const previousSelectedDays = usePrevious(selectedDays); + const handleSelectionChange = useCallback( + (days: number) => { + const value = selectedDays === days ? undefined : days; + setSelectedDays(value); + setCurrentValue(value); + setIsDateMenuOpen(false); + }, + [selectedDays] + ); + + const daysFilterMenuItems = useMemo( + () => + Object.values(DEFAULT_LIST_OPTIONS).map((x) => ({ + id: x.toString(), + label: "Last " + getOptionLabel(x), + isSelected: selectedDays === x, + onClick: () => handleSelectionChange(x) + })), + [handleSelectionChange, selectedDays] + ); + + useEffect(() => { + if (previousSelectedDays !== selectedDays) { + onChanged(selectedDays); + } + }, [selectedDays, previousSelectedDays, onChanged]); + + const handleSortingMenuButtonClick = () => { + sendUserActionTrackingEvent( + trackingEvents.GLOBAL_ERRORS_VIEW_DATES_FILTERS_CHANGE + ); + setIsDateMenuOpen(!isDateMenuOpen); + setCurrentValue(selectedDays); + }; + + const handleCounterInputChange = (e: ChangeEvent) => { + const newValue = e.target.value; + const intValue = parseInt(newValue); + const days = + !newValue || isNaN(intValue) + ? undefined + : intValue > MAX_VALUE + ? selectedDays + : intValue; + + sendUserActionTrackingEvent( + trackingEvents.GLOBAL_ERRORS_DAYS_FILTER_DECREMENT_CLICKED + ); + setCurrentValue(days); + }; + + const handleDecrement = () => { + if (currentValue === MIN_VALUE) { + return; + } + sendUserActionTrackingEvent( + trackingEvents.GLOBAL_ERRORS_DAYS_FILTER_DECREMENT_CLICKED + ); + setCurrentValue(currentValue ? currentValue - 1 : 0); + }; + + const handleIncrement = () => { + if (currentValue === MAX_VALUE) { + return; + } + + sendUserActionTrackingEvent( + trackingEvents.GLOBAL_ERRORS_DAYS_FILTER_INCREMENT_CLICKED + ); + setCurrentValue(currentValue ? currentValue + 1 : 1); + }; + + const handleApplyClick = () => { + sendUserActionTrackingEvent( + trackingEvents.GLOBAL_ERRORS_DAYS_FILTER_APPLY_BTN_CLICKED + ); + setSelectedDays(currentValue); + setIsDateMenuOpen(false); + }; + + return ( + + + + + + } + onClick={handleDecrement} + /> + + } + onClick={handleIncrement} + /> + Last days + + + + + + } + placement={"bottom-end"} + > + 0} + icon={() => ( + + + + )} + label={selectedDays ? getOptionLabel(selectedDays) : "Dates"} + buttonType={"secondary"} + onClick={handleSortingMenuButtonClick} + /> + + ); +}; diff --git a/src/components/Errors/GlobalErrorsList/DaysFilter/styles.ts b/src/components/Errors/GlobalErrorsList/DaysFilter/styles.ts new file mode 100644 index 000000000..b37d2ba1f --- /dev/null +++ b/src/components/Errors/GlobalErrorsList/DaysFilter/styles.ts @@ -0,0 +1,76 @@ +import styled from "styled-components"; +import { + bodyRegularTypography, + footnoteRegularTypography +} from "../../../common/App/typographies"; +import { NewButton } from "../../../common/v3/NewButton"; +import { TextField } from "../../../common/v3/TextField"; +import { Popup } from "../../../Navigation/common/Popup"; +import { DaysButtonProps } from "./types"; + +export const ButtonIconContainer = styled.div` + color: ${({ theme }) => theme.colors.v3.icon.tertiary}; +`; + +export const DateButton = styled(NewButton)` + border: 1px solid + ${({ theme, $isActive }) => { + if ($isActive) { + return theme.colors.v3.surface.brandPrimary; + } + + return theme.colors.v3.stroke.dark; + }}; + background: ${({ theme, $isActive }) => { + if ($isActive) { + return theme.colors.v3.surface.brandDark; + } + + return theme.colors.v3.surface.primary; + }}; +`; + +export const DatePopup = styled(Popup)` + min-width: 164px; + display: flex; +`; + +export const ItemsContainer = styled.div` + display: flex; + flex-direction: column; + gap: 8px; +`; + +export const CustomCounterContainer = styled.div` + flex-direction: column; + display: flex; + gap: 8px; + margin: 0 -8px -8px; + padding: 8px; + background: ${({ theme }) => theme.colors.v3.surface.highlight}; +`; + +export const Counter = styled.div` + ${bodyRegularTypography} + display: flex; + flex-direction: row; + align-items: center; +`; + +export const CounterInput = styled(TextField)` + ${footnoteRegularTypography} + padding: 4px; + + input { + max-width: 16px; + } +`; + +export const ApplyButton = styled(NewButton)` + width: 100%; + justify-content: center; +`; + +export const Text = styled.span` + padding-right: 5px; +`; diff --git a/src/components/Errors/GlobalErrorsList/DaysFilter/types.ts b/src/components/Errors/GlobalErrorsList/DaysFilter/types.ts new file mode 100644 index 000000000..8e124dfc7 --- /dev/null +++ b/src/components/Errors/GlobalErrorsList/DaysFilter/types.ts @@ -0,0 +1,33 @@ +import { ErrorFilter } from "../../../../store/errors/errorsSlice"; +import { ButtonProps } from "../../../common/v3/NewButton/types"; + +export interface GetGlobalErrorsFiltersDataPayload { + environment: string; + filterName?: string; + filterData?: { + services?: string[]; + values: string[]; + }; +} + +export interface FilterData { + filterName: ErrorFilter; + values: T[]; +} + +export interface EndpointFilterData { + spanCodeObjectId: string; + displayName: string; +} + +export interface SetGlobalErrorsFiltersDataPayload { + filters: FilterData[]; +} + +export interface DaysButtonProps extends ButtonProps { + $isActive: boolean; +} + +export interface DaysFilterProps { + onChanged: (days?: number) => void; +} diff --git a/src/components/Errors/GlobalErrorsList/index.tsx b/src/components/Errors/GlobalErrorsList/index.tsx index 86265820f..ccd5815d3 100644 --- a/src/components/Errors/GlobalErrorsList/index.tsx +++ b/src/components/Errors/GlobalErrorsList/index.tsx @@ -37,6 +37,7 @@ import { actions } from "../actions"; import { NewErrorCard } from "../NewErrorCard"; import { NoDataEmptyState } from "../NoDataEmptyState"; import { trackingEvents } from "../tracking"; +import { DaysFilter } from "./DaysFilter"; import { GlobalErrorsFilters } from "./GlobalErrorsFilters"; import * as s from "./styles"; import { @@ -78,7 +79,8 @@ export const GlobalErrorsList = () => { globalErrorsPageSize: pageSize, globalErrorsList: list, globalErrorsTotalCount: totalCount, - globalErrorsSelectedFilters: selectedFilters + globalErrorsSelectedFilters: selectedFilters, + globalErrorsLastDays: lastDays } = useErrorsSelector(); const previousList = usePrevious(list); @@ -90,7 +92,8 @@ export const GlobalErrorsList = () => { setGlobalErrorsPage, resetGlobalErrors, resetGlobalErrorsSelectedFilters, - setGlobalErrorsViewMode + setGlobalErrorsViewMode, + setGlobalErrorsLastDays } = useStore.getState(); const areGlobalErrorsFiltersEnabled = getFeatureFlagValue( @@ -98,6 +101,11 @@ export const GlobalErrorsList = () => { FeatureFlag.ARE_GLOBAL_ERRORS_FILTERS_ENABLED ); + const isGlobalErrorsLastDaysFilterEnabled = getFeatureFlagValue( + backendInfo, + FeatureFlag.IS_GLOBAL_ERROR_LAST_DAYS_FILTER_ENABLED + ); + const areGlobalErrorsCriticalityAndUnhandledFiltersEnabled = getFeatureFlagValue( backendInfo, @@ -131,6 +139,7 @@ export const GlobalErrorsList = () => { searchCriteria: search, sortBy: sorting, page, + lastDays, pageSize: PAGE_SIZE, dismissed: mode === ViewMode.OnlyDismissed, ...(areGlobalErrorsFiltersEnabled @@ -153,6 +162,7 @@ export const GlobalErrorsList = () => { sorting, page, mode, + lastDays, areGlobalErrorsFiltersEnabled, selectedFilters.services, selectedFilters.endpoints, @@ -265,6 +275,10 @@ export const GlobalErrorsList = () => { setGlobalErrorsSearch(search); }; + const handleDayFilterChange = (days?: number) => { + setGlobalErrorsLastDays(days); + }; + const handleSortingMenuButtonClick = () => { sendUserActionTrackingEvent( trackingEvents.GLOBAL_ERRORS_VIEW_SORTING_CHANGE @@ -366,6 +380,9 @@ export const GlobalErrorsList = () => { {areGlobalErrorsFiltersEnabled && } + {isGlobalErrorsLastDaysFilterEnabled && ( + + )} { > ( - + - + )} label={"Sort"} buttonType={"secondary"} diff --git a/src/components/Errors/GlobalErrorsList/styles.ts b/src/components/Errors/GlobalErrorsList/styles.ts index 51955fa4e..c02d88a07 100644 --- a/src/components/Errors/GlobalErrorsList/styles.ts +++ b/src/components/Errors/GlobalErrorsList/styles.ts @@ -91,7 +91,7 @@ export const EmptyStateContent = styled.div` color: ${({ theme }) => theme.colors.v3.text.tertiary}; `; -export const SortButtonIconContainer = styled.div` +export const ButtonIconContainer = styled.div` color: ${({ theme }) => theme.colors.v3.icon.tertiary}; `; diff --git a/src/components/Errors/GlobalErrorsList/types.ts b/src/components/Errors/GlobalErrorsList/types.ts index d2c8d5067..5a24fe0f7 100644 --- a/src/components/Errors/GlobalErrorsList/types.ts +++ b/src/components/Errors/GlobalErrorsList/types.ts @@ -17,6 +17,7 @@ export interface GetGlobalErrorsDataPayload { criticalities?: ErrorCriticality[]; handlingTypes?: ErrorHandlingType[]; dismissed?: boolean; + lastDays?: number; } export interface GlobalErrorData { diff --git a/src/components/Errors/tracking.ts b/src/components/Errors/tracking.ts index aa28fe0e8..ce1a48155 100644 --- a/src/components/Errors/tracking.ts +++ b/src/components/Errors/tracking.ts @@ -15,7 +15,17 @@ export const trackingEvents = addPrefix( WORKSPACE_ONLY_TOGGLE_SWITCHED: "workspace only toggle switched", GLOBAL_ERRORS_VIEW_SEARCH_CHANGED: "global errors view search changed", GLOBAL_ERRORS_VIEW_SORTING_CHANGE: "global errors view sorting change", + GLOBAL_ERRORS_VIEW_DATES_FILTERS_CHANGE: + "global errors view date filters change", GLOBAL_ERRORS_VIEW_PAGE_CHANGE: "global errors view page change", + GLOBAL_ERRORS_DAYS_FILTER_INPUT_VALUE_CHANGE: + "global errors days filter input value change", + GLOBAL_ERRORS_DAYS_FILTER_INCREMENT_CLICKED: + "global errors days filter increment change", + GLOBAL_ERRORS_DAYS_FILTER_DECREMENT_CLICKED: + "global errors days filter decrement change", + GLOBAL_ERRORS_DAYS_FILTER_APPLY_BTN_CLICKED: + "global errors days filter apply button clicked", GLOBAL_ERRORS_VIEW_RESET_FILTERS_BUTTON_CLICKED: "global errors view reset filters button clicked", GLOBAL_ERRORS_VIEW_FILTERS_BUTTON_CLICKED: diff --git a/src/components/Navigation/common/MenuList/index.tsx b/src/components/Navigation/common/MenuList/index.tsx index 6bdbc40b5..217a6ef20 100644 --- a/src/components/Navigation/common/MenuList/index.tsx +++ b/src/components/Navigation/common/MenuList/index.tsx @@ -12,7 +12,8 @@ export const MenuList = ({ items, showGroupDividers, highlightSelected, - header + header, + className }: MenuListProps) => { const groups = groupBy( items, @@ -21,7 +22,7 @@ export const MenuList = ({ const groupElements = Object.entries(groups).map(([groupName, items]) => { return ( - + {showGroupNames && groupName !== UNGROUPED_GROUP_LABEL && ( {groupName} )} diff --git a/src/components/Navigation/common/MenuList/types.ts b/src/components/Navigation/common/MenuList/types.ts index 1a16b9ef6..69d4cfb19 100644 --- a/src/components/Navigation/common/MenuList/types.ts +++ b/src/components/Navigation/common/MenuList/types.ts @@ -7,6 +7,7 @@ export interface MenuListProps { highlightSelected?: boolean; header?: ReactNode; isDisabled?: boolean; + className?: string; } export interface ListItemProps { diff --git a/src/components/common/icons/12px/CalendarIcon.tsx b/src/components/common/icons/12px/CalendarIcon.tsx new file mode 100644 index 000000000..06a7dd0b2 --- /dev/null +++ b/src/components/common/icons/12px/CalendarIcon.tsx @@ -0,0 +1,20 @@ +import React from "react"; +import { useIconProps } from "../hooks"; +import { IconProps } from "../types"; + +const CalendarIconComponent = (props: IconProps) => { + const { size, color } = useIconProps(props); + + return ( + + + + ); +}; + +export const CalendarIcon = React.memo(CalendarIconComponent); diff --git a/src/components/common/icons/16px/PlusIcon.tsx b/src/components/common/icons/16px/PlusIcon.tsx new file mode 100644 index 000000000..2a7b0feff --- /dev/null +++ b/src/components/common/icons/16px/PlusIcon.tsx @@ -0,0 +1,27 @@ +import React from "react"; +import { useIconProps } from "../hooks"; +import { IconProps } from "../types"; + +const PlusIconComponent = (props: IconProps) => { + const { size, color } = useIconProps(props); + + return ( + + + + + + + + + + + ); +}; + +export const PlusIcon = React.memo(PlusIconComponent); diff --git a/src/featureFlags.ts b/src/featureFlags.ts index 01c6c444a..48113da93 100644 --- a/src/featureFlags.ts +++ b/src/featureFlags.ts @@ -26,7 +26,8 @@ export const featureFlagMinBackendVersions: Record = { [FeatureFlag.ARE_GLOBAL_ERRORS_CRITICALITY_AND_UNHANDLED_FILTERS_ENABLED]: "0.3.145", [FeatureFlag.IS_GLOBAL_ERROR_PIN_ENABLED]: "0.3.147", - [FeatureFlag.IS_GLOBAL_ERROR_DISMISS_ENABLED]: "0.3.148" + [FeatureFlag.IS_GLOBAL_ERROR_DISMISS_ENABLED]: "0.3.148", + [FeatureFlag.IS_GLOBAL_ERROR_LAST_DAYS_FILTER_ENABLED]: "0.3.149" }; export const getFeatureFlagValue = ( diff --git a/src/store/errors/errorsSlice.ts b/src/store/errors/errorsSlice.ts index 1ad9d8961..6b8215b01 100644 --- a/src/store/errors/errorsSlice.ts +++ b/src/store/errors/errorsSlice.ts @@ -47,6 +47,7 @@ export interface ErrorsState { globalErrorsSelectedFilters: GlobalErrorsSelectedFiltersState; globalErrorsViewMode: ViewMode; errorDetailsWorkspaceItemsOnly: boolean; + globalErrorsLastDays?: number; } const selectedFiltersInitialState = { @@ -114,6 +115,8 @@ export const errorsSlice = createSlice({ ) => set({ errorDetailsWorkspaceItemsOnly }), setGlobalErrorsViewMode: (mode: ViewMode) => set({ globalErrorsViewMode: mode }), + setGlobalErrorsLastDays: (days?: number) => + set({ globalErrorsLastDays: days }), resetGlobalErrors: () => set({ ...globalErrorsInitialState }) } }); diff --git a/src/types.ts b/src/types.ts index 49c5f9b0c..46dcb77c1 100644 --- a/src/types.ts +++ b/src/types.ts @@ -27,7 +27,8 @@ export enum FeatureFlag { IS_ERROR_OCCURRENCE_CHART_ENABLED, ARE_GLOBAL_ERRORS_CRITICALITY_AND_UNHANDLED_FILTERS_ENABLED, IS_GLOBAL_ERROR_PIN_ENABLED, - IS_GLOBAL_ERROR_DISMISS_ENABLED + IS_GLOBAL_ERROR_DISMISS_ENABLED, + IS_GLOBAL_ERROR_LAST_DAYS_FILTER_ENABLED } export enum InsightType { From fa53dc46cef21906c0c670b9b98d4da254f2c4c9 Mon Sep 17 00:00:00 2001 From: opoliarush Date: Tue, 29 Oct 2024 17:21:15 +0200 Subject: [PATCH 2/4] fix small usage --- .../SpanUsagesInsightCard.stories.tsx | 15 +++++++++++++++ .../insightCards/SpanUsagesInsightCard/index.tsx | 4 +++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/insightCards/SpanUsagesInsightCard/SpanUsagesInsightCard.stories.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/insightCards/SpanUsagesInsightCard/SpanUsagesInsightCard.stories.tsx index c010e18f5..aa03566da 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/insightCards/SpanUsagesInsightCard/SpanUsagesInsightCard.stories.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/insightCards/SpanUsagesInsightCard/SpanUsagesInsightCard.stories.tsx @@ -33,3 +33,18 @@ export const WithoutUsage: Story = { } } }; + +export const WithSmallUsage: Story = { + args: { + insight: { + ...mockedSpanUsagesInsight, + sampleTrace: "sampleTraceId", + flows: [ + mockedSpanUsagesInsight.flows[0], + mockedSpanUsagesInsight.flows[1], + { ...mockedSpanUsagesInsight.flows[2], percentage: 0.001 } + ], + isRecalculateEnabled: false + } + } +}; diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/insightCards/SpanUsagesInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/insightCards/SpanUsagesInsightCard/index.tsx index 925d8dec8..d86c0689c 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/insightCards/SpanUsagesInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/insightCards/SpanUsagesInsightCard/index.tsx @@ -106,7 +106,9 @@ export const SpanUsagesInsightCard = ({ }, cell: (info) => { const percentage = info.getValue(); - const percentageString = `${roundTo(percentage, 2)}%`; + + const percentageString = + percentage < 0.01 ? "> 0.01%" : `${roundTo(percentage, 2)}%`; return ( Date: Wed, 30 Oct 2024 12:00:13 +0200 Subject: [PATCH 3/4] Update src/components/Insights/InsightsCatalog/InsightsPage/insightCards/SpanUsagesInsightCard/index.tsx Co-authored-by: Kyrylo Shmidt <119138536+kshmidt-digma@users.noreply.github.com> --- .../InsightsPage/insightCards/SpanUsagesInsightCard/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Insights/InsightsCatalog/InsightsPage/insightCards/SpanUsagesInsightCard/index.tsx b/src/components/Insights/InsightsCatalog/InsightsPage/insightCards/SpanUsagesInsightCard/index.tsx index d86c0689c..7198e58e0 100644 --- a/src/components/Insights/InsightsCatalog/InsightsPage/insightCards/SpanUsagesInsightCard/index.tsx +++ b/src/components/Insights/InsightsCatalog/InsightsPage/insightCards/SpanUsagesInsightCard/index.tsx @@ -108,7 +108,7 @@ export const SpanUsagesInsightCard = ({ const percentage = info.getValue(); const percentageString = - percentage < 0.01 ? "> 0.01%" : `${roundTo(percentage, 2)}%`; + percentage < 0.01 ? "<0.01%" : `${roundTo(percentage, 2)}%`; return ( Date: Wed, 30 Oct 2024 12:00:20 +0200 Subject: [PATCH 4/4] Update src/components/Errors/GlobalErrorsList/DaysFilter/index.tsx Co-authored-by: Kyrylo Shmidt <119138536+kshmidt-digma@users.noreply.github.com> --- src/components/Errors/GlobalErrorsList/DaysFilter/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Errors/GlobalErrorsList/DaysFilter/index.tsx b/src/components/Errors/GlobalErrorsList/DaysFilter/index.tsx index 19dc4c88e..4840f842b 100644 --- a/src/components/Errors/GlobalErrorsList/DaysFilter/index.tsx +++ b/src/components/Errors/GlobalErrorsList/DaysFilter/index.tsx @@ -64,7 +64,7 @@ export const DaysFilter = ({ onChanged }: DaysFilterProps) => { const newValue = e.target.value; const intValue = parseInt(newValue); const days = - !newValue || isNaN(intValue) + !newValue || Number.isNaN(intValue) ? undefined : intValue > MAX_VALUE ? selectedDays