Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correlation CRUD operations #417

Merged
merged 93 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
24bb27f
Correlation route and page setup
Nov 8, 2024
fdd6389
Added logTable toolbar
praveen5959 Nov 13, 2024
66b8237
Added sidebar and collapsable config
praveen5959 Nov 13, 2024
f37f28c
Added sidebar and collapsable config
praveen5959 Nov 13, 2024
544b400
Added new UX few items
praveen5959 Nov 14, 2024
baf8901
Added new desing flow for correlation
praveen5959 Nov 14, 2024
84ccdb8
correlation
praveen5959 Nov 15, 2024
edc3b90
Created Correlation store and new UX changes
praveen5959 Nov 19, 2024
c532cf2
Created Correlation store and new UX changes
praveen5959 Nov 19, 2024
ea155f3
Merge pull request #3 from praveen5959/main
praveen5959 Nov 19, 2024
71637c3
Moved useCorrelationQueryLogs to react-query
praveen5959 Nov 19, 2024
aae5b1e
A seperate hook for schema call
praveen5959 Nov 20, 2024
85a7254
Added stream-prefix
praveen5959 Nov 21, 2024
c4688e8
Moved to two stream approach
praveen5959 Nov 22, 2024
9a6eef3
Added correltation query logic
praveen5959 Dec 3, 2024
2a90341
Moved Querier to new component
praveen5959 Dec 4, 2024
c63df2a
fix: Add or update OFFSET clause in query (#376)
praveen5959 Nov 27, 2024
d8ffd31
fix: handle null userRoles in stream metadata fetching logic (#383)
praveen5959 Nov 27, 2024
b63380f
feat: improve UX and DX in delete and reset modals (#382)
pranavgoel29 Nov 28, 2024
721da8a
Moved Querier to new component
praveen5959 Dec 4, 2024
3c2dc2c
Added event lint graph to correlation
praveen5959 Dec 5, 2024
313e5a0
Added multi line graph to events
praveen5959 Dec 6, 2024
d650324
feat: collapsible explore page sidebar. (#378)
praveen5959 Dec 6, 2024
5cba882
feat: move timeRange to AppStore (#384)
praveen5959 Dec 6, 2024
9328b52
Rebased
praveen5959 Dec 6, 2024
38b876b
Rebased
praveen5959 Dec 6, 2024
bb53abd
Moved Querier to new component
praveen5959 Dec 4, 2024
10b3e76
Rebased to main
praveen5959 Dec 6, 2024
bfa07c1
Fixed extra schema call issue
praveen5959 Dec 8, 2024
4f6205c
Fixed the Event Graph queries
praveen5959 Dec 10, 2024
a98e889
Fixed the SQL query with alias
praveen5959 Dec 11, 2024
1f6d3ab
UI CHanges
praveen5959 Dec 19, 2024
3bcb3f4
Fixed SQL query
praveen5959 Dec 19, 2024
cddf346
Added Legend color to ChartTooltip
praveen5959 Dec 19, 2024
9ee3269
Fixed the EventGraph issue
praveen5959 Dec 19, 2024
827b26a
Fixed FieldItem Width issue
praveen5959 Dec 19, 2024
df67dec
Added loaders and removed dead code
praveen5959 Dec 20, 2024
202b024
Handled delete stream row bug
praveen5959 Dec 20, 2024
eb233e4
Resolved merge conflicts
praveen5959 Dec 20, 2024
5c98cb1
Added new CorrelationICon for navbar
praveen5959 Dec 20, 2024
751ae35
Added stepper for placeholder
praveen5959 Dec 20, 2024
4f3ec2a
Resolved lint issues
praveen5959 Dec 20, 2024
b5497ee
Fixed the after correltaion col addition bug
praveen5959 Dec 21, 2024
177431a
Fixed the deep nest warning in Log Table
praveen5959 Dec 21, 2024
f676bb0
Fixed the timeRange and other data view issues
praveen5959 Dec 23, 2024
6ece5d5
Fixed the pagination issues
praveen5959 Dec 24, 2024
bf5f3a7
Added loading state on schema call
praveen5959 Dec 24, 2024
01657d3
Merge branch 'main' of https://github.com/praveen5959/console into co…
praveen5959 Dec 24, 2024
2d5d674
Refactored CorrelationProvider
praveen5959 Dec 26, 2024
cba8817
Moved FieldItem to seperate component
praveen5959 Dec 26, 2024
bc44b05
Removed lodash dep from Correlation index.tsx
praveen5959 Dec 26, 2024
85a7fc1
Merge branch 'main' of https://github.com/praveen5959/console into co…
praveen5959 Dec 26, 2024
4dd31d3
Added Tooltips to the field item
praveen5959 Dec 26, 2024
7f19d6d
Big fixes reagarding delete field & Joins
praveen5959 Dec 26, 2024
a994d64
Fixed the scroll area CSS
praveen5959 Dec 26, 2024
5f42766
FIxed Empty rows case and loading states
praveen5959 Dec 26, 2024
06e61b0
Merge branch 'main' of https://github.com/praveen5959/console into co…
praveen5959 Dec 26, 2024
05fc7a0
fix: Pagination pageData
praveen5959 Dec 31, 2024
137f95f
fix: Totalpages count on pagination fixed
praveen5959 Jan 1, 2025
c2e4ebb
Bug fixes (timeRange page count, Share Btn)
praveen5959 Jan 6, 2025
f9f3a5e
Merge branch 'main' of https://github.com/praveen5959/console into co…
praveen5959 Jan 6, 2025
ae25fc2
Added URL params
praveen5959 Jan 6, 2025
961ac61
CRUD operations of correlations
praveen5959 Jan 10, 2025
2bce8ae
Removed unused files
praveen5959 Jan 10, 2025
801ce01
Removed empty file
praveen5959 Jan 10, 2025
006298b
Resolved merge conflicts
praveen5959 Jan 10, 2025
28a4351
Removed QueryEngine Logic
praveen5959 Jan 10, 2025
e2ff453
Improved the CorelationIcon logic
praveen5959 Jan 10, 2025
a5c4777
Resolved conflicts
praveen5959 Jan 10, 2025
32ef792
Rebased with base branch
praveen5959 Jan 10, 2025
d7d4a05
Added placeholder txt for query
praveen5959 Jan 10, 2025
a5572f9
Add streamData in store as per streamName in response
praveen5959 Jan 12, 2025
35e8a88
fix: Correlate button disable states fixed
praveen5959 Jan 12, 2025
667f685
Removed logs
praveen5959 Jan 12, 2025
55eb994
Resolved conflicts
praveen5959 Jan 13, 2025
52064f3
Update saved correlations fix
praveen5959 Jan 13, 2025
12da404
Merge branch 'main' of https://github.com/praveen5959/console into co…
praveen5959 Jan 13, 2025
e90643e
Merge branch 'correlation' of https://github.com/praveen5959/console …
praveen5959 Jan 13, 2025
0aedb67
Bug fixes
praveen5959 Jan 13, 2025
4ce85b9
fix: Correlate btn and explore page changes
praveen5959 Jan 13, 2025
d592b75
Merge branch 'correlation' of https://github.com/praveen5959/console …
praveen5959 Jan 13, 2025
118b11f
Resolved merge conflicts
praveen5959 Jan 13, 2025
5b57f6c
Lint fixes
praveen5959 Jan 13, 2025
c4af613
Merge branch 'correlation' of https://github.com/praveen5959/console …
praveen5959 Jan 14, 2025
f9e6098
Added update correlation logic
praveen5959 Jan 14, 2025
b6d229b
Merge branch 'main' into correlation-save
praveen5959 Jan 14, 2025
447cd5d
fix: Graph call fixes
praveen5959 Jan 15, 2025
c467bfe
fix: FIxed Update correlation btn text
praveen5959 Jan 16, 2025
5d167c1
Merge branch 'main' of https://github.com/praveen5959/console into co…
praveen5959 Jan 17, 2025
d055f68
fix: Graph fixes and other bug fixes
praveen5959 Jan 17, 2025
433f753
fix: Removed v1 text from correlation APIs
praveen5959 Jan 17, 2025
ca41faa
fix: Styles of join and table configs chagned
praveen5959 Jan 17, 2025
949ecae
fix: Changed /counts api response key names
praveen5959 Jan 17, 2025
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
18 changes: 18 additions & 0 deletions src/@types/parseable/api/correlation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export type Correlation = {
version: string;
id: string;
title: string;
tableConfigs: Array<{
selectedFields: string[];
tableName: string;
}>;
joinConfig: {
joinConditions: Array<{
tableName: string;
field: string;
}>;
};
filter: null;
startTime: string;
endTime: string;
};
4 changes: 4 additions & 0 deletions src/api/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export const LOG_QUERY_URL = (params?: Params, resourcePath = 'query') =>
export const LOG_STREAMS_ALERTS_URL = (streamName: string) => `${LOG_STREAM_LIST_URL}/${streamName}/alert`;
export const LIST_SAVED_FILTERS_URL = `${API_V1}/filters`;
export const LIST_DASHBOARDS = `${API_V1}/dashboards`;
export const LIST_CORRELATIONS = `${API_V1}/correlation`;
export const UPDATE_CORRELATION_URL = (correlationId: string) => `${API_V1}/correlation/${correlationId}`;
export const DELETE_SAVED_CORRELATION_URL = (correlationId: string) => `${API_V1}/correlation/${correlationId}`;
export const GET_SAVED_CORRELATION_URL = (correlationId: string) => `${API_V1}/correlation/${correlationId}`;
export const UPDATE_SAVED_FILTERS_URL = (filterId: string) => `${API_V1}/filters/${filterId}`;
export const UPDATE_DASHBOARDS_URL = (dashboardId: string) => `${API_V1}/dashboards/${dashboardId}`;
export const DELETE_DASHBOARDS_URL = (dashboardId: string) => `${API_V1}/dashboards/${dashboardId}`;
Expand Down
28 changes: 28 additions & 0 deletions src/api/correlations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Correlation } from '@/@types/parseable/api/correlation';
import { Axios } from './axios';
import {
DELETE_SAVED_CORRELATION_URL,
GET_SAVED_CORRELATION_URL,
LIST_CORRELATIONS,
UPDATE_CORRELATION_URL,
} from './constants';

export const getCorrelations = () => {
return Axios().get<Correlation[]>(LIST_CORRELATIONS);
};

export const getCorrelationById = (correlationId: string) => {
return Axios().get(GET_SAVED_CORRELATION_URL(correlationId));
};

export const deleteSavedCorrelation = (correlationId: string) => {
return Axios().delete(DELETE_SAVED_CORRELATION_URL(correlationId));
};

export const saveCorrelation = (correlationData: Correlation) => {
return Axios().post(LIST_CORRELATIONS, correlationData);
};

export const updateCorrelation = (correlationData: Correlation) => {
return Axios().put(UPDATE_CORRELATION_URL(correlationData.id), correlationData);
};
5 changes: 2 additions & 3 deletions src/hooks/useCorrelationQueryLogs.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { getCorrelationQueryLogsWithHeaders } from '@/api/query';
import { StatusCodes } from 'http-status-codes';
import useMountedState from './useMountedState';
import { useAppStore } from '@/layouts/MainLayout/providers/AppProvider';
import _ from 'lodash';
Expand Down Expand Up @@ -55,9 +54,9 @@ export const useCorrelationQueryLogs = () => {
enabled: false,
refetchOnWindowFocus: false,
onSuccess: async (responses) => {
responses.map((data: { data: LogsResponseWithHeaders; status: StatusCodes }) => {
responses.map((data: { data: LogsResponseWithHeaders }) => {
const logs = data.data;
const isInvalidResponse = _.isEmpty(logs) || _.isNil(logs) || data.status !== StatusCodes.OK;
const isInvalidResponse = _.isEmpty(logs) || _.isNil(logs);
if (isInvalidResponse) return setError('Failed to query logs');

const { records, fields } = logs;
Expand Down
157 changes: 157 additions & 0 deletions src/hooks/useCorrelations.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import { useMutation, useQuery } from 'react-query';
import _ from 'lodash';

import {
deleteSavedCorrelation,
getCorrelationById,
getCorrelations,
saveCorrelation,
updateCorrelation,
} from '@/api/correlations';
import { correlationStoreReducers, useCorrelationStore } from '@/pages/Correlation/providers/CorrelationProvider';
import { notifyError, notifySuccess } from '@/utils/notification';
import { AxiosError, isAxiosError } from 'axios';
import { appStoreReducers, useAppStore } from '@/layouts/MainLayout/providers/AppProvider';
import dayjs from 'dayjs';

const {
setCorrelations,
setActiveCorrelation,
setCorrelationId,
setSavedCorrelationId,
cleanCorrelationStore,
toggleSavedCorrelationsModal,
} = correlationStoreReducers;
const { setTimeRange, syncTimeRange } = appStoreReducers;
export const useCorrelationsQuery = () => {
const [{ correlationId }, setCorrelatedStore] = useCorrelationStore((store) => store);
const [, setAppStore] = useAppStore((store) => store);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

instead of returning the entire store u can return nil which will still return the setAppStore reducer

const {
isError: fetchCorrelationsError,
isSuccess: fetchCorrelationsSuccess,
isLoading: fetchCorrelationsLoading,
refetch: fetchCorrelations,
} = useQuery(['correlations'], () => getCorrelations(), {
retry: false,
enabled: false,
refetchOnWindowFocus: false,
onSuccess: (data) => {
setCorrelatedStore((store) => setCorrelations(store, data.data || []));
},
onError: () => {
setCorrelatedStore((store) => setCorrelations(store, []));
notifyError({ message: 'Failed to fetch correlations' });
},
});

const {
mutate: getCorrelationByIdMutation,
isError: fetchCorrelationIdError,
isSuccess: fetchCorrelationIdSuccess,
isLoading: fetchCorrelationIdLoading,
} = useMutation((correlationId: string) => getCorrelationById(correlationId), {
onSuccess: (data: any) => {
data.data.startTime &&
data.data.endTime &&
setAppStore((store) =>
setTimeRange(store, {
startTime: dayjs(data.data.startTime),
endTime: dayjs(data.data.endTime),
type: 'custom',
}),
);
setCorrelatedStore((store) => setCorrelationId(store, data.data.id));
setCorrelatedStore((store) => setActiveCorrelation(store, data.data));
},
onError: () => {
notifyError({ message: 'Failed to fetch correlation' });
},
});

const { mutate: deleteSavedCorrelationMutation, isLoading: isDeleting } = useMutation(
(data: { correlationId: string; onSuccess?: () => void }) => deleteSavedCorrelation(data.correlationId),
{
onSuccess: (_data, variables) => {
variables.onSuccess && variables.onSuccess();
if (variables.correlationId === correlationId) {
setCorrelatedStore(cleanCorrelationStore);
setAppStore(syncTimeRange);
}
fetchCorrelations();
setCorrelatedStore((store) => toggleSavedCorrelationsModal(store, false));
notifySuccess({ message: 'Deleted Successfully' });
},
onError: (data: AxiosError) => {
if (isAxiosError(data) && data.response) {
const error = data.response?.data as string;
typeof error === 'string' && notifyError({ message: error });
} else if (data.message && typeof data.message === 'string') {
notifyError({ message: data.message });
}
},
},
);

const { mutate: saveCorrelationMutation, isLoading: isCorrelationSaving } = useMutation(
(data: { correlationData: any; onSuccess?: () => void }) => saveCorrelation(data.correlationData),
{
onSuccess: (data, variables) => {
variables.onSuccess && variables.onSuccess();
setCorrelatedStore((store) => setCorrelationId(store, data.data.id));
setCorrelatedStore((store) => setSavedCorrelationId(store, data.data.id));
fetchCorrelations();
notifySuccess({ message: 'Correlation saved successfully' });
},
onError: (data: AxiosError) => {
if (isAxiosError(data) && data.response) {
const error = data.response?.data as string;
typeof error === 'string' && notifyError({ message: error });
} else if (data.message && typeof data.message === 'string') {
notifyError({ message: data.message });
}
},
},
);

const { mutate: updateCorrelationMutation, isLoading: isCorrelationUpdating } = useMutation(
(data: { correlationData: any; onSuccess?: () => void }) => updateCorrelation(data.correlationData),
{
onSuccess: (data, variables) => {
variables.onSuccess && variables.onSuccess();
setCorrelatedStore((store) => setCorrelationId(store, data.data.id));
setCorrelatedStore((store) => setActiveCorrelation(store, data.data));
fetchCorrelations();
notifySuccess({ message: 'Correlation updated successfully' });
},
onError: (data: AxiosError) => {
if (isAxiosError(data) && data.response) {
const error = data.response?.data as string;
typeof error === 'string' && notifyError({ message: error });
} else if (data.message && typeof data.message === 'string') {
notifyError({ message: data.message });
}
},
},
);

return {
fetchCorrelationsError,
fetchCorrelationsSuccess,
fetchCorrelationsLoading,
fetchCorrelations,

deleteSavedCorrelationMutation,
isDeleting,

fetchCorrelationIdError,
fetchCorrelationIdSuccess,
fetchCorrelationIdLoading,
getCorrelationByIdMutation,

saveCorrelationMutation,
isCorrelationSaving,

updateCorrelationMutation,
isCorrelationUpdating,
};
};
17 changes: 9 additions & 8 deletions src/hooks/useFetchStreamData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
} from '@/pages/Correlation/providers/CorrelationProvider';
import { notifyError } from '@/utils/notification';
import { useQuery } from 'react-query';
import { LogsResponseWithHeaders } from '@/@types/parseable/api/query';
import { useRef, useEffect } from 'react';

const { setStreamData } = correlationStoreReducers;
Expand All @@ -23,7 +22,6 @@ export const useFetchStreamData = () => {
(store) => store,
);
const [streamInfo] = useStreamStore((store) => store.info);
const [currentStream] = useAppStore((store) => store.currentStream);
const timePartitionColumn = _.get(streamInfo, 'time_partition', 'p_timestamp');
const [timeRange] = useAppStore((store) => store.timeRange);
const [
Expand Down Expand Up @@ -66,26 +64,29 @@ export const useFetchStreamData = () => {

const fetchPromises = streamsToFetch.map((streamName) => {
const queryOpts = { ...defaultQueryOpts, streamNames: [streamName] };
return getStreamDataWithHeaders(queryOpts);
return getStreamDataWithHeaders(queryOpts).then((data) => ({ streamName, data }));
});
return Promise.all(fetchPromises);
},
{
enabled: false,
refetchOnWindowFocus: false,
onSuccess: async (responses) => {
responses.map((data: { data: LogsResponseWithHeaders; status: StatusCodes }) => {
responses.forEach(({ streamName, data }) => {
const logs = data.data;
const isInvalidResponse = _.isEmpty(logs) || _.isNil(logs) || data.status !== StatusCodes.OK;
if (isInvalidResponse) return setError('Failed to query logs');
if (isInvalidResponse) {
setError('Failed to query logs');
return;
}

const { records, fields } = logs;
if (fields.length > 0 && !correlationCondition) {
return setCorrelationStore((store) => setStreamData(store, currentStream || '', records));
setCorrelationStore((store) => setStreamData(store, streamName, records));
} else if (fields.length > 0 && correlationCondition) {
return setCorrelationStore((store) => setStreamData(store, 'correlatedStream', records));
setCorrelationStore((store) => setStreamData(store, 'correlatedStream', records));
} else {
notifyError({ message: `${currentStream} doesn't have any fields` });
notifyError({ message: `${streamName} doesn't have any fields` });
}
});
},
Expand Down
45 changes: 44 additions & 1 deletion src/hooks/useGetCorrelationStreamSchema.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getLogStreamSchema } from '@/api/logStream';
import { AxiosError, isAxiosError } from 'axios';
import _ from 'lodash';
import { useQuery } from 'react-query';
import { useQueries, useQuery } from 'react-query';
import { useState } from 'react';
import { correlationStoreReducers, useCorrelationStore } from '@/pages/Correlation/providers/CorrelationProvider';

Expand Down Expand Up @@ -43,3 +43,46 @@ export const useGetStreamSchema = (opts: { streamName: string }) => {
isRefetching,
};
};

// Multiple stream schemas hook
export const useGetMultipleStreamSchemas = (streams: string[]) => {
const [, setCorrelationStore] = useCorrelationStore((_store) => null);
const [errors, setErrors] = useState<Record<string, string>>({});

const queries = useQueries(
streams.map((streamName) => ({
queryKey: ['stream-schema', streamName],
queryFn: () => getLogStreamSchema(streamName),
retry: false,
enabled: streamName !== '' && streamName !== 'correlatedStream',
refetchOnWindowFocus: false,
onSuccess: (data: any) => {
setErrors((prev) => _.omit(prev, streamName));
setCorrelationStore((store) => setStreamSchema(store, data.data, streamName));
},
onError: (error: AxiosError) => {
let errorMessage = 'An unknown error occurred';
if (isAxiosError(error) && error.response?.data) {
errorMessage = typeof error.response.data === 'string' ? error.response.data : error.message;
}
setErrors((prev) => ({
...prev,
[streamName]: errorMessage,
}));
},
})),
);

const isLoading = queries.some((query) => query.isLoading);
const isError = queries.some((query) => query.isError);
const isSuccess = queries.every((query) => query.isSuccess);
const isRefetching = queries.some((query) => query.isRefetching);

return {
isLoading,
isError,
isSuccess,
isRefetching,
errors,
};
};
Loading
Loading