From 8b52b9ab225eae05ed969b648d5b66e83323df07 Mon Sep 17 00:00:00 2001 From: Praveen K B <30530587+praveen5959@users.noreply.github.com> Date: Thu, 7 Nov 2024 17:03:36 +0530 Subject: [PATCH 1/4] Saved Filters on dashboard page --- src/pages/Dashboards/CreateTileForm.tsx | 20 +++++++++-- .../components/Querier/SavedFiltersModal.tsx | 34 ++++++++++++------- src/pages/Stream/providers/FilterProvider.tsx | 10 ++++++ src/routes/elements.tsx | 4 ++- 4 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/pages/Dashboards/CreateTileForm.tsx b/src/pages/Dashboards/CreateTileForm.tsx index a77b3ea0..88434530 100644 --- a/src/pages/Dashboards/CreateTileForm.tsx +++ b/src/pages/Dashboards/CreateTileForm.tsx @@ -3,7 +3,7 @@ import classes from './styles/Form.module.css'; import { useForm } from '@mantine/form'; import { useDashboardsStore, dashboardsStoreReducers } from './providers/DashboardsProvider'; import { MutableRefObject, useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; +import { appStoreReducers, useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; import _ from 'lodash'; import { getLogStreamSchema } from '@/api/logStream'; import { Field } from '@/@types/parseable/dataType'; @@ -29,6 +29,7 @@ import TimeRange from '@/components/Header/TimeRange'; import { colors, isCircularChart, isGraph, normalizeGraphColorConfig } from './Charts'; import { usePostLLM } from '@/hooks/usePostLLM'; import { notify } from '@/utils/notification'; +import { filterStoreReducers, useFilterStore } from '../Stream/providers/FilterProvider'; const selectDashboardWarningText = 'Select a dashboard to continue'; const validateQueryWarningText = 'Validate query to continue'; @@ -37,6 +38,8 @@ const noDataWarning = 'No data available for the query'; const invalidVizConfig = 'Invalid visualization config'; const { toggleVizEditorModal, toggleCreateTileModal } = dashboardsStoreReducers; +const { toggleSavedFiltersModal } = filterStoreReducers; +const { changeStream } = appStoreReducers; const getErrorMsg = (form: TileFormType, configType: 'basic' | 'data' | 'viz'): string | null => { const { dashboardId, isQueryValidated, data, visualization } = form.values; @@ -289,14 +292,20 @@ const Query = (props: { form: TileFormType; onChangeValue: (key: string, value: const [initialHeight, setInitialHeight] = useState(0); const [dashboards] = useDashboardsStore((store) => store.dashboards); const [timeRange] = useLogsStore((store) => store.timeRange); + const [appliedFilterQuery, setLogsStore] = useFilterStore((store) => store.appliedFilterQuery); const [aiQuery, setAiQuery] = useState(''); const [userSpecificStreams] = useAppStore((store) => store.userSpecificStreams); + const [, setAppStore] = useAppStore((store) => store.maximized); const allStreams = useMemo( () => _.map(userSpecificStreams, (stream) => ({ label: stream.name, value: stream.name })), [userSpecificStreams], ); const { data: resAIQuery, postLLMQuery } = usePostLLM(); + useEffect(() => { + onEditorChange(appliedFilterQuery); + }, [appliedFilterQuery]); + const onEditorChange = useCallback((query: string | undefined) => { onChangeValue('query', query || ''); onChangeValue('isQueryValidated', false); @@ -348,10 +357,12 @@ const Query = (props: { form: TileFormType; onChangeValue: (key: string, value: }); }, [query, dashboardId, dashboards, timeRange]); - const onStreamSelect = useCallback((val: string | null) => { - setLocalStream(val || ''); + const onStreamSelect = useCallback((stream: string | null) => { + if (stream) setAppStore((store) => changeStream(store, stream)); + setLocalStream(stream || ''); }, []); + const onClick = useCallback(() => setLogsStore((store) => toggleSavedFiltersModal(store, true)), []); const isValidStream = !_.isEmpty(localStream); const handleAIGenerate = useCallback(() => { if (!aiQuery?.length) { @@ -375,6 +386,9 @@ const Query = (props: { form: TileFormType; onChangeValue: (key: string, value: key="stream" placeholder="Select Stream" /> + {errorMsg && {errorMsg}} diff --git a/src/pages/Stream/components/Querier/SavedFiltersModal.tsx b/src/pages/Stream/components/Querier/SavedFiltersModal.tsx index c06cabb7..edd63abd 100644 --- a/src/pages/Stream/components/Querier/SavedFiltersModal.tsx +++ b/src/pages/Stream/components/Querier/SavedFiltersModal.tsx @@ -13,8 +13,10 @@ import { EmptySimple } from '@/components/Empty'; import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider'; import useSavedFiltersQuery from '@/hooks/useSavedFilters'; import { generateQueryBuilderASTFromSQL } from '../../utils'; +import { useLocation } from 'react-router-dom'; -const { toggleSavedFiltersModal, resetFilters, parseQuery, applySavedFilters } = filterStoreReducers; +const { toggleSavedFiltersModal, resetFilters, parseQuery, applySavedFilters, setAppliedFilterQuery } = + filterStoreReducers; const { applyCustomQuery, updateSavedFilterId, getCleanStoreForRefetch, setTimeRange } = logsStoreReducers; const renderDeleteIcon = () => ; @@ -58,6 +60,9 @@ const SavedFilterItem = (props: { const [showDeletePropmt, setShowDeletePrompt] = useState(false); const { deleteSavedFilterMutation, isDeleting, isRefetching } = useSavedFiltersQuery(); + const location = useLocation(); + const [, setFilterStore] = useFilterStore((_store) => null); + const toggleShowQuery = useCallback(() => { return setShowQuery((prev) => !prev); }, []); @@ -78,22 +83,27 @@ const SavedFilterItem = (props: { }, [time_filter, isStoredAndCurrentTimeRangeAreSame, hardRefresh, changeTimerange]); const onApplyFilters = useCallback(() => { - if (query.filter_query) { - if (query.filter_type === 'sql') { - props.onSqlSearchApply(query.filter_query, filter_id, time_filter); - } else { + if (location.pathname.includes('dashboard')) { + setFilterStore((store) => setAppliedFilterQuery(store, query.filter_query)); + setFilterStore((store) => toggleSavedFiltersModal(store, false)); + } else { + if (query.filter_query) { + if (query.filter_type === 'sql') { + props.onSqlSearchApply(query.filter_query, filter_id, time_filter); + } else { + if (filter_id !== savedFilterId) { + props.onFilterBuilderQueryApply(generateQueryBuilderASTFromSQL(query.filter_query), filter_id); + } else { + handleTimeFilter(); + } + } + } else if (query.filter_builder) { if (filter_id !== savedFilterId) { - props.onFilterBuilderQueryApply(generateQueryBuilderASTFromSQL(query.filter_query), filter_id); + props.onFilterBuilderQueryApply(query.filter_builder, filter_id); } else { handleTimeFilter(); } } - } else if (query.filter_builder) { - if (filter_id !== savedFilterId) { - props.onFilterBuilderQueryApply(query.filter_builder, filter_id); - } else { - handleTimeFilter(); - } } }, [savedFilterId, isStoredAndCurrentTimeRangeAreSame, hardRefresh, changeTimerange]); diff --git a/src/pages/Stream/providers/FilterProvider.tsx b/src/pages/Stream/providers/FilterProvider.tsx index f5eb1df3..4f44cfdb 100644 --- a/src/pages/Stream/providers/FilterProvider.tsx +++ b/src/pages/Stream/providers/FilterProvider.tsx @@ -65,6 +65,7 @@ type UpdateRuleType = { type FilterStore = { fields: Field[]; query: QueryType; + appliedFilterQuery: string; fieldTypeMap: FieldTypeMap; fieldNames: string[]; isSumbitDisabled: boolean; @@ -88,6 +89,7 @@ const defaultQuery = { const initialState: FilterStore = { fields: [], query: defaultQuery, + appliedFilterQuery: '', fieldTypeMap: {}, fieldNames: [], isSumbitDisabled: true, @@ -139,6 +141,7 @@ type FilterStoreReducers = { toggleSaveFiltersModal: (_store: FilterStore, val: boolean) => ReducerOutput; toggleSavedFiltersModal: (_store: FilterStore, val: boolean) => ReducerOutput; applySavedFilters: (store: FilterStore, query: QueryType) => ReducerOutput; + setAppliedFilterQuery: (store: FilterStore, query: string | undefined) => ReducerOutput; }; const { Provider: FilterProvider, useStore: useFilterStore } = initContext(initialState); @@ -234,6 +237,12 @@ const updateParentCombinator = (store: FilterStore, combinator: Combinator) => { return { query: { ...query, combinator: combinator } }; }; +const setAppliedFilterQuery = (_store: FilterStore, query: string | undefined) => { + return { + appliedFilterQuery: query, + }; +}; + export const noValueOperators = ['null', 'notNull']; const toggleSubmitBtn = (_store: FilterStore, val: boolean) => { @@ -354,6 +363,7 @@ const filterStoreReducers: FilterStoreReducers = { toggleSaveFiltersModal, toggleSavedFiltersModal, applySavedFilters, + setAppliedFilterQuery, }; export { FilterProvider, useFilterStore, filterStoreReducers }; diff --git a/src/routes/elements.tsx b/src/routes/elements.tsx index 573281bb..57101afd 100644 --- a/src/routes/elements.tsx +++ b/src/routes/elements.tsx @@ -24,7 +24,9 @@ export const DashboardsElement: FC = () => { - + + + From cefd979fdd2da2a8c495c69cf3ecc0fbbac363a8 Mon Sep 17 00:00:00 2001 From: praveen5959 Date: Thu, 7 Nov 2024 17:05:56 +0530 Subject: [PATCH 2/4] Saved filter modal added --- src/pages/Dashboards/index.tsx | 46 ++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/src/pages/Dashboards/index.tsx b/src/pages/Dashboards/index.tsx index d9304fa5..07c497d6 100644 --- a/src/pages/Dashboards/index.tsx +++ b/src/pages/Dashboards/index.tsx @@ -12,6 +12,7 @@ import { useSyncTimeRange } from './hooks'; import _ from 'lodash'; import useParamsController from './hooks/useParamsController'; import { useDocumentTitle } from '@mantine/hooks'; +import SavedFiltersModal from '../Stream/components/Querier/SavedFiltersModal'; const LoadingView = () => { return ( @@ -35,27 +36,30 @@ const Dashboards = () => { }, [isStoreSynced]); return ( - - {dashboards === null || !isStoreSynced ? ( - - ) : createTileFormOpen ? ( - - ) : ( - <> - - - - - )} - + <> + + + {dashboards === null || !isStoreSynced ? ( + + ) : createTileFormOpen ? ( + + ) : ( + <> + + + + + )} + + ); }; From 7bb6536c3163d72a91fb68e762c5a23a9914752a Mon Sep 17 00:00:00 2001 From: praveen5959 Date: Thu, 7 Nov 2024 22:30:16 +0530 Subject: [PATCH 3/4] Clear appliedFilterQuery when stream changes --- src/pages/Dashboards/CreateTileForm.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/pages/Dashboards/CreateTileForm.tsx b/src/pages/Dashboards/CreateTileForm.tsx index 88434530..e264694c 100644 --- a/src/pages/Dashboards/CreateTileForm.tsx +++ b/src/pages/Dashboards/CreateTileForm.tsx @@ -38,7 +38,7 @@ const noDataWarning = 'No data available for the query'; const invalidVizConfig = 'Invalid visualization config'; const { toggleVizEditorModal, toggleCreateTileModal } = dashboardsStoreReducers; -const { toggleSavedFiltersModal } = filterStoreReducers; +const { toggleSavedFiltersModal, setAppliedFilterQuery } = filterStoreReducers; const { changeStream } = appStoreReducers; const getErrorMsg = (form: TileFormType, configType: 'basic' | 'data' | 'viz'): string | null => { @@ -358,7 +358,10 @@ const Query = (props: { form: TileFormType; onChangeValue: (key: string, value: }, [query, dashboardId, dashboards, timeRange]); const onStreamSelect = useCallback((stream: string | null) => { - if (stream) setAppStore((store) => changeStream(store, stream)); + if (stream) { + setAppStore((store) => changeStream(store, stream)); + setLogsStore((store) => setAppliedFilterQuery(store, '')); + } setLocalStream(stream || ''); }, []); From 184bb62709426814961b8c78f823d42b483b7276 Mon Sep 17 00:00:00 2001 From: Praveen K B Date: Tue, 12 Nov 2024 11:52:09 +0530 Subject: [PATCH 4/4] Handle undefined case for appliedFilterQuery in setAppliedFilterQuery function --- src/pages/Stream/providers/FilterProvider.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/Stream/providers/FilterProvider.tsx b/src/pages/Stream/providers/FilterProvider.tsx index 4f44cfdb..c44c1b8a 100644 --- a/src/pages/Stream/providers/FilterProvider.tsx +++ b/src/pages/Stream/providers/FilterProvider.tsx @@ -239,7 +239,8 @@ const updateParentCombinator = (store: FilterStore, combinator: Combinator) => { const setAppliedFilterQuery = (_store: FilterStore, query: string | undefined) => { return { - appliedFilterQuery: query, + ..._store, + appliedFilterQuery: query ?? '', }; };