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

Feat: back navigation support throughout the app #6701

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
cf17992
feat: custom hook to prevent redundant navigation and handle default …
ahmadshaheer Dec 23, 2024
87515cd
feat: implement useSafeNavigation to QB, to ensure that the back navi…
ahmadshaheer Dec 23, 2024
238dd08
fix: handle syncing the relativeTime param with the time picker selec…
ahmadshaheer Dec 23, 2024
54ca6fa
feat: add support for absolute and relative time sync with time picke…
ahmadshaheer Dec 23, 2024
6839916
refactor: integrate safeNavigate in LogsExplorerChart and deprecate t…
ahmadshaheer Dec 23, 2024
9bc6cb6
feat: update pagination query params on pressing next/prev page
ahmadshaheer Dec 23, 2024
1a5668a
fix: fix the issue of NOOP getting converted to Count on coming back …
ahmadshaheer Dec 26, 2024
9b57f4a
refactor: replace history navigation with safeNavigate in DateTimeSel…
ahmadshaheer Dec 26, 2024
f7895db
feat: integrate useSafeNavigate across service details tabs
ahmadshaheer Dec 29, 2024
3e487eb
fix: fix duplicate redirections by converting the timestamp to millis…
ahmadshaheer Dec 29, 2024
d828c04
fix: replace history navigation with useSafeNavigate in LogsExplorerV…
ahmadshaheer Dec 29, 2024
1f52e2e
fix: replace history navigation with useSafeNavigate across dashboard…
ahmadshaheer Dec 29, 2024
aa2c7c4
fix: use safeNavigate in alert components
ahmadshaheer Dec 29, 2024
3e180f3
fix: fix the issue of back navigation in alert table and sync the pag…
ahmadshaheer Dec 29, 2024
ca99162
fix: handle back navigation for resource filter and sync the state wi…
ahmadshaheer Dec 29, 2024
38c10c0
fix: fix the issue of double redirection from top operations to traces
ahmadshaheer Dec 30, 2024
bab2667
fix: replace history.push with safeNavigate in TracesExplorer's updat…
ahmadshaheer Dec 30, 2024
10cf077
fix: prevent unnecessary query re-runs by checking stagedQuery before…
ahmadshaheer Dec 30, 2024
682a7c3
Merge branch 'main' into feat/back-navigation-support-throughout-the-app
ahmadshaheer Dec 30, 2024
b43aa08
chore: cleanup
ahmadshaheer Dec 30, 2024
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
29 changes: 29 additions & 0 deletions frontend/src/components/ResizeTable/DynamicColumnTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { ColumnGroupType, ColumnType } from 'antd/es/table';
import { ColumnsType } from 'antd/lib/table';
import logEvent from 'api/common/logEvent';
import LaunchChatSupport from 'components/LaunchChatSupport/LaunchChatSupport';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import useUrlQuery from 'hooks/useUrlQuery';
import { SlidersHorizontal } from 'lucide-react';
import { memo, useEffect, useState } from 'react';
import { popupContainer } from 'utils/selectPopupContainer';
Expand All @@ -25,8 +27,12 @@ function DynamicColumnTable({
onDragColumn,
facingIssueBtn,
shouldSendAlertsLogEvent,
pagination,
...restProps
}: DynamicColumnTableProps): JSX.Element {
const { safeNavigate } = useSafeNavigate();
const urlQuery = useUrlQuery();

const [columnsData, setColumnsData] = useState<ColumnsType | undefined>(
columns,
);
Expand Down Expand Up @@ -93,6 +99,28 @@ function DynamicColumnTable({
type: 'checkbox',
})) || [];

// Get current page from URL or default to 1
const currentPage = Number(urlQuery.get('page')) || 1;

const handlePaginationChange = (page: number, pageSize?: number): void => {
// Update URL with new page number while preserving other params
urlQuery.set('page', page.toString());

const newUrl = `${window.location.pathname}?${urlQuery.toString()}`;
safeNavigate(newUrl);

// Call original pagination handler if provided
if (pagination?.onChange && !!pageSize) {
pagination.onChange(page, pageSize);
}
};

const enhancedPagination = {
...pagination,
current: currentPage, // Ensure the pagination component shows the correct page
onChange: handlePaginationChange,
};

return (
<div className="DynamicColumnTable">
<Flex justify="flex-end" align="center" gap={8}>
Expand All @@ -116,6 +144,7 @@ function DynamicColumnTable({
<ResizeTable
columns={columnsData}
onDragColumn={onDragColumn}
pagination={enhancedPagination}
{...restProps}
/>
</div>
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/components/ResizeTable/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { TableProps } from 'antd';
import { ColumnsType } from 'antd/es/table';
import { PaginationProps } from 'antd/lib';
import { ColumnGroupType, ColumnType } from 'antd/lib/table';
import { LaunchChatSupportProps } from 'components/LaunchChatSupport/LaunchChatSupport';

Expand All @@ -15,6 +16,7 @@ export interface DynamicColumnTableProps extends TableProps<any> {
onDragColumn?: (fromIndex: number, toIndex: number) => void;
facingIssueBtn?: LaunchChatSupportProps;
shouldSendAlertsLogEvent?: boolean;
pagination?: PaginationProps;
}

export type GetVisibleColumnsFunction = (
Expand Down
12 changes: 6 additions & 6 deletions frontend/src/container/FormAlertRules/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import { BuilderUnitsFilter } from 'container/QueryBuilder/filters';
import { useQueryBuilder } from 'hooks/queryBuilder/useQueryBuilder';
import { useShareBuilderUrl } from 'hooks/queryBuilder/useShareBuilderUrl';
import { useNotifications } from 'hooks/useNotifications';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import useUrlQuery from 'hooks/useUrlQuery';
import history from 'lib/history';
import { mapQueryDataFromApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataFromApi';
import { mapQueryDataToApi } from 'lib/newQueryBuilder/queryBuilderMappers/mapQueryDataToApi';
import { isEqual } from 'lodash-es';
Expand Down Expand Up @@ -87,7 +87,7 @@ function FormAlertRules({
// init namespace for translations
const { t } = useTranslation('alerts');
const { featureFlags } = useAppContext();

const { safeNavigate } = useSafeNavigate();
const { selectedTime: globalSelectedInterval } = useSelector<
AppState,
GlobalReducer
Expand Down Expand Up @@ -224,7 +224,7 @@ function FormAlertRules({

const generatedUrl = `${location.pathname}?${queryParams.toString()}`;

history.replace(generatedUrl);
safeNavigate(generatedUrl);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [detectionMethod]);

Expand Down Expand Up @@ -295,8 +295,8 @@ function FormAlertRules({
urlQuery.delete(QueryParams.panelTypes);
urlQuery.delete(QueryParams.ruleId);
urlQuery.delete(QueryParams.relativeTime);
history.replace(`${ROUTES.LIST_ALL_ALERT}?${urlQuery.toString()}`);
}, [urlQuery]);
safeNavigate(`${ROUTES.LIST_ALL_ALERT}?${urlQuery.toString()}`);
}, [safeNavigate, urlQuery]);

// onQueryCategoryChange handles changes to query category
// in state as well as sets additional defaults
Expand Down Expand Up @@ -515,7 +515,7 @@ function FormAlertRules({
urlQuery.delete(QueryParams.panelTypes);
urlQuery.delete(QueryParams.ruleId);
urlQuery.delete(QueryParams.relativeTime);
history.replace(`${ROUTES.LIST_ALL_ALERT}?${urlQuery.toString()}`);
safeNavigate(`${ROUTES.LIST_ALL_ALERT}?${urlQuery.toString()}`);
}, 2000);
} else {
logData = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ import {
import PanelWrapper from 'container/PanelWrapper/PanelWrapper';
import { useGetQueryRange } from 'hooks/queryBuilder/useGetQueryRange';
import { useChartMutable } from 'hooks/useChartMutable';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import useUrlQuery from 'hooks/useUrlQuery';
import { getDashboardVariables } from 'lib/dashbaordVariables/getDashboardVariables';
import { GetQueryResultsProps } from 'lib/dashboard/getQueryResults';
import GetMinMax from 'lib/getMinMax';
import history from 'lib/history';
import { useDashboard } from 'providers/Dashboard/Dashboard';
import { useCallback, useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
Expand All @@ -49,6 +49,7 @@ function FullView({
isDependedDataLoaded = false,
onToggleModelHandler,
}: FullViewProps): JSX.Element {
const { safeNavigate } = useSafeNavigate();
const { selectedTime: globalSelectedTime } = useSelector<
AppState,
GlobalReducer
Expand Down Expand Up @@ -137,9 +138,9 @@ function FullView({
urlQuery.set(QueryParams.startTime, minTime.toString());
urlQuery.set(QueryParams.endTime, maxTime.toString());
const generatedUrl = `${location.pathname}?${urlQuery.toString()}`;
history.push(generatedUrl);
safeNavigate(generatedUrl);
},
[dispatch, location.pathname, urlQuery],
[dispatch, location.pathname, safeNavigate, urlQuery],
);

const [graphsVisibilityStates, setGraphsVisibilityStates] = useState<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ import { PANEL_TYPES } from 'constants/queryBuilder';
import PanelWrapper from 'container/PanelWrapper/PanelWrapper';
import { useUpdateDashboard } from 'hooks/dashboard/useUpdateDashboard';
import { useNotifications } from 'hooks/useNotifications';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import useUrlQuery from 'hooks/useUrlQuery';
import createQueryParams from 'lib/createQueryParams';
import history from 'lib/history';
import { RowData } from 'lib/query/createTableColumnsFromQuery';
import { useDashboard } from 'providers/Dashboard/Dashboard';
import {
Expand Down Expand Up @@ -46,6 +46,7 @@ function WidgetGraphComponent({
onDragSelect,
customTooltipElement,
}: WidgetGraphComponentProps): JSX.Element {
const { safeNavigate } = useSafeNavigate();
const [deleteModal, setDeleteModal] = useState(false);
const [hovered, setHovered] = useState(false);
const { notifications } = useNotifications();
Expand Down Expand Up @@ -172,7 +173,7 @@ function WidgetGraphComponent({
graphType: widget?.panelTypes,
widgetId: uuid,
};
history.push(`${pathname}/new?${createQueryParams(queryParams)}`);
safeNavigate(`${pathname}/new?${createQueryParams(queryParams)}`);
},
},
);
Expand All @@ -193,7 +194,7 @@ function WidgetGraphComponent({
const separator = existingSearch.toString() ? '&' : '';
const newSearch = `${existingSearch}${separator}${updatedSearch}`;

history.push({
safeNavigate({
pathname,
search: newSearch,
});
Expand All @@ -220,7 +221,7 @@ function WidgetGraphComponent({
});
setGraphVisibility(localStoredVisibilityState);
}
history.push({
safeNavigate({
pathname,
search: createQueryParams(updatedQueryParams),
});
Expand Down
7 changes: 4 additions & 3 deletions frontend/src/container/GridCardLayout/GridCardLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import { useUpdateDashboard } from 'hooks/dashboard/useUpdateDashboard';
import useComponentPermission from 'hooks/useComponentPermission';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { useNotifications } from 'hooks/useNotifications';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import useUrlQuery from 'hooks/useUrlQuery';
import history from 'lib/history';
import { defaultTo, isUndefined } from 'lodash-es';
import isEqual from 'lodash-es/isEqual';
import {
Expand Down Expand Up @@ -53,6 +53,7 @@ interface GraphLayoutProps {
// eslint-disable-next-line sonarjs/cognitive-complexity
function GraphLayout(props: GraphLayoutProps): JSX.Element {
const { handle } = props;
const { safeNavigate } = useSafeNavigate();
const {
selectedDashboard,
layouts,
Expand Down Expand Up @@ -189,13 +190,13 @@ function GraphLayout(props: GraphLayoutProps): JSX.Element {
urlQuery.set(QueryParams.startTime, startTimestamp.toString());
urlQuery.set(QueryParams.endTime, endTimestamp.toString());
const generatedUrl = `${pathname}?${urlQuery.toString()}`;
history.push(generatedUrl);
safeNavigate(generatedUrl);

if (startTimestamp !== endTimestamp) {
dispatch(UpdateTimeInterval('custom', [startTimestamp, endTimestamp]));
}
},
[dispatch, pathname, urlQuery],
[dispatch, pathname, safeNavigate, urlQuery],
);

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import { QueryParams } from 'constants/query';
import { PANEL_TYPES } from 'constants/queryBuilder';
import useCreateAlerts from 'hooks/queryBuilder/useCreateAlerts';
import useComponentPermission from 'hooks/useComponentPermission';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import useUrlQuery from 'hooks/useUrlQuery';
import history from 'lib/history';
import { RowData } from 'lib/query/createTableColumnsFromQuery';
import { isEmpty } from 'lodash-es';
import { CircleX, X } from 'lucide-react';
Expand Down Expand Up @@ -72,6 +72,7 @@ function WidgetHeader({
setSearchTerm,
}: IWidgetHeaderProps): JSX.Element | null {
const urlQuery = useUrlQuery();
const { safeNavigate } = useSafeNavigate();
const onEditHandler = useCallback((): void => {
const widgetId = widget.id;
urlQuery.set(QueryParams.widgetId, widgetId);
Expand All @@ -81,8 +82,8 @@ function WidgetHeader({
encodeURIComponent(JSON.stringify(widget.query)),
);
const generatedUrl = `${window.location.pathname}/new?${urlQuery}`;
history.push(generatedUrl);
}, [urlQuery, widget.id, widget.panelTypes, widget.query]);
safeNavigate(generatedUrl);
}, [safeNavigate, urlQuery, widget.id, widget.panelTypes, widget.query]);

const onCreateAlertsHandler = useCreateAlerts(widget, 'dashboardView');

Expand Down
22 changes: 12 additions & 10 deletions frontend/src/container/ListOfDashboard/DashboardsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import dayjs from 'dayjs';
import { useGetAllDashboard } from 'hooks/dashboard/useGetAllDashboard';
import useComponentPermission from 'hooks/useComponentPermission';
import { useNotifications } from 'hooks/useNotifications';
import history from 'lib/history';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import { get, isEmpty, isUndefined } from 'lodash-es';
import {
ArrowDownWideNarrow,
Expand Down Expand Up @@ -73,7 +73,7 @@ import {
} from 'react';
import { Layout } from 'react-grid-layout';
import { useTranslation } from 'react-i18next';
import { generatePath, Link } from 'react-router-dom';
import { generatePath } from 'react-router-dom';
import { useCopyToClipboard } from 'react-use';
import {
Dashboard,
Expand Down Expand Up @@ -104,7 +104,7 @@ function DashboardsList(): JSX.Element {
} = useGetAllDashboard();

const { user } = useAppContext();

const { safeNavigate } = useSafeNavigate();
const {
listSortOrder: sortOrder,
setListSortOrder: setSortOrder,
Expand Down Expand Up @@ -292,7 +292,7 @@ function DashboardsList(): JSX.Element {
});

if (response.statusCode === 200) {
history.push(
safeNavigate(
generatePath(ROUTES.DASHBOARD, {
dashboardId: response.payload.uuid,
}),
Expand All @@ -312,7 +312,7 @@ function DashboardsList(): JSX.Element {
errorMessage: (error as AxiosError).toString() || 'Something went Wrong',
});
}
}, [newDashboardState, t]);
}, [newDashboardState, safeNavigate, t]);

const onModalHandler = (uploadedGrafana: boolean): void => {
logEvent('Dashboard List: Import JSON clicked', {});
Expand Down Expand Up @@ -417,7 +417,7 @@ function DashboardsList(): JSX.Element {
if (event.metaKey || event.ctrlKey) {
window.open(getLink(), '_blank');
} else {
history.push(getLink());
safeNavigate(getLink());
}
logEvent('Dashboard List: Clicked on dashboard', {
dashboardId: dashboard.id,
Expand All @@ -443,10 +443,12 @@ function DashboardsList(): JSX.Element {
placement="left"
overlayClassName="title-toolip"
>
<Link
to={getLink()}
<div
className="title-link"
onClick={(e): void => e.stopPropagation()}
onClick={(e): void => {
e.stopPropagation();
safeNavigate(getLink());
}}
>
<img
src={dashboard?.image || Base64Icons[0]}
Expand All @@ -459,7 +461,7 @@ function DashboardsList(): JSX.Element {
>
{dashboard.name}
</Typography.Text>
</Link>
</div>
</Tooltip>
</div>

Expand Down
5 changes: 3 additions & 2 deletions frontend/src/container/ListOfDashboard/ImportJSON/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import createDashboard from 'api/dashboard/create';
import ROUTES from 'constants/routes';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { useNotifications } from 'hooks/useNotifications';
import { useSafeNavigate } from 'hooks/useSafeNavigate';
import { getUpdatedLayout } from 'lib/dashboard/getUpdatedLayout';
import history from 'lib/history';
import { ExternalLink, Github, MonitorDot, MoveRight, X } from 'lucide-react';
// #TODO: Lucide will be removing brand icons like GitHub in the future. In that case, we can use Simple Icons. https://simpleicons.org/
// See more: https://github.com/lucide-icons/lucide/issues/94
Expand All @@ -33,6 +33,7 @@ function ImportJSON({
uploadedGrafana,
onModalHandler,
}: ImportJSONProps): JSX.Element {
const { safeNavigate } = useSafeNavigate();
const [jsonData, setJsonData] = useState<Record<string, unknown>>();
const { t } = useTranslation(['dashboard', 'common']);
const [isUploadJSONError, setIsUploadJSONError] = useState<boolean>(false);
Expand Down Expand Up @@ -97,7 +98,7 @@ function ImportJSON({
});

if (response.statusCode === 200) {
history.push(
safeNavigate(
generatePath(ROUTES.DASHBOARD, {
dashboardId: response.payload.uuid,
}),
Expand Down
Loading
Loading