From 0e9c39143dc9145f1c5442e830d860b522938f9a Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Mon, 20 Jan 2025 13:19:56 +0430 Subject: [PATCH 01/10] feat: add documentation link for logs explorer quick filters --- .../Checkbox/Checkbox.styles.scss | 14 ++++++++ .../FilterRenderers/Checkbox/Checkbox.tsx | 35 +++++++++++++++++-- .../components/QuickFilters/QuickFilters.tsx | 17 +++++++-- 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.styles.scss b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.styles.scss index 72fc1b44b2a..44b59a36f8c 100644 --- a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.styles.scss +++ b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.styles.scss @@ -130,6 +130,20 @@ cursor: pointer; } } + .go-to-docs { + display: flex; + align-items: center; + gap: 4px; + cursor: pointer; + margin-bottom: 4px; + &__text { + color: var(--bg-robin-400); + font-family: Inter; + font-size: 14px; + line-height: 20px; /* 142.857% */ + letter-spacing: -0.07px; + } + } } .lightMode { diff --git a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx index 8b48a55dde5..8cf8632daac 100644 --- a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx +++ b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx @@ -4,6 +4,7 @@ /* eslint-disable jsx-a11y/click-events-have-key-events */ import './Checkbox.styles.scss'; +import { Color } from '@signozhq/design-tokens'; import { Button, Checkbox, Input, Skeleton, Typography } from 'antd'; import cx from 'classnames'; import { IQuickFiltersConfig } from 'components/QuickFilters/QuickFilters'; @@ -14,7 +15,7 @@ import { useGetAggregateValues } from 'hooks/queryBuilder/useGetAggregateValues' import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import useDebouncedFn from 'hooks/useDebouncedFunction'; import { cloneDeep, isArray, isEmpty, isEqual, isFunction } from 'lodash-es'; -import { ChevronDown, ChevronRight } from 'lucide-react'; +import { ArrowUpRight, ChevronDown, ChevronRight } from 'lucide-react'; import { useMemo, useState } from 'react'; import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse'; import { Query, TagFilterItem } from 'types/api/queryBuilder/queryBuilderData'; @@ -36,11 +37,23 @@ function setDefaultValues( } interface ICheckboxProps { filter: IQuickFiltersConfig; + isInfraMonitoring: boolean; onFilterChange?: (query: Query) => void; } +const QUICK_FILTER_DOC_PATHS: Record = { + severity_text: 'severity-text', + 'deployment.environment': 'environment', + 'service.name': 'service-name', + 'host.name': 'hostname', + 'k8s.cluster.name': 'k8s-cluster-name', + 'k8s.deployment.name': 'k8s-deployment-name', + 'k8s.namespace.name': 'k8s-namespace-name', + 'k8s.pod.name': 'k8s-pod-name', +}; + export default function CheckboxFilter(props: ICheckboxProps): JSX.Element { - const { filter, onFilterChange } = props; + const { isInfraMonitoring, filter, onFilterChange } = props; const [searchText, setSearchText] = useState(''); const [isOpen, setIsOpen] = useState(filter.defaultOpen); const [visibleItemsCount, setVisibleItemsCount] = useState(10); @@ -410,6 +423,15 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element { } }; + const handleLearnMoreClick = (): void => { + const section = QUICK_FILTER_DOC_PATHS[filter.attributeKey.key]; + + window.open( + `https://signoz.io/docs/logs-management/features/logs-quick-filters#${section}`, + '_blank', + ); + }; + return (
)} + + {!isInfraMonitoring && ( +
+ + Learn more + + +
+ )} )}
diff --git a/frontend/src/components/QuickFilters/QuickFilters.tsx b/frontend/src/components/QuickFilters/QuickFilters.tsx index bc367b58fce..0e0840a7ed4 100644 --- a/frontend/src/components/QuickFilters/QuickFilters.tsx +++ b/frontend/src/components/QuickFilters/QuickFilters.tsx @@ -128,11 +128,24 @@ export default function QuickFilters(props: IQuickFiltersProps): JSX.Element { {config.map((filter) => { switch (filter.type) { case FiltersType.CHECKBOX: - return ; + return ( + + ); case FiltersType.SLIDER: return ; + // eslint-disable-next-line sonarjs/no-duplicated-branches default: - return ; + return ( + + ); } })} From 8722d67d6b7c241b2949bbacb15cee4e98a05a1b Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Mon, 20 Jan 2025 13:21:06 +0430 Subject: [PATCH 02/10] refactor: simplify QuickFilters component rendering logic --- .../components/QuickFilters/QuickFilters.tsx | 30 +++++++------------ 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/frontend/src/components/QuickFilters/QuickFilters.tsx b/frontend/src/components/QuickFilters/QuickFilters.tsx index 0e0840a7ed4..e4098f9d9b0 100644 --- a/frontend/src/components/QuickFilters/QuickFilters.tsx +++ b/frontend/src/components/QuickFilters/QuickFilters.tsx @@ -126,27 +126,17 @@ export default function QuickFilters(props: IQuickFiltersProps): JSX.Element {
{config.map((filter) => { - switch (filter.type) { - case FiltersType.CHECKBOX: - return ( - - ); - case FiltersType.SLIDER: - return ; - // eslint-disable-next-line sonarjs/no-duplicated-branches - default: - return ( - - ); + if (filter.type === FiltersType.SLIDER) { + return ; } + return ( + + ); })}
From 2cc7b8631684a818d1487e2c6d6afbeba0f49bf6 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Mon, 20 Jan 2025 17:25:59 +0430 Subject: [PATCH 03/10] fix: properly implement the log fast filter empty state UI --- .../CustomIcons/EmptyQuickFilterIcon.tsx | 90 +++++++++ .../Checkbox/Checkbox.styles.scss | 38 +++- .../FilterRenderers/Checkbox/Checkbox.tsx | 174 ++++++++++-------- 3 files changed, 213 insertions(+), 89 deletions(-) create mode 100644 frontend/src/assets/CustomIcons/EmptyQuickFilterIcon.tsx diff --git a/frontend/src/assets/CustomIcons/EmptyQuickFilterIcon.tsx b/frontend/src/assets/CustomIcons/EmptyQuickFilterIcon.tsx new file mode 100644 index 00000000000..89ab66896d0 --- /dev/null +++ b/frontend/src/assets/CustomIcons/EmptyQuickFilterIcon.tsx @@ -0,0 +1,90 @@ +interface EmptyQuickFilterIconProps { + width?: number; + height?: number; + className?: string; +} + +function EmptyQuickFilterIcon({ + width = 32, + height = 32, + className, +}: EmptyQuickFilterIconProps): JSX.Element { + return ( + + + + + + + + + + + + + + + + + + + + ); +} + +EmptyQuickFilterIcon.defaultProps = { + width: 32, + height: 32, + className: '', +}; + +export default EmptyQuickFilterIcon; diff --git a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.styles.scss b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.styles.scss index 44b59a36f8c..81de180b3ed 100644 --- a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.styles.scss +++ b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.styles.scss @@ -132,16 +132,34 @@ } .go-to-docs { display: flex; - align-items: center; - gap: 4px; - cursor: pointer; - margin-bottom: 4px; - &__text { - color: var(--bg-robin-400); - font-family: Inter; - font-size: 14px; - line-height: 20px; /* 142.857% */ - letter-spacing: -0.07px; + flex-direction: column; + gap: 64px; + &__container { + display: flex; + flex-direction: column; + gap: 4px; + margin-top: 4px; + + &-message { + color: var(--bg-vanilla-400); + font-size: 14px; + line-height: 20px; /* 142.857% */ + letter-spacing: -0.07px; + } + } + &__button { + display: flex; + align-items: center; + gap: 4px; + cursor: pointer; + margin-bottom: 4px; + &-text { + color: var(--bg-robin-400); + font-family: Inter; + font-size: 14px; + line-height: 20px; /* 142.857% */ + letter-spacing: -0.07px; + } } } } diff --git a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx index 8cf8632daac..5585e2c2bfd 100644 --- a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx +++ b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx @@ -6,6 +6,7 @@ import './Checkbox.styles.scss'; import { Color } from '@signozhq/design-tokens'; import { Button, Checkbox, Input, Skeleton, Typography } from 'antd'; +import EmptyQuickFilterIcon from 'assets/CustomIcons/EmptyQuickFilterIcon'; import cx from 'classnames'; import { IQuickFiltersConfig } from 'components/QuickFilters/QuickFilters'; import { OPERATORS } from 'constants/queryBuilder'; @@ -52,6 +53,7 @@ const QUICK_FILTER_DOC_PATHS: Record = { 'k8s.pod.name': 'k8s-pod-name', }; +// eslint-disable-next-line sonarjs/cognitive-complexity export default function CheckboxFilter(props: ICheckboxProps): JSX.Element { const { isInfraMonitoring, filter, onFilterChange } = props; const [searchText, setSearchText] = useState(''); @@ -454,7 +456,7 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element { {filter.title}
- {isOpen && ( + {isOpen && !!attributeValues.length && ( { @@ -473,88 +475,102 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element {
)} - {isOpen && !isLoading && ( - <> -
- setSearchTextDebounced(e.target.value)} - disabled={isFilterDisabled} - /> -
- {attributeValues.length > 0 ? ( -
- {currentAttributeKeys.map((value: string) => ( -
- onChange(value, e.target.checked, false)} - checked={currentFilterState[value]} - disabled={isFilterDisabled} - rootClassName="check-box" - /> - -
{ - if (isFilterDisabled) { - return; - } - onChange(value, currentFilterState[value], true); - }} - > - {filter.customRendererForValue ? ( - filter.customRendererForValue(value) - ) : ( - - {value} - - )} - - -
-
- ))} -
- ) : ( -
- No values found{' '} -
- )} - {visibleItemsCount < attributeValues?.length && ( -
- setVisibleItemsCount((prev) => prev + 10)} - > - Show More... - -
- )} - - {!isInfraMonitoring && ( -
- + {isOpen ? ( + !isLoading && !isInfraMonitoring && !attributeValues.length ? ( +
+
+
+ +
+
+ {`You'd need to parse out this attribute to start getting them as a fast + filter.`} +
+
+
+ Learn more +
+
+ ) : ( + <> +
+ setSearchTextDebounced(e.target.value)} + disabled={isFilterDisabled} + />
- )} - - )} + {attributeValues.length > 0 ? ( +
+ { + // eslint-disable-next-line sonarjs/cognitive-complexity + currentAttributeKeys.map((value: string) => ( +
+ onChange(value, e.target.checked, false)} + checked={currentFilterState[value]} + disabled={isFilterDisabled} + rootClassName="check-box" + /> + +
{ + if (isFilterDisabled) { + return; + } + onChange(value, currentFilterState[value], true); + }} + > + {filter.customRendererForValue ? ( + filter.customRendererForValue(value) + ) : ( + + {value} + + )} + + +
+
+ )) + } +
+ ) : ( +
+ No values found{' '} +
+ )} + {visibleItemsCount < attributeValues?.length && ( +
+ setVisibleItemsCount((prev) => prev + 10)} + > + Show More... + +
+ )} + + ) + ) : null} ); } From 369bad5806e02ab6d7769383bca9b6b87b4a0b6b Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 21 Jan 2025 08:38:11 +0430 Subject: [PATCH 04/10] fix: don't display empty state while loading quick filters --- .../QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx index 5585e2c2bfd..46cd2d4030b 100644 --- a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx +++ b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx @@ -475,8 +475,8 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element {
)} - {isOpen ? ( - !isLoading && !isInfraMonitoring && !attributeValues.length ? ( + {isOpen && !isLoading ? ( + !isInfraMonitoring && !attributeValues.length ? (
From 40c9a18d40bcda1efaefcf1df56f4fe3ac2db103 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 21 Jan 2025 08:40:39 +0430 Subject: [PATCH 05/10] refactor: extract quick filter empty state into a separate component --- .../Checkbox/Checkbox.styles.scss | 3 +- .../FilterRenderers/Checkbox/Checkbox.tsx | 44 ++------------- .../Checkbox/QuickFilterEmptyState.tsx | 53 +++++++++++++++++++ 3 files changed, 59 insertions(+), 41 deletions(-) create mode 100644 frontend/src/components/QuickFilters/FilterRenderers/Checkbox/QuickFilterEmptyState.tsx diff --git a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.styles.scss b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.styles.scss index 81de180b3ed..2d7834b6264 100644 --- a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.styles.scss +++ b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.styles.scss @@ -152,7 +152,8 @@ align-items: center; gap: 4px; cursor: pointer; - margin-bottom: 4px; + margin: 0 0 4px; + padding: 0; &-text { color: var(--bg-robin-400); font-family: Inter; diff --git a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx index 46cd2d4030b..890e70ef524 100644 --- a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx +++ b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx @@ -4,9 +4,7 @@ /* eslint-disable jsx-a11y/click-events-have-key-events */ import './Checkbox.styles.scss'; -import { Color } from '@signozhq/design-tokens'; import { Button, Checkbox, Input, Skeleton, Typography } from 'antd'; -import EmptyQuickFilterIcon from 'assets/CustomIcons/EmptyQuickFilterIcon'; import cx from 'classnames'; import { IQuickFiltersConfig } from 'components/QuickFilters/QuickFilters'; import { OPERATORS } from 'constants/queryBuilder'; @@ -16,13 +14,15 @@ import { useGetAggregateValues } from 'hooks/queryBuilder/useGetAggregateValues' import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import useDebouncedFn from 'hooks/useDebouncedFunction'; import { cloneDeep, isArray, isEmpty, isEqual, isFunction } from 'lodash-es'; -import { ArrowUpRight, ChevronDown, ChevronRight } from 'lucide-react'; +import { ChevronDown, ChevronRight } from 'lucide-react'; import { useMemo, useState } from 'react'; import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse'; import { Query, TagFilterItem } from 'types/api/queryBuilder/queryBuilderData'; import { DataSource } from 'types/common/queryBuilder'; import { v4 as uuid } from 'uuid'; +import QuickFilterEmptyState from './QuickFilterEmptyState'; + const SELECTED_OPERATORS = [OPERATORS['='], 'in']; const NON_SELECTED_OPERATORS = [OPERATORS['!='], 'nin']; @@ -42,17 +42,6 @@ interface ICheckboxProps { onFilterChange?: (query: Query) => void; } -const QUICK_FILTER_DOC_PATHS: Record = { - severity_text: 'severity-text', - 'deployment.environment': 'environment', - 'service.name': 'service-name', - 'host.name': 'hostname', - 'k8s.cluster.name': 'k8s-cluster-name', - 'k8s.deployment.name': 'k8s-deployment-name', - 'k8s.namespace.name': 'k8s-namespace-name', - 'k8s.pod.name': 'k8s-pod-name', -}; - // eslint-disable-next-line sonarjs/cognitive-complexity export default function CheckboxFilter(props: ICheckboxProps): JSX.Element { const { isInfraMonitoring, filter, onFilterChange } = props; @@ -425,15 +414,6 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element { } }; - const handleLearnMoreClick = (): void => { - const section = QUICK_FILTER_DOC_PATHS[filter.attributeKey.key]; - - window.open( - `https://signoz.io/docs/logs-management/features/logs-quick-filters#${section}`, - '_blank', - ); - }; - return (
-
-
- -
-
- {`You'd need to parse out this attribute to start getting them as a fast - filter.`} -
-
-
- - Learn more - - -
-
+ ) : ( <>
diff --git a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/QuickFilterEmptyState.tsx b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/QuickFilterEmptyState.tsx new file mode 100644 index 00000000000..8537eab3d9a --- /dev/null +++ b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/QuickFilterEmptyState.tsx @@ -0,0 +1,53 @@ +import { Color } from '@signozhq/design-tokens'; +import { Button } from 'antd'; +import EmptyQuickFilterIcon from 'assets/CustomIcons/EmptyQuickFilterIcon'; +import { ArrowUpRight } from 'lucide-react'; + +const QUICK_FILTER_DOC_PATHS: Record = { + severity_text: 'severity-text', + 'deployment.environment': 'environment', + 'service.name': 'service-name', + 'host.name': 'hostname', + 'k8s.cluster.name': 'k8s-cluster-name', + 'k8s.deployment.name': 'k8s-deployment-name', + 'k8s.namespace.name': 'k8s-namespace-name', + 'k8s.pod.name': 'k8s-pod-name', +}; + +function QuickFilterEmptyState({ + attributeKey, +}: { + attributeKey: string; +}): JSX.Element { + const handleLearnMoreClick = (): void => { + const section = QUICK_FILTER_DOC_PATHS[attributeKey]; + + window.open( + `https://signoz.io/docs/logs-management/features/logs-quick-filters#${section}`, + '_blank', + ); + }; + return ( +
+
+
+ +
+
+ {`You'd need to parse out this attribute to start getting them as a fast + filter.`} +
+
+ +
+ ); +} + +export default QuickFilterEmptyState; From 96154a84e564021b69936d285ed1399cfafc54b3 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Wed, 22 Jan 2025 11:19:29 +0430 Subject: [PATCH 06/10] refactor: render quick filters empty state based on source param --- .../FilterRenderers/Checkbox/Checkbox.tsx | 153 +++++++++--------- .../components/QuickFilters/QuickFilters.tsx | 13 +- .../InfraMonitoringK8s/InfraMonitoringK8s.tsx | 8 +- frontend/src/pages/LogsExplorer/index.tsx | 5 +- 4 files changed, 97 insertions(+), 82 deletions(-) diff --git a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx index 890e70ef524..cae5506fb6e 100644 --- a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx +++ b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx @@ -6,7 +6,10 @@ import './Checkbox.styles.scss'; import { Button, Checkbox, Input, Skeleton, Typography } from 'antd'; import cx from 'classnames'; -import { IQuickFiltersConfig } from 'components/QuickFilters/QuickFilters'; +import { + IQuickFiltersConfig, + QuickFiltersSource, +} from 'components/QuickFilters/QuickFilters'; import { OPERATORS } from 'constants/queryBuilder'; import { DEBOUNCE_DELAY } from 'constants/queryBuilderFilterConfig'; import { getOperatorValue } from 'container/QueryBuilder/filters/QueryBuilderSearch/utils'; @@ -38,13 +41,13 @@ function setDefaultValues( } interface ICheckboxProps { filter: IQuickFiltersConfig; - isInfraMonitoring: boolean; + source: QuickFiltersSource; onFilterChange?: (query: Query) => void; } // eslint-disable-next-line sonarjs/cognitive-complexity export default function CheckboxFilter(props: ICheckboxProps): JSX.Element { - const { isInfraMonitoring, filter, onFilterChange } = props; + const { source, filter, onFilterChange } = props; const [searchText, setSearchText] = useState(''); const [isOpen, setIsOpen] = useState(filter.defaultOpen); const [visibleItemsCount, setVisibleItemsCount] = useState(10); @@ -414,6 +417,11 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element { } }; + const isEmptyStateWithDocsEnabled = + [QuickFiltersSource.LOGS_EXPLORER].includes(source) && + !searchText && + !attributeValues.length; + return (
)} - {isOpen && !isLoading ? ( - !isInfraMonitoring && !attributeValues.length ? ( - - ) : ( - <> + {isOpen && !isLoading && ( + <> + {!isEmptyStateWithDocsEnabled && (
- {attributeValues.length > 0 ? ( -
- { - // eslint-disable-next-line sonarjs/cognitive-complexity - currentAttributeKeys.map((value: string) => ( -
- onChange(value, e.target.checked, false)} - checked={currentFilterState[value]} - disabled={isFilterDisabled} - rootClassName="check-box" - /> + )} + {attributeValues.length > 0 ? ( +
+ {currentAttributeKeys.map((value: string) => ( +
+ onChange(value, e.target.checked, false)} + checked={currentFilterState[value]} + disabled={isFilterDisabled} + rootClassName="check-box" + /> -
{ - if (isFilterDisabled) { - return; - } - onChange(value, currentFilterState[value], true); - }} +
{ + if (isFilterDisabled) { + return; + } + onChange(value, currentFilterState[value], true); + }} + > + {filter.customRendererForValue ? ( + filter.customRendererForValue(value) + ) : ( + - {filter.customRendererForValue ? ( - filter.customRendererForValue(value) - ) : ( - - {value} - - )} - - -
-
- )) - } -
- ) : ( -
- No values found{' '} -
- )} - {visibleItemsCount < attributeValues?.length && ( -
- setVisibleItemsCount((prev) => prev + 10)} - > - Show More... - -
- )} - - ) - ) : null} + {value} + + )} + + +
+
+ ))} +
+ ) : isEmptyStateWithDocsEnabled ? ( + + ) : ( +
+ No values found{' '} +
+ )} + {visibleItemsCount < attributeValues?.length && ( +
+ setVisibleItemsCount((prev) => prev + 10)} + > + Show More... + +
+ )} + + )}
); } diff --git a/frontend/src/components/QuickFilters/QuickFilters.tsx b/frontend/src/components/QuickFilters/QuickFilters.tsx index e4098f9d9b0..6b25d3b1916 100644 --- a/frontend/src/components/QuickFilters/QuickFilters.tsx +++ b/frontend/src/components/QuickFilters/QuickFilters.tsx @@ -41,10 +41,16 @@ export interface IQuickFiltersConfig { defaultOpen: boolean; } +export enum QuickFiltersSource { + LOGS_EXPLORER = 'logs-explorer', + INFRA_MONITORING = 'infra-monitoring', + TRACES_EXPLORER = 'traces-explorer', +} + interface IQuickFiltersProps { config: IQuickFiltersConfig[]; handleFilterVisibilityChange: () => void; - source?: string | null; + source: QuickFiltersSource; onFilterChange?: (query: Query) => void; } @@ -95,7 +101,7 @@ export default function QuickFilters(props: IQuickFiltersProps): JSX.Element { const lastQueryName = currentQuery.builder.queryData?.[lastUsedQuery || 0]?.queryName; - const isInfraMonitoring = source === 'infra-monitoring'; + const isInfraMonitoring = source === QuickFiltersSource.INFRA_MONITORING; return (
@@ -132,7 +138,7 @@ export default function QuickFilters(props: IQuickFiltersProps): JSX.Element { return ( @@ -144,6 +150,5 @@ export default function QuickFilters(props: IQuickFiltersProps): JSX.Element { } QuickFilters.defaultProps = { - source: null, onFilterChange: null, }; diff --git a/frontend/src/container/InfraMonitoringK8s/InfraMonitoringK8s.tsx b/frontend/src/container/InfraMonitoringK8s/InfraMonitoringK8s.tsx index 2e99fdb4dda..88aad8a7f38 100644 --- a/frontend/src/container/InfraMonitoringK8s/InfraMonitoringK8s.tsx +++ b/frontend/src/container/InfraMonitoringK8s/InfraMonitoringK8s.tsx @@ -4,7 +4,9 @@ import { VerticalAlignTopOutlined } from '@ant-design/icons'; import * as Sentry from '@sentry/react'; import type { CollapseProps } from 'antd'; import { Collapse, Tooltip, Typography } from 'antd'; -import QuickFilters from 'components/QuickFilters/QuickFilters'; +import QuickFilters, { + QuickFiltersSource, +} from 'components/QuickFilters/QuickFilters'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations'; import { @@ -83,7 +85,7 @@ export default function InfraMonitoringK8s(): JSX.Element { showArrow: false, children: ( From 7805102e0f8533223d0ee0c7b9d2f6d0b5937c28 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Wed, 22 Jan 2025 11:33:07 +0430 Subject: [PATCH 07/10] refactor: update QuickFilters source to use QuickFiltersSource.INFRA_MONITORING for consistency --- .../container/InfraMonitoringK8s/InfraMonitoringK8s.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/frontend/src/container/InfraMonitoringK8s/InfraMonitoringK8s.tsx b/frontend/src/container/InfraMonitoringK8s/InfraMonitoringK8s.tsx index 88aad8a7f38..2eaee5ade31 100644 --- a/frontend/src/container/InfraMonitoringK8s/InfraMonitoringK8s.tsx +++ b/frontend/src/container/InfraMonitoringK8s/InfraMonitoringK8s.tsx @@ -128,7 +128,7 @@ export default function InfraMonitoringK8s(): JSX.Element { showArrow: false, children: ( Date: Mon, 27 Jan 2025 19:12:20 +0430 Subject: [PATCH 08/10] fix: address review comments --- .../FilterRenderers/Checkbox/Checkbox.tsx | 8 +++-- ...tate.tsx => LogsQuickFilterEmptyState.tsx} | 4 +-- .../components/QuickFilters/QuickFilters.tsx | 34 ++++++++++++------- 3 files changed, 28 insertions(+), 18 deletions(-) rename frontend/src/components/QuickFilters/FilterRenderers/Checkbox/{QuickFilterEmptyState.tsx => LogsQuickFilterEmptyState.tsx} (94%) diff --git a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx index cae5506fb6e..85b71cb4a02 100644 --- a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx +++ b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx @@ -24,11 +24,13 @@ import { Query, TagFilterItem } from 'types/api/queryBuilder/queryBuilderData'; import { DataSource } from 'types/common/queryBuilder'; import { v4 as uuid } from 'uuid'; -import QuickFilterEmptyState from './QuickFilterEmptyState'; +import LogsQuickFilterEmptyState from './LogsQuickFilterEmptyState'; const SELECTED_OPERATORS = [OPERATORS['='], 'in']; const NON_SELECTED_OPERATORS = [OPERATORS['!='], 'nin']; +const SOURCES_WITH_EMPTY_STATE_ENABLED = [QuickFiltersSource.LOGS_EXPLORER]; + function setDefaultValues( values: string[], trueOrFalse: boolean, @@ -418,7 +420,7 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element { }; const isEmptyStateWithDocsEnabled = - [QuickFiltersSource.LOGS_EXPLORER].includes(source) && + SOURCES_WITH_EMPTY_STATE_ENABLED.includes(source) && !searchText && !attributeValues.length; @@ -522,7 +524,7 @@ export default function CheckboxFilter(props: ICheckboxProps): JSX.Element { ))}
) : isEmptyStateWithDocsEnabled ? ( - + ) : (
No values found{' '} diff --git a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/QuickFilterEmptyState.tsx b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/LogsQuickFilterEmptyState.tsx similarity index 94% rename from frontend/src/components/QuickFilters/FilterRenderers/Checkbox/QuickFilterEmptyState.tsx rename to frontend/src/components/QuickFilters/FilterRenderers/Checkbox/LogsQuickFilterEmptyState.tsx index 8537eab3d9a..e1646dad285 100644 --- a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/QuickFilterEmptyState.tsx +++ b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/LogsQuickFilterEmptyState.tsx @@ -14,7 +14,7 @@ const QUICK_FILTER_DOC_PATHS: Record = { 'k8s.pod.name': 'k8s-pod-name', }; -function QuickFilterEmptyState({ +function LogsQuickFilterEmptyState({ attributeKey, }: { attributeKey: string; @@ -50,4 +50,4 @@ function QuickFilterEmptyState({ ); } -export default QuickFilterEmptyState; +export default LogsQuickFilterEmptyState; diff --git a/frontend/src/components/QuickFilters/QuickFilters.tsx b/frontend/src/components/QuickFilters/QuickFilters.tsx index 6b25d3b1916..5af3f202f3f 100644 --- a/frontend/src/components/QuickFilters/QuickFilters.tsx +++ b/frontend/src/components/QuickFilters/QuickFilters.tsx @@ -101,11 +101,9 @@ export default function QuickFilters(props: IQuickFiltersProps): JSX.Element { const lastQueryName = currentQuery.builder.queryData?.[lastUsedQuery || 0]?.queryName; - const isInfraMonitoring = source === QuickFiltersSource.INFRA_MONITORING; - return (
- {!isInfraMonitoring && ( + {source !== QuickFiltersSource.INFRA_MONITORING && (
@@ -132,17 +130,27 @@ export default function QuickFilters(props: IQuickFiltersProps): JSX.Element {
{config.map((filter) => { - if (filter.type === FiltersType.SLIDER) { - return ; + switch (filter.type) { + case FiltersType.CHECKBOX: + return ( + + ); + case FiltersType.SLIDER: + return ; + // eslint-disable-next-line sonarjs/no-duplicated-branches + default: + return ( + + ); } - return ( - - ); })}
From 949242ee7698d6a3e67449b083684cf33cae74e2 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Tue, 28 Jan 2025 17:14:38 +0430 Subject: [PATCH 09/10] refactor: fix the failing test by moving QuickFilters types to types.tsx --- .../FilterRenderers/Checkbox/Checkbox.tsx | 2 +- .../FilterRenderers/Slider/Slider.tsx | 2 +- .../components/QuickFilters/QuickFilters.tsx | 42 +------------------ frontend/src/components/QuickFilters/types.ts | 42 +++++++++++++++++++ .../container/InfraMonitoringK8s/constants.ts | 2 +- frontend/src/pages/LogsExplorer/index.tsx | 5 +-- frontend/src/pages/LogsExplorer/utils.tsx | 2 +- 7 files changed, 49 insertions(+), 48 deletions(-) create mode 100644 frontend/src/components/QuickFilters/types.ts diff --git a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx index 85b71cb4a02..1051a47c3d7 100644 --- a/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx +++ b/frontend/src/components/QuickFilters/FilterRenderers/Checkbox/Checkbox.tsx @@ -9,7 +9,7 @@ import cx from 'classnames'; import { IQuickFiltersConfig, QuickFiltersSource, -} from 'components/QuickFilters/QuickFilters'; +} from 'components/QuickFilters/types'; import { OPERATORS } from 'constants/queryBuilder'; import { DEBOUNCE_DELAY } from 'constants/queryBuilderFilterConfig'; import { getOperatorValue } from 'container/QueryBuilder/filters/QueryBuilderSearch/utils'; diff --git a/frontend/src/components/QuickFilters/FilterRenderers/Slider/Slider.tsx b/frontend/src/components/QuickFilters/FilterRenderers/Slider/Slider.tsx index f7cd9547e83..70b2fdceea7 100644 --- a/frontend/src/components/QuickFilters/FilterRenderers/Slider/Slider.tsx +++ b/frontend/src/components/QuickFilters/FilterRenderers/Slider/Slider.tsx @@ -1,6 +1,6 @@ import './Slider.styles.scss'; -import { IQuickFiltersConfig } from 'components/QuickFilters/QuickFilters'; +import { IQuickFiltersConfig } from 'components/QuickFilters/types'; interface ISliderProps { filter: IQuickFiltersConfig; diff --git a/frontend/src/components/QuickFilters/QuickFilters.tsx b/frontend/src/components/QuickFilters/QuickFilters.tsx index 5af3f202f3f..ffd7ee3a25a 100644 --- a/frontend/src/components/QuickFilters/QuickFilters.tsx +++ b/frontend/src/components/QuickFilters/QuickFilters.tsx @@ -8,51 +8,11 @@ import { import { Tooltip, Typography } from 'antd'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import { cloneDeep, isFunction } from 'lodash-es'; -import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse'; import { Query } from 'types/api/queryBuilder/queryBuilderData'; -import { DataSource } from 'types/common/queryBuilder'; import Checkbox from './FilterRenderers/Checkbox/Checkbox'; import Slider from './FilterRenderers/Slider/Slider'; - -export enum FiltersType { - SLIDER = 'SLIDER', - CHECKBOX = 'CHECKBOX', -} - -export enum MinMax { - MIN = 'MIN', - MAX = 'MAX', -} - -export enum SpecficFilterOperations { - ALL = 'ALL', - ONLY = 'ONLY', -} - -export interface IQuickFiltersConfig { - type: FiltersType; - title: string; - attributeKey: BaseAutocompleteData; - aggregateOperator?: string; - aggregateAttribute?: string; - dataSource?: DataSource; - customRendererForValue?: (value: string) => JSX.Element; - defaultOpen: boolean; -} - -export enum QuickFiltersSource { - LOGS_EXPLORER = 'logs-explorer', - INFRA_MONITORING = 'infra-monitoring', - TRACES_EXPLORER = 'traces-explorer', -} - -interface IQuickFiltersProps { - config: IQuickFiltersConfig[]; - handleFilterVisibilityChange: () => void; - source: QuickFiltersSource; - onFilterChange?: (query: Query) => void; -} +import { FiltersType, IQuickFiltersProps, QuickFiltersSource } from './types'; export default function QuickFilters(props: IQuickFiltersProps): JSX.Element { const { config, handleFilterVisibilityChange, source, onFilterChange } = props; diff --git a/frontend/src/components/QuickFilters/types.ts b/frontend/src/components/QuickFilters/types.ts new file mode 100644 index 00000000000..0d5766f862d --- /dev/null +++ b/frontend/src/components/QuickFilters/types.ts @@ -0,0 +1,42 @@ +import { BaseAutocompleteData } from 'types/api/queryBuilder/queryAutocompleteResponse'; +import { Query } from 'types/api/queryBuilder/queryBuilderData'; +import { DataSource } from 'types/common/queryBuilder'; + +export enum FiltersType { + SLIDER = 'SLIDER', + CHECKBOX = 'CHECKBOX', +} + +export enum MinMax { + MIN = 'MIN', + MAX = 'MAX', +} + +export enum SpecficFilterOperations { + ALL = 'ALL', + ONLY = 'ONLY', +} + +export interface IQuickFiltersConfig { + type: FiltersType; + title: string; + attributeKey: BaseAutocompleteData; + aggregateOperator?: string; + aggregateAttribute?: string; + dataSource?: DataSource; + customRendererForValue?: (value: string) => JSX.Element; + defaultOpen: boolean; +} + +export interface IQuickFiltersProps { + config: IQuickFiltersConfig[]; + handleFilterVisibilityChange: () => void; + source: QuickFiltersSource; + onFilterChange?: (query: Query) => void; +} + +export enum QuickFiltersSource { + LOGS_EXPLORER = 'logs-explorer', + INFRA_MONITORING = 'infra-monitoring', + TRACES_EXPLORER = 'traces-explorer', +} diff --git a/frontend/src/container/InfraMonitoringK8s/constants.ts b/frontend/src/container/InfraMonitoringK8s/constants.ts index 12e71ee844b..997daeaa777 100644 --- a/frontend/src/container/InfraMonitoringK8s/constants.ts +++ b/frontend/src/container/InfraMonitoringK8s/constants.ts @@ -2,7 +2,7 @@ import { FiltersType, IQuickFiltersConfig, -} from 'components/QuickFilters/QuickFilters'; +} from 'components/QuickFilters/types'; import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse'; import { DataSource } from 'types/common/queryBuilder'; diff --git a/frontend/src/pages/LogsExplorer/index.tsx b/frontend/src/pages/LogsExplorer/index.tsx index 2ce5ecea3a0..701b1931a8f 100644 --- a/frontend/src/pages/LogsExplorer/index.tsx +++ b/frontend/src/pages/LogsExplorer/index.tsx @@ -5,9 +5,8 @@ import getLocalStorageKey from 'api/browser/localstorage/get'; import setLocalStorageApi from 'api/browser/localstorage/set'; import cx from 'classnames'; import ExplorerCard from 'components/ExplorerCard/ExplorerCard'; -import QuickFilters, { - QuickFiltersSource, -} from 'components/QuickFilters/QuickFilters'; +import QuickFilters from 'components/QuickFilters/QuickFilters'; +import { QuickFiltersSource } from 'components/QuickFilters/types'; import { LOCALSTORAGE } from 'constants/localStorage'; import LogExplorerQuerySection from 'container/LogExplorerQuerySection'; import LogsExplorerViews from 'container/LogsExplorerViews'; diff --git a/frontend/src/pages/LogsExplorer/utils.tsx b/frontend/src/pages/LogsExplorer/utils.tsx index a886013941f..f140f495b4b 100644 --- a/frontend/src/pages/LogsExplorer/utils.tsx +++ b/frontend/src/pages/LogsExplorer/utils.tsx @@ -1,7 +1,7 @@ import { FiltersType, IQuickFiltersConfig, -} from 'components/QuickFilters/QuickFilters'; +} from 'components/QuickFilters/types'; import { DataTypes } from 'types/api/queryBuilder/queryAutocompleteResponse'; import { Query } from 'types/api/queryBuilder/queryBuilderData'; From 193c4fba7885a2da6b16469048cdd971fa3a3b95 Mon Sep 17 00:00:00 2001 From: ahmadshaheer Date: Wed, 29 Jan 2025 10:14:46 +0430 Subject: [PATCH 10/10] refactor: properly import use QuickFiltersSource --- .../InfraMonitoringK8s/InfraMonitoringK8s.tsx | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/frontend/src/container/InfraMonitoringK8s/InfraMonitoringK8s.tsx b/frontend/src/container/InfraMonitoringK8s/InfraMonitoringK8s.tsx index 2eaee5ade31..5ed5cd56336 100644 --- a/frontend/src/container/InfraMonitoringK8s/InfraMonitoringK8s.tsx +++ b/frontend/src/container/InfraMonitoringK8s/InfraMonitoringK8s.tsx @@ -4,9 +4,8 @@ import { VerticalAlignTopOutlined } from '@ant-design/icons'; import * as Sentry from '@sentry/react'; import type { CollapseProps } from 'antd'; import { Collapse, Tooltip, Typography } from 'antd'; -import QuickFilters, { - QuickFiltersSource, -} from 'components/QuickFilters/QuickFilters'; +import QuickFilters from 'components/QuickFilters/QuickFilters'; +import { QuickFiltersSource } from 'components/QuickFilters/types'; import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder'; import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations'; import { @@ -188,7 +187,7 @@ export default function InfraMonitoringK8s(): JSX.Element { showArrow: false, children: (