Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
201 changes: 174 additions & 27 deletions src/components/Errors/GlobalErrorsList/GlobalErrorsFilters/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
import { useCallback, useEffect, useMemo, useState } from "react";
import { getFeatureFlagValue } from "../../../../featureFlags";
import { useFetchData } from "../../../../hooks/useFetchData";
import { usePrevious } from "../../../../hooks/usePrevious";
import { useConfigSelector } from "../../../../store/config/useConfigSelector";
import {
ErrorCriticality,
ErrorFilter,
ErrorHandlingType,
GlobalErrorsFiltersState
} from "../../../../store/errors/errorsSlice";
import { useErrorsSelector } from "../../../../store/errors/useErrorsSelector";
import { useStore } from "../../../../store/useStore";
import { FeatureFlag } from "../../../../types";
import { sendUserActionTrackingEvent } from "../../../../utils/actions/sendUserActionTrackingEvent";
import { FilterPopup } from "../../../common/FilterPopup";
import { EyeIcon } from "../../../common/icons/12px/EyeIcon";
import { WarningTriangleIcon } from "../../../common/icons/12px/WarningTriangleIcon";
import { WrenchIcon } from "../../../common/icons/12px/WrenchIcon";
import { CrossCircleIcon } from "../../../common/icons/CrossCircleIcon";
import { EndpointIcon } from "../../../common/icons/EndpointIcon";
Expand All @@ -28,7 +34,14 @@ const getSelectPlaceholder = (options: SelectItem[], placeholder: string) =>
options.filter((x) => x.selected).length > 0 ? placeholder : "All";

export const GlobalErrorsFilters = () => {
const { environment } = useConfigSelector();
const { environment, backendInfo } = useConfigSelector();

const areGlobalErrorsCriticalityAndUnhandledFiltersEnabled =
getFeatureFlagValue(
backendInfo,
FeatureFlag.ARE_GLOBAL_ERRORS_CRITICALITY_AND_UNHANDLED_FILTERS_ENABLED
);

const { globalErrorsFilters, globalErrorsSelectedFilters } =
useErrorsSelector();
const { setGlobalErrorsFilters, setGlobalErrorsSelectedFilters } =
Expand All @@ -47,6 +60,12 @@ export const GlobalErrorsFilters = () => {
const [selectedErrorTypes, setSelectedErrorTypes] = useState<string[]>(
globalErrorsSelectedFilters.errorTypes
);
const [selectedCriticalities, setSelectedCriticalities] = useState<
ErrorCriticality[]
>(globalErrorsSelectedFilters.criticalities);
const [selectedHandlingTypes, setSelectedHandlingTypes] = useState<
ErrorHandlingType[]
>(globalErrorsSelectedFilters.handlingTypes);

const getLastSelectedFilterValues = useCallback(
(changedFilter: ErrorFilter) => {
Expand Down Expand Up @@ -171,29 +190,111 @@ export const GlobalErrorsFilters = () => {
setSelectedErrorTypes(newValue);
};

const servicesFilterOptions: SelectItem[] =
services?.map((x) => ({
label: x,
value: x,
selected: selectedServices.includes(x),
enabled: true
})) ?? [];

const endpointsFilterOptions: SelectItem[] =
endpoints?.map((x) => ({
label: x.displayName,
value: x.spanCodeObjectId,
selected: selectedEndpoints.includes(x.spanCodeObjectId),
enabled: true
})) ?? [];

const errorTypesFilterOptions: SelectItem[] =
errorTypes?.map((x) => ({
label: x,
value: x,
selected: selectedErrorTypes.includes(x),
enabled: true
})) ?? [];
const handleCriticalityChange = (value: string | string[]) => {
sendUserActionTrackingEvent(
trackingEvents.GLOBAL_ERRORS_VIEW_CRITICALITY_FILTER_CHANGED
);
const newValue = Array.isArray(value) ? value : [value];
setSelectedCriticalities(newValue as ErrorCriticality[]);
};

const handleHandlingTypeChange = (value: string | string[]) => {
sendUserActionTrackingEvent(
trackingEvents.GLOBAL_ERRORS_VIEW_UNHANDLED_FILTER_CHANGED
);
const newValue = value === "All" ? [] : [value];
setSelectedHandlingTypes(newValue as ErrorHandlingType[]);
};

const servicesFilterOptions: SelectItem[] = useMemo(
() =>
services?.map((x) => ({
label: x,
value: x,
selected: selectedServices.includes(x),
enabled: true
})) ?? [],
[services, selectedServices]
);

const endpointsFilterOptions: SelectItem[] = useMemo(
() =>
endpoints?.map((x) => ({
label: x.displayName,
value: x.spanCodeObjectId,
selected: selectedEndpoints.includes(x.spanCodeObjectId),
enabled: true
})) ?? [],
[endpoints, selectedEndpoints]
);

const errorTypesFilterOptions: SelectItem[] = useMemo(
() =>
errorTypes?.map((x) => ({
label: x,
value: x,
selected: selectedErrorTypes.includes(x),
enabled: true
})) ?? [],
[errorTypes, selectedErrorTypes]
);

const criticalityFilterOptions: SelectItem[] = useMemo(
() => [
{
label: "Critical",
value: "High",
selected: selectedCriticalities.includes("High"),
enabled: true
},
{
label: "Medium",
value: "Medium",
selected: selectedCriticalities.includes("Medium"),
enabled: true
},
{
label: "Low",
value: "Low",
selected: selectedCriticalities.includes("Low"),
enabled: true
}
],
[selectedCriticalities]
);

const handlingTypeFilterOptions: SelectItem[] = useMemo(
() => [
{
label: "Yes",
value: "Handled",
selected:
selectedHandlingTypes.length === 1 &&
selectedHandlingTypes[0] === "Handled",
enabled: true
},
{
label: "No",
value: "Unhandled",
selected:
selectedHandlingTypes.length === 1 &&
selectedHandlingTypes[0] === "Unhandled",
enabled: true
},
{
label: "All",
value: "All",
selected: selectedHandlingTypes.length === 0,
enabled: true
}
],
[selectedHandlingTypes]
);

const selectedHandlingTypeOption = useMemo(
() => handlingTypeFilterOptions.find((x) => x.selected),
[handlingTypeFilterOptions]
);

const filters = [
{
Expand Down Expand Up @@ -255,15 +356,57 @@ export const GlobalErrorsFilters = () => {
disabled={errorTypesFilterOptions?.length === 0}
/>
)
}
},
...(areGlobalErrorsCriticalityAndUnhandledFiltersEnabled
? [
{
title: "Criticality",
component: (
<s.StyledSelect
key={"criticality"}
items={criticalityFilterOptions}
onChange={handleCriticalityChange}
placeholder={getSelectPlaceholder(
criticalityFilterOptions,
"Criticality levels"
)}
multiselect={true}
icon={(props: IconProps) => (
<s.SelectItemIconContainer>
<WarningTriangleIcon {...props} />
</s.SelectItemIconContainer>
)}
/>
)
},
{
title: "Unhandled",
component: (
<s.StyledSelect
key={"handlingType"}
items={handlingTypeFilterOptions}
onChange={handleHandlingTypeChange}
placeholder={selectedHandlingTypeOption?.label ?? "All"}
icon={(props: IconProps) => (
<s.SelectItemIconContainer>
<EyeIcon {...props} />
</s.SelectItemIconContainer>
)}
/>
)
}
]
: [])
];

const applyFilters = () => {
setGlobalErrorsSelectedFilters({
...globalErrorsSelectedFilters,
services: selectedServices,
endpoints: selectedEndpoints,
errorTypes: selectedErrorTypes
errorTypes: selectedErrorTypes,
criticalities: selectedCriticalities,
handlingTypes: selectedHandlingTypes
});
};

Expand All @@ -281,12 +424,16 @@ export const GlobalErrorsFilters = () => {
setSelectedServices([]);
setSelectedEndpoints([]);
setSelectedErrorTypes([]);
setSelectedCriticalities([]);
setSelectedHandlingTypes([]);
};

const selectedFiltersCount = [
selectedServices.length,
selectedEndpoints.length,
selectedErrorTypes.length
selectedErrorTypes.length,
selectedCriticalities.length,
selectedHandlingTypes.length
].filter((x) => x > 0).length;

const handlePopupOpenStateChange = (isOpen: boolean) => {
Expand Down
21 changes: 16 additions & 5 deletions src/components/Errors/GlobalErrorsList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ export const GlobalErrorsList = () => {
FeatureFlag.ARE_GLOBAL_ERRORS_FILTERS_ENABLED
);

const areGlobalErrorsCriticalityAndUnhandledFiltersEnabled =
getFeatureFlagValue(
backendInfo,
FeatureFlag.ARE_GLOBAL_ERRORS_CRITICALITY_AND_UNHANDLED_FILTERS_ENABLED
);

const environmentId = environment?.id;

const sortingMenuItems = Object.values(GLOBAL_ERROR_SORTING_CRITERION).map(
Expand Down Expand Up @@ -98,8 +104,12 @@ export const GlobalErrorsList = () => {
? {
services: selectedFilters.services,
endpoints: selectedFilters.endpoints,
errorTypes: selectedFilters.errorTypes,
criticality: selectedFilters.criticality,
errorTypes: selectedFilters.errorTypes
}
: {}),
...(areGlobalErrorsCriticalityAndUnhandledFiltersEnabled
? {
criticalities: selectedFilters.criticalities,
handlingTypes: selectedFilters.handlingTypes
}
: {})
Expand All @@ -110,10 +120,11 @@ export const GlobalErrorsList = () => {
sorting,
page,
areGlobalErrorsFiltersEnabled,
areGlobalErrorsCriticalityAndUnhandledFiltersEnabled,
selectedFilters.services,
selectedFilters.endpoints,
selectedFilters.errorTypes,
selectedFilters.criticality,
selectedFilters.criticalities,
selectedFilters.handlingTypes
]
);
Expand All @@ -140,7 +151,7 @@ export const GlobalErrorsList = () => {
selectedFilters.services,
selectedFilters.endpoints,
selectedFilters.errorTypes,
selectedFilters.criticality,
selectedFilters.criticalities,
selectedFilters.handlingTypes
]);

Expand Down Expand Up @@ -209,7 +220,7 @@ export const GlobalErrorsList = () => {
selectedFilters.services,
selectedFilters.endpoints,
selectedFilters.errorTypes,
selectedFilters.criticality,
selectedFilters.criticalities,
selectedFilters.handlingTypes
].some((x) => x.length > 0);

Expand Down
2 changes: 1 addition & 1 deletion src/components/Errors/GlobalErrorsList/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface GetGlobalErrorsDataPayload {
services?: string[];
endpoints?: string[];
errorTypes?: string[];
criticality?: ErrorCriticality[];
criticalities?: ErrorCriticality[];
handlingTypes?: ErrorHandlingType[];
}

Expand Down
4 changes: 4 additions & 0 deletions src/components/Errors/tracking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export const trackingEvents = addPrefix(
"global errors view endpoints filter changed",
GLOBAL_ERRORS_VIEW_ERROR_TYPES_FILTER_CHANGED:
"global errors view error types filter changed",
GLOBAL_ERRORS_VIEW_CRITICALITY_FILTER_CHANGED:
"global errors view criticality filter changed",
GLOBAL_ERRORS_VIEW_UNHANDLED_FILTER_CHANGED:
"global errors view unhandled filter changed",
GLOBAL_ERRORS_VIEW_FILTERS_CLOSE_BUTTON_CLICKED:
"global errors view filters close button clicked",
GLOBAL_ERRORS_VIEW_CLEAR_FILTERS_BUTTON_CLICKED:
Expand Down
4 changes: 3 additions & 1 deletion src/featureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ export const featureFlagMinBackendVersions: Record<FeatureFlag, string> = {
[FeatureFlag.IS_METRICS_REPORT_ENDPOINT_VIEW_ENABLED]: "0.3.122-alpha.3",
[FeatureFlag.ARE_GLOBAL_ERRORS_ENABLED]: "0.3.129",
[FeatureFlag.ARE_GLOBAL_ERRORS_FILTERS_ENABLED]: "0.3.140-alpha.2",
[FeatureFlag.IS_ERROR_OCCURRENCE_CHART_ENABLED]: "0.3.141-alpha.3"
[FeatureFlag.IS_ERROR_OCCURRENCE_CHART_ENABLED]: "0.3.141-alpha.3",
[FeatureFlag.ARE_GLOBAL_ERRORS_CRITICALITY_AND_UNHANDLED_FILTERS_ENABLED]:
"0.3.145"
};

export const getFeatureFlagValue = (
Expand Down
4 changes: 2 additions & 2 deletions src/store/errors/errorsSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export interface GlobalErrorsSelectedFiltersState {
services: string[];
endpoints: string[];
errorTypes: string[];
criticality: ErrorCriticality[];
criticalities: ErrorCriticality[];
handlingTypes: ErrorHandlingType[];
}

Expand All @@ -47,7 +47,7 @@ const selectedFiltersInitialState = {
services: [],
endpoints: [],
errorTypes: [],
criticality: [],
criticalities: [],
handlingTypes: []
};

Expand Down
3 changes: 2 additions & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ export enum FeatureFlag {
IS_METRICS_REPORT_ENDPOINT_VIEW_ENABLED,
ARE_GLOBAL_ERRORS_ENABLED,
ARE_GLOBAL_ERRORS_FILTERS_ENABLED,
IS_ERROR_OCCURRENCE_CHART_ENABLED
IS_ERROR_OCCURRENCE_CHART_ENABLED,
ARE_GLOBAL_ERRORS_CRITICALITY_AND_UNHANDLED_FILTERS_ENABLED
}

export enum InsightType {
Expand Down
Loading