mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-12 10:09:02 +08:00
feat: added url sharing for main domain list page api monitoring
This commit is contained in:
parent
a41ffceca4
commit
e125d146b5
@ -7,16 +7,22 @@ import logEvent from 'api/common/logEvent';
|
|||||||
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
|
import { initialQueriesMap } from 'constants/queryBuilder';
|
||||||
import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
|
import { REACT_QUERY_KEY } from 'constants/reactQueryKeys';
|
||||||
|
import RightToolbarActions from 'container/QueryBuilder/components/ToolbarActions/RightToolbarActions';
|
||||||
import QueryBuilderSearchV2 from 'container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2';
|
import QueryBuilderSearchV2 from 'container/QueryBuilder/filters/QueryBuilderSearchV2/QueryBuilderSearchV2';
|
||||||
import DateTimeSelectionV2 from 'container/TopNav/DateTimeSelectionV2';
|
import Toolbar from 'container/Toolbar/Toolbar';
|
||||||
import { useMemo, useState } from 'react';
|
import { useGetCompositeQueryParam } from 'hooks/queryBuilder/useGetCompositeQueryParam';
|
||||||
|
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
||||||
|
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
|
||||||
|
import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl';
|
||||||
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
import { useQuery } from 'react-query';
|
import { useQuery } from 'react-query';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { AppState } from 'store/reducers';
|
import { AppState } from 'store/reducers';
|
||||||
import { ErrorResponse, SuccessResponse } from 'types/api';
|
import { ErrorResponse, SuccessResponse } from 'types/api';
|
||||||
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
import { IBuilderQuery } from 'types/api/queryBuilder/queryBuilderData';
|
||||||
import { HandleChangeQueryData } from 'types/common/operations.types';
|
import { DataSource } from 'types/common/queryBuilder';
|
||||||
import { GlobalReducer } from 'types/reducer/globalTime';
|
import { GlobalReducer } from 'types/reducer/globalTime';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -26,20 +32,49 @@ import {
|
|||||||
} from '../../utils';
|
} from '../../utils';
|
||||||
import DomainDetails from './DomainDetails/DomainDetails';
|
import DomainDetails from './DomainDetails/DomainDetails';
|
||||||
|
|
||||||
function DomainList({
|
function DomainList({ showIP }: { showIP: boolean }): JSX.Element {
|
||||||
query,
|
|
||||||
showIP,
|
|
||||||
handleChangeQueryData,
|
|
||||||
}: {
|
|
||||||
query: IBuilderQuery;
|
|
||||||
showIP: boolean;
|
|
||||||
handleChangeQueryData: HandleChangeQueryData;
|
|
||||||
}): JSX.Element {
|
|
||||||
const [selectedDomainIndex, setSelectedDomainIndex] = useState<number>(-1);
|
const [selectedDomainIndex, setSelectedDomainIndex] = useState<number>(-1);
|
||||||
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
const { maxTime, minTime } = useSelector<AppState, GlobalReducer>(
|
||||||
(state) => state.globalTime,
|
(state) => state.globalTime,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { currentQuery, handleRunQuery } = useQueryBuilder();
|
||||||
|
const query = currentQuery?.builder?.queryData[0] || null;
|
||||||
|
|
||||||
|
const { handleChangeQueryData } = useQueryOperations({
|
||||||
|
index: 0,
|
||||||
|
query,
|
||||||
|
entityVersion: '',
|
||||||
|
});
|
||||||
|
|
||||||
|
// initialise tab with default query.
|
||||||
|
useShareBuilderUrl({
|
||||||
|
...initialQueriesMap.traces,
|
||||||
|
builder: {
|
||||||
|
...initialQueriesMap.traces.builder,
|
||||||
|
queryData: [
|
||||||
|
{
|
||||||
|
...initialQueriesMap.traces.builder.queryData[0],
|
||||||
|
dataSource: DataSource.TRACES,
|
||||||
|
aggregateOperator: 'noop',
|
||||||
|
aggregateAttribute: {
|
||||||
|
...initialQueriesMap.traces.builder.queryData[0].aggregateAttribute,
|
||||||
|
},
|
||||||
|
queryName: '',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const compositeData = useGetCompositeQueryParam();
|
||||||
|
|
||||||
|
const handleChangeTagFilters = useCallback(
|
||||||
|
(value: IBuilderQuery['filters']) => {
|
||||||
|
handleChangeQueryData('filters', value);
|
||||||
|
},
|
||||||
|
[handleChangeQueryData],
|
||||||
|
);
|
||||||
|
|
||||||
const fetchApiOverview = async (): Promise<
|
const fetchApiOverview = async (): Promise<
|
||||||
SuccessResponse<any> | ErrorResponse
|
SuccessResponse<any> | ErrorResponse
|
||||||
> => {
|
> => {
|
||||||
@ -70,7 +105,7 @@ function DomainList({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const { data, isLoading, isFetching } = useQuery(
|
const { data, isLoading, isFetching } = useQuery(
|
||||||
[REACT_QUERY_KEY.GET_DOMAINS_LIST, minTime, maxTime, query, showIP],
|
[REACT_QUERY_KEY.GET_DOMAINS_LIST, minTime, maxTime, compositeData, showIP],
|
||||||
fetchApiOverview,
|
fetchApiOverview,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -81,20 +116,18 @@ function DomainList({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<section className={cx('api-module-right-section')}>
|
<section className={cx('api-module-right-section')}>
|
||||||
|
<Toolbar
|
||||||
|
showAutoRefresh={false}
|
||||||
|
rightActions={<RightToolbarActions onStageRunQuery={handleRunQuery} />}
|
||||||
|
/>
|
||||||
|
{/* add bottom border here */}
|
||||||
<div className={cx('api-monitoring-list-header')}>
|
<div className={cx('api-monitoring-list-header')}>
|
||||||
<QueryBuilderSearchV2
|
<QueryBuilderSearchV2
|
||||||
query={query}
|
query={query}
|
||||||
onChange={(searchFilters): void =>
|
onChange={handleChangeTagFilters}
|
||||||
handleChangeQueryData('filters', searchFilters)
|
|
||||||
}
|
|
||||||
placeholder="Search filters..."
|
placeholder="Search filters..."
|
||||||
hardcodedAttributeKeys={hardcodedAttributeKeys}
|
hardcodedAttributeKeys={hardcodedAttributeKeys}
|
||||||
/>
|
/>
|
||||||
<DateTimeSelectionV2
|
|
||||||
showAutoRefresh={false}
|
|
||||||
showRefreshText={false}
|
|
||||||
hideShareModal
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<Table
|
<Table
|
||||||
className={cx('api-monitoring-domain-list-table')}
|
className={cx('api-monitoring-domain-list-table')}
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
.api-quick-filters-header {
|
.api-quick-filters-header {
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
border-bottom: 1px solid var(--bg-slate-400);
|
border-bottom: 1px solid var(--bg-slate-400);
|
||||||
|
border-right: 1px solid var(--bg-slate-400);
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -24,6 +25,10 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
|
.toolbar {
|
||||||
|
border-bottom: 1px solid var(--bg-slate-400);
|
||||||
|
}
|
||||||
|
|
||||||
.api-monitoring-list-header {
|
.api-monitoring-list-header {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
|
@ -7,12 +7,8 @@ import logEvent from 'api/common/logEvent';
|
|||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
import QuickFilters from 'components/QuickFilters/QuickFilters';
|
import QuickFilters from 'components/QuickFilters/QuickFilters';
|
||||||
import { QuickFiltersSource } from 'components/QuickFilters/types';
|
import { QuickFiltersSource } from 'components/QuickFilters/types';
|
||||||
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
|
|
||||||
import { useQueryOperations } from 'hooks/queryBuilder/useQueryBuilderOperations';
|
|
||||||
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
import ErrorBoundaryFallback from 'pages/ErrorBoundaryFallback/ErrorBoundaryFallback';
|
||||||
import { useEffect, useMemo, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { Query } from 'types/api/queryBuilder/queryBuilderData';
|
|
||||||
import { DataSource } from 'types/common/queryBuilder';
|
|
||||||
|
|
||||||
import { ApiMonitoringQuickFiltersConfig } from '../utils';
|
import { ApiMonitoringQuickFiltersConfig } from '../utils';
|
||||||
import DomainList from './Domains/DomainList';
|
import DomainList from './Domains/DomainList';
|
||||||
@ -20,39 +16,10 @@ import DomainList from './Domains/DomainList';
|
|||||||
function Explorer(): JSX.Element {
|
function Explorer(): JSX.Element {
|
||||||
const [showIP, setShowIP] = useState<boolean>(true);
|
const [showIP, setShowIP] = useState<boolean>(true);
|
||||||
|
|
||||||
const { currentQuery } = useQueryBuilder();
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
logEvent('API Monitoring: Landing page visited', {});
|
logEvent('API Monitoring: Landing page visited', {});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const { handleChangeQueryData } = useQueryOperations({
|
|
||||||
index: 0,
|
|
||||||
query: currentQuery.builder.queryData[0],
|
|
||||||
entityVersion: '',
|
|
||||||
});
|
|
||||||
|
|
||||||
const updatedCurrentQuery = useMemo(
|
|
||||||
() => ({
|
|
||||||
...currentQuery,
|
|
||||||
builder: {
|
|
||||||
...currentQuery.builder,
|
|
||||||
queryData: [
|
|
||||||
{
|
|
||||||
...currentQuery.builder.queryData[0],
|
|
||||||
dataSource: DataSource.TRACES,
|
|
||||||
aggregateOperator: 'noop',
|
|
||||||
aggregateAttribute: {
|
|
||||||
...currentQuery.builder.queryData[0].aggregateAttribute,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
[currentQuery],
|
|
||||||
);
|
|
||||||
const query = updatedCurrentQuery?.builder?.queryData[0] || null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Sentry.ErrorBoundary fallback={<ErrorBoundaryFallback />}>
|
<Sentry.ErrorBoundary fallback={<ErrorBoundaryFallback />}>
|
||||||
<div className={cx('api-monitoring-page', 'filter-visible')}>
|
<div className={cx('api-monitoring-page', 'filter-visible')}>
|
||||||
@ -83,16 +50,9 @@ function Explorer(): JSX.Element {
|
|||||||
source={QuickFiltersSource.API_MONITORING}
|
source={QuickFiltersSource.API_MONITORING}
|
||||||
config={ApiMonitoringQuickFiltersConfig}
|
config={ApiMonitoringQuickFiltersConfig}
|
||||||
handleFilterVisibilityChange={(): void => {}}
|
handleFilterVisibilityChange={(): void => {}}
|
||||||
onFilterChange={(query: Query): void =>
|
|
||||||
handleChangeQueryData('filters', query.builder.queryData[0].filters)
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
<DomainList
|
<DomainList showIP={showIP} />
|
||||||
query={query}
|
|
||||||
showIP={showIP}
|
|
||||||
handleChangeQueryData={handleChangeQueryData}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</Sentry.ErrorBoundary>
|
</Sentry.ErrorBoundary>
|
||||||
);
|
);
|
||||||
|
@ -24,6 +24,11 @@ export default function Toolbar({
|
|||||||
const isLogsExplorerPage = useMemo(() => pathname === ROUTES.LOGS_EXPLORER, [
|
const isLogsExplorerPage = useMemo(() => pathname === ROUTES.LOGS_EXPLORER, [
|
||||||
pathname,
|
pathname,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const isApiMonitoringPage = useMemo(() => pathname === ROUTES.API_MONITORING, [
|
||||||
|
pathname,
|
||||||
|
]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="toolbar">
|
<div className="toolbar">
|
||||||
<div className="leftActions">{leftActions}</div>
|
<div className="leftActions">{leftActions}</div>
|
||||||
@ -31,7 +36,7 @@ export default function Toolbar({
|
|||||||
{showOldCTA && <NewExplorerCTA />}
|
{showOldCTA && <NewExplorerCTA />}
|
||||||
<DateTimeSelectionV2
|
<DateTimeSelectionV2
|
||||||
showAutoRefresh={showAutoRefresh}
|
showAutoRefresh={showAutoRefresh}
|
||||||
showRefreshText={!isLogsExplorerPage}
|
showRefreshText={!isLogsExplorerPage && !isApiMonitoringPage}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="rightActions">{rightActions}</div>
|
<div className="rightActions">{rightActions}</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user