mirror of
https://github.com/SigNoz/signoz.git
synced 2026-09-15 16:00:41 +01:00
Compare commits
3 Commits
feat/sqlco
...
fix/dashbo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e392bfbc6c | ||
|
|
5345d95f59 | ||
|
|
3a3f707af8 |
@@ -1,4 +1,4 @@
|
||||
import { useCallback } from 'react';
|
||||
import { startTransition, useCallback } from 'react';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import logEvent from 'api/common/logEvent';
|
||||
import type { DashboardtypesPanelDTO } from 'api/generated/services/sigNoz.schemas';
|
||||
@@ -57,12 +57,16 @@ export function useViewPanel(): UseViewPanelApi {
|
||||
QueryParams.compositeQuery,
|
||||
encodeURIComponent(JSON.stringify(query)),
|
||||
);
|
||||
// The provider applies the URL in an effect, a tick after the builder's fields have
|
||||
// mounted and read the query they keep. `resetQuery` — not `initQueryBuilderData`:
|
||||
// swapping one staged id for another re-anchors global time and refetches the grid.
|
||||
resetQuery(query);
|
||||
void logEvent(DashboardDetailEvents.PanelViewed, { panelId });
|
||||
safeNavigate(`${pathname}?${next.toString()}`);
|
||||
// Off the urgent lane: mounting the modal re-renders the app-wide query builder
|
||||
// and every grid panel, so let the menu this ran from close and paint first.
|
||||
startTransition(() => {
|
||||
// The provider applies the URL in an effect, a tick after the builder's fields have
|
||||
// mounted and read the query they keep. `resetQuery` — not `initQueryBuilderData`:
|
||||
// swapping one staged id for another re-anchors global time and refetches the grid.
|
||||
resetQuery(query);
|
||||
safeNavigate(`${pathname}?${next.toString()}`);
|
||||
});
|
||||
},
|
||||
[pathname, safeNavigate, urlQuery, resetQuery],
|
||||
);
|
||||
@@ -74,17 +78,19 @@ export function useViewPanel(): UseViewPanelApi {
|
||||
next.set(QueryParams.graphType, panelType);
|
||||
// A grid drilldown opens on the saved panel, never a stale editor handoff.
|
||||
clearViewPanelHandoff();
|
||||
// As in `openView`. Clearing the staged query matters twice over here: the URL
|
||||
// below carries this query's own id, and a staged query with a matching id
|
||||
// makes the provider skip the hydration that normalises legacy filter fields.
|
||||
resetQuery(query);
|
||||
// Same encoding the query builder uses (see `useGetCompositeQueryParam`): the URL
|
||||
// value is `encodeURIComponent(JSON.stringify(query))`, decoded once on read.
|
||||
next.set(
|
||||
QueryParams.compositeQuery,
|
||||
encodeURIComponent(JSON.stringify(query)),
|
||||
);
|
||||
safeNavigate(`${pathname}?${next.toString()}`);
|
||||
startTransition(() => {
|
||||
// As in `openView`. Clearing the staged query matters twice over here: the URL
|
||||
// below carries this query's own id, and a staged query with a matching id
|
||||
// makes the provider skip the hydration that normalises legacy filter fields.
|
||||
resetQuery(query);
|
||||
safeNavigate(`${pathname}?${next.toString()}`);
|
||||
});
|
||||
},
|
||||
[pathname, safeNavigate, urlQuery, resetQuery],
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useCallback } from 'react';
|
||||
import { startTransition, useCallback } from 'react';
|
||||
import { generatePath } from 'react-router-dom';
|
||||
import type { DashboardtypesPanelDTO } from 'api/generated/services/sigNoz.schemas';
|
||||
import { QueryParams } from 'constants/query';
|
||||
@@ -46,23 +46,32 @@ export function useOpenPanelEditor(): (
|
||||
new URLSearchParams(timeSearch).forEach((value, key) => {
|
||||
params.set(key, value);
|
||||
});
|
||||
if (options?.panel) {
|
||||
const query = getPanelBuilderQuery(options.panel);
|
||||
const query = options?.panel
|
||||
? getPanelBuilderQuery(options.panel)
|
||||
: undefined;
|
||||
if (query) {
|
||||
// Single-encoded: `useGetCompositeQueryParam` decodes once on top of the decode
|
||||
// `URLSearchParams` already does.
|
||||
params.set(
|
||||
QueryParams.compositeQuery,
|
||||
encodeURIComponent(JSON.stringify(query)),
|
||||
);
|
||||
// The provider applies the URL in an effect, a tick after the builder's fields
|
||||
// have mounted and read the query they keep (PromQL inputs, add-on rows).
|
||||
resetQuery(query);
|
||||
}
|
||||
const search = params.toString();
|
||||
safeNavigate(
|
||||
search ? `${path}?${search}` : path,
|
||||
options?.handoffState ? { state: options.handoffState } : undefined,
|
||||
);
|
||||
// Leaving the dashboard tears down every panel and re-renders the app-wide
|
||||
// query builder — off the urgent lane so the menu this ran from closes and
|
||||
// paints before that work starts.
|
||||
startTransition(() => {
|
||||
if (query) {
|
||||
// The provider applies the URL in an effect, a tick after the builder's fields
|
||||
// have mounted and read the query they keep (PromQL inputs, add-on rows).
|
||||
resetQuery(query);
|
||||
}
|
||||
safeNavigate(
|
||||
search ? `${path}?${search}` : path,
|
||||
options?.handoffState ? { state: options.handoffState } : undefined,
|
||||
);
|
||||
});
|
||||
},
|
||||
[safeNavigate, dashboardId, timeSearch, resetQuery],
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type ChangeEvent, useState } from 'react';
|
||||
import { type ChangeEvent, startTransition, useState } from 'react';
|
||||
// eslint-disable-next-line signoz/no-antd-components -- no @signozhq/ui multiline TextArea yet
|
||||
import { Input as AntInput } from 'antd';
|
||||
import { Button } from '@signozhq/ui/button';
|
||||
@@ -71,9 +71,13 @@ function BlankDashboardPanel({ onClose }: Props): JSX.Element {
|
||||
hasImage: Boolean(image),
|
||||
});
|
||||
onClose();
|
||||
safeNavigate(
|
||||
generatePath(ROUTES.DASHBOARD, { dashboardId: created.data.id }),
|
||||
);
|
||||
// Off the urgent lane so the modal's close paints before the dashboard page
|
||||
// mounts, instead of the modal sitting over it while that render runs.
|
||||
startTransition(() => {
|
||||
safeNavigate(
|
||||
generatePath(ROUTES.DASHBOARD, { dashboardId: created.data.id }),
|
||||
);
|
||||
});
|
||||
} catch (e) {
|
||||
showErrorModal(e as APIError);
|
||||
toast.error((e as AxiosError).toString() || 'Failed to create dashboard');
|
||||
@@ -154,6 +158,7 @@ function BlankDashboardPanel({ onClose }: Props): JSX.Element {
|
||||
color="primary"
|
||||
size="md"
|
||||
disabled={!canSubmit}
|
||||
loading={submitting}
|
||||
testId="create-dashboard-submit"
|
||||
onClick={(): void => {
|
||||
void handleCreate();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState } from 'react';
|
||||
import { startTransition, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { generatePath } from 'react-router-dom';
|
||||
import { red } from '@ant-design/colors';
|
||||
@@ -81,9 +81,13 @@ function ImportJsonPanel({ onClose }: Props): JSX.Element {
|
||||
const response = await createDashboardV2(payload);
|
||||
void logEvent(DashboardListEvents.DashboardCreated, { method: 'import' });
|
||||
onClose();
|
||||
safeNavigate(
|
||||
generatePath(ROUTES.DASHBOARD, { dashboardId: response.data.id }),
|
||||
);
|
||||
// As in the blank panel: let the modal's close paint before the dashboard
|
||||
// page mounts.
|
||||
startTransition(() => {
|
||||
safeNavigate(
|
||||
generatePath(ROUTES.DASHBOARD, { dashboardId: response.data.id }),
|
||||
);
|
||||
});
|
||||
} catch (error) {
|
||||
showErrorModal(error as APIError);
|
||||
setIsCreateError(true);
|
||||
|
||||
Reference in New Issue
Block a user