From ef5ebe34c5c9954252dc0d3cebfe09af2a273c45 Mon Sep 17 00:00:00 2001 From: Danil Kostromin Date: Fri, 9 Feb 2024 13:02:17 +0200 Subject: [PATCH 1/2] feat(log): make log page respect user preferences Redirect to log with experimental mode "on" in case user prefers experimental mode Signed-off-by: Danil Kostromin --- apps/bublik/src/pages/log-page/log-page.tsx | 29 ++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/apps/bublik/src/pages/log-page/log-page.tsx b/apps/bublik/src/pages/log-page/log-page.tsx index 8375f206..690b9659 100644 --- a/apps/bublik/src/pages/log-page/log-page.tsx +++ b/apps/bublik/src/pages/log-page/log-page.tsx @@ -1,12 +1,14 @@ /* SPDX-License-Identifier: Apache-2.0 */ /* SPDX-FileCopyrightText: 2021-2023 OKTET Labs Ltd. */ -import { useState } from 'react'; +import { useMemo, useState } from 'react'; +import { Navigate, useSearchParams } from 'react-router-dom'; import { LogPageMode } from '@/shared/types'; import { usePrefetchLogPage, usePrefetchRun } from '@/services/bublik-api'; import { CardHeader, RunModeToggle } from '@/shared/tailwind-ui'; import { LogFeature, useLogPage } from '@/bublik/features/log'; import { RunDetailsContainer } from '@/bublik/features/run-details'; +import { useUserPreferences } from '@/bublik/features/user-preferences'; export interface LogHeaderProps { runId: string; @@ -30,8 +32,31 @@ const LogHeader = ({ runId }: LogHeaderProps) => { ); }; +export const useExperimentalLogRedirect = () => { + const [searchParams] = useSearchParams(); + const { userPreferences } = useUserPreferences(); + + const shouldRedirect = + searchParams.get('experimental') === 'true' + ? false + : userPreferences.log.makeExperimentalModeDefault && + !searchParams.get('experimental') + ? true + : false; + + const redirectLocation = useMemo(() => { + const nextParams = new URLSearchParams(searchParams); + nextParams.set('experimental', 'true'); + + return { search: nextParams.toString() }; + }, [searchParams]); + + return { shouldRedirect, location: redirectLocation }; +}; + export const LogPage = () => { const { runId, mode } = useLogPage(); + const { location, shouldRedirect } = useExperimentalLogRedirect(); usePrefetchLogPage({ runId }); usePrefetchRun({ runId }); @@ -44,6 +69,8 @@ export const LogPage = () => { if (!runId) return
No Run ID!
; + if (shouldRedirect) return ; + return (
From 2d3cfff076211d8adb2a2b272119d7ad7556efd1 Mon Sep 17 00:00:00 2001 From: Danil Kostromin Date: Fri, 9 Feb 2024 13:03:48 +0200 Subject: [PATCH 2/2] refactor(log,history,measurements): make history links respect preferences Now when building link URLs for history we respect preferred mode of user for history e.g. aggregation or linear Signed-off-by: Danil Kostromin --- .../link-to-history/link-to-history.tsx | 9 +++++++-- .../measurement-statistics/link-to-history.tsx | 12 ++++++++---- .../src/lib/link-to-history/link-to-history.tsx | 11 ++++++++--- .../src/lib/result-links.container.tsx | 17 +++++++++++++++-- libs/shared/utils/src/lib/router.ts | 15 +++++++++++++-- 5 files changed, 51 insertions(+), 13 deletions(-) diff --git a/libs/bublik/features/log/src/lib/containers/link-to-history/link-to-history.tsx b/libs/bublik/features/log/src/lib/containers/link-to-history/link-to-history.tsx index df753cae..4ab56567 100644 --- a/libs/bublik/features/log/src/lib/containers/link-to-history/link-to-history.tsx +++ b/libs/bublik/features/log/src/lib/containers/link-to-history/link-to-history.tsx @@ -10,6 +10,7 @@ import { useGetHistoryLinkDefaultsQuery, useGetRunDetailsQuery } from '@/services/bublik-api'; +import { useUserPreferences } from '@/bublik/features/user-preferences'; import { LinkToHistory } from '../../components'; @@ -27,6 +28,7 @@ export const LinkToHistoryContainer: FC = ({ node: !state.data || !focusId ? undefined : state.data.tree[focusId] }) }); + const { userPreferences } = useUserPreferences(); const isTest = node?.entity === 'test'; const nodeId = node?.id; @@ -41,8 +43,11 @@ export const LinkToHistoryContainer: FC = ({ const query = buildQuery({ result: data, runDetails }); - return `/history${stringifySearch(query)}`; - }, [data, runDetails]); + const search = new URLSearchParams(stringifySearch(query)); + search.set('mode', userPreferences.history.defaultMode); + + return `/history?${search.toString()}`; + }, [data, runDetails, userPreferences.history.defaultMode]); return ( diff --git a/libs/bublik/features/measurements/src/lib/containers/measurement-statistics/link-to-history.tsx b/libs/bublik/features/measurements/src/lib/containers/measurement-statistics/link-to-history.tsx index f323be34..78c0440d 100644 --- a/libs/bublik/features/measurements/src/lib/containers/measurement-statistics/link-to-history.tsx +++ b/libs/bublik/features/measurements/src/lib/containers/measurement-statistics/link-to-history.tsx @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: Apache-2.0 */ /* SPDX-FileCopyrightText: 2021-2023 OKTET Labs Ltd. */ -import { FC, useMemo } from 'react'; +import { useMemo } from 'react'; import { Link } from 'react-router-dom'; import { stringifySearch } from '@/router'; @@ -10,24 +10,28 @@ import { } from '@/services/bublik-api'; import { buildQuery } from '@/shared/utils'; import { ButtonTw, Icon } from '@/shared/tailwind-ui'; +import { useUserPreferences } from '@/bublik/features/user-preferences'; export interface LinkToHistoryProps { runId: string; resultId: string; } -export const LinkToHistory: FC = ({ runId, resultId }) => { +export const LinkToHistory = ({ runId, resultId }: LinkToHistoryProps) => { const { data, isFetching, isError } = useGetHistoryLinkDefaultsQuery(resultId); const { data: runDetails } = useGetRunDetailsQuery(runId); + const { userPreferences } = useUserPreferences(); const query = useMemo(() => { if (!data || !runDetails) return ''; const query = buildQuery({ result: data, runDetails }); + const search = new URLSearchParams(stringifySearch(query)); + search.set('mode', userPreferences.history.defaultMode); - return stringifySearch(query); - }, [data, runDetails]); + return search.toString(); + }, [data, runDetails, userPreferences.history.defaultMode]); const to = { pathname: `/history`, search: query }; diff --git a/libs/bublik/features/result-links/src/lib/link-to-history/link-to-history.tsx b/libs/bublik/features/result-links/src/lib/link-to-history/link-to-history.tsx index d59c4d00..ebf1f6be 100644 --- a/libs/bublik/features/result-links/src/lib/link-to-history/link-to-history.tsx +++ b/libs/bublik/features/result-links/src/lib/link-to-history/link-to-history.tsx @@ -4,17 +4,22 @@ import { useMemo } from 'react'; import { Link } from 'react-router-dom'; import { getHistorySearch } from '@/shared/utils'; -import { DetailsAPIResponse, RunDataResults } from '@/shared/types'; +import { + DetailsAPIResponse, + HistoryMode, + RunDataResults +} from '@/shared/types'; import { ContextLinks, ContextLinksSection, Icon } from '@/shared/tailwind-ui'; export interface LinkToHistoryProps { result: RunDataResults; runDetails: DetailsAPIResponse; + userPreferredHistoryMode?: HistoryMode; } export const LinkToHistory = (props: LinkToHistoryProps) => { - const { runDetails, result } = props; - const search = getHistorySearch(runDetails, result); + const { runDetails, result, userPreferredHistoryMode = 'linear' } = props; + const search = getHistorySearch(runDetails, result, userPreferredHistoryMode); const prefilled = { pathname: '/history', search: search.prefilled }; const sections = useMemo( diff --git a/libs/bublik/features/result-links/src/lib/result-links.container.tsx b/libs/bublik/features/result-links/src/lib/result-links.container.tsx index 83053fd3..c60ad2dc 100644 --- a/libs/bublik/features/result-links/src/lib/result-links.container.tsx +++ b/libs/bublik/features/result-links/src/lib/result-links.container.tsx @@ -3,10 +3,15 @@ import { FC } from 'react'; import { Link } from 'react-router-dom'; -import { DetailsAPIResponse, RunDataResults } from '@/shared/types'; +import { + DetailsAPIResponse, + HistoryMode, + RunDataResults +} from '@/shared/types'; import { useGetRunDetailsQuery, usePrefetch } from '@/services/bublik-api'; import { routes } from '@/router'; import { Icon } from '@/shared/tailwind-ui'; +import { useUserPreferences } from '@/bublik/features/user-preferences'; import { LinkToHistory } from './link-to-history'; @@ -15,6 +20,7 @@ export interface ResultLinksProps { resultId: number; result: RunDataResults; runInfo: DetailsAPIResponse; + userPreferredHistoryMode?: HistoryMode; hasMeasurements?: boolean; onMeasurementLinkMouseEnter?: () => void; onLogLinkMouseEnter?: () => void; @@ -27,6 +33,7 @@ export const ResultLinks = (props: ResultLinksProps) => { hasMeasurements, result, runInfo, + userPreferredHistoryMode = 'linear', onLogLinkMouseEnter, onMeasurementLinkMouseEnter } = props; @@ -45,7 +52,11 @@ export const ResultLinks = (props: ResultLinksProps) => {
  • - +
  • {hasMeasurements && (
  • @@ -77,6 +88,7 @@ export const ResultLinksContainer: FC = ({ }) => { const { has_measurements: hasMeasurements } = result; const { data: runInfo } = useGetRunDetailsQuery(runId); + const { userPreferences } = useUserPreferences(); const prefetchLogURL = usePrefetch('getLogUrlByResultId'); const prefetchHistory = usePrefetch('getHistoryLinkDefaults'); @@ -101,6 +113,7 @@ export const ResultLinksContainer: FC = ({ runId={runId} runInfo={runInfo} result={result} + userPreferredHistoryMode={userPreferences.history.defaultMode} hasMeasurements={hasMeasurements} onLogLinkMouseEnter={handleLogLinkMouseEnter} onMeasurementLinkMouseEnter={handleMeasurementLinkMouseEnter} diff --git a/libs/shared/utils/src/lib/router.ts b/libs/shared/utils/src/lib/router.ts index bc9e2836..c831e862 100644 --- a/libs/shared/utils/src/lib/router.ts +++ b/libs/shared/utils/src/lib/router.ts @@ -6,6 +6,7 @@ import { DetailsAPIResponse, HistoryAPIQuery, HistoryDefaultResultAPIResponse, + HistoryMode, HistorySearchParams, RESULT_PROPERTIES, RUN_PROPERTIES, @@ -170,7 +171,8 @@ const byIterationWithAllTags = ( export const getHistorySearch = ( runDetails: DetailsAPIResponse, - resultInfo: RunDataResults + resultInfo: RunDataResults, + userPreferredHistoryMode: HistoryMode ): HistorySearch => { const { relevant_tags, important_tags } = runDetails; const important = important_tags; @@ -192,11 +194,20 @@ export const getHistorySearch = ( runDetails.finish ); - return { + const searchObj = { prefilled: stringifySearch(prefilled).concat('&fromRun=true'), byTestName: stringifySearch(testName), byIteration: stringifySearch(iteration), byIterationWithImportant: stringifySearch(iterationWithImportant), byIterationWithAllTags: stringifySearch(iterationWithAllTags) }; + + return Object.fromEntries( + Object.entries(searchObj).map(([key, search]) => { + const searchParams = new URLSearchParams(search); + searchParams.set('mode', userPreferredHistoryMode); + + return [key, searchParams.toString()]; + }) + ) as unknown as HistorySearch; };