From d9e7ee7bffe449d859a6359be95c175d556fce3a Mon Sep 17 00:00:00 2001 From: Gabriel Bernal Date: Tue, 1 Jul 2025 10:40:27 +0200 Subject: [PATCH 1/3] fix: allow correct selection of dashboard with same name in different projects --- .../dashboards/perses/dashboard-page.tsx | 1 + .../dashboards/shared/dashboard-skeleton.tsx | 32 +++++++++++++------ 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/web/src/components/dashboards/perses/dashboard-page.tsx b/web/src/components/dashboards/perses/dashboard-page.tsx index 13455644..f09b8b71 100644 --- a/web/src/components/dashboards/perses/dashboard-page.tsx +++ b/web/src/components/dashboards/perses/dashboard-page.tsx @@ -53,6 +53,7 @@ const MonitoringDashboardsPage_: React.FC = () => { boardItems={activeProjectDashboardsMetadata} changeBoard={changeBoard} dashboardName={dashboardName} + activeProject={activeProject} > diff --git a/web/src/components/dashboards/shared/dashboard-skeleton.tsx b/web/src/components/dashboards/shared/dashboard-skeleton.tsx index c6ca18f8..77def6b7 100644 --- a/web/src/components/dashboards/shared/dashboard-skeleton.tsx +++ b/web/src/components/dashboards/shared/dashboard-skeleton.tsx @@ -50,10 +50,11 @@ type MonitoringDashboardsPageProps = React.PropsWithChildren<{ boardItems: CombinedDashboardMetadata[]; changeBoard: (dashboardName: string) => void; dashboardName: string; + activeProject?: string; }>; const DashboardSkeleton: React.FC = React.memo( - ({ children, boardItems, changeBoard, dashboardName }) => { + ({ children, boardItems, changeBoard, dashboardName, activeProject }) => { const { t } = useTranslation(process.env.I18N_NAMESPACE); const isPerses = useIsPerses(); @@ -61,19 +62,30 @@ const DashboardSkeleton: React.FC = React.memo( const { setDashboard } = useDashboardActions(); const variables = useVariableDefinitions(); - const onChangeBoard = (selectedDashboard: string) => { - changeBoard(selectedDashboard); + const onChangeBoard = React.useCallback( + (selectedDashboard: string) => { + changeBoard(selectedDashboard); - if (isPerses) { - const selectedBoard = boardItems.find( - (item) => item.name.toLowerCase() === selectedDashboard.toLowerCase(), - ); + if (isPerses) { + const selectedBoard = boardItems.find( + (item) => + item.name.toLowerCase() === selectedDashboard.toLowerCase() && + item.project?.toLowerCase() === activeProject?.toLowerCase(), + ); - if (selectedBoard) { - setDashboard(selectedBoard.persesDashboard); + if (selectedBoard) { + setDashboard(selectedBoard.persesDashboard); + } } + }, + [changeBoard, boardItems, activeProject, isPerses, setDashboard], + ); + + React.useEffect(() => { + if (isPerses) { + onChangeBoard(dashboardName); } - }; + }, [dashboardName, isPerses, onChangeBoard]); return ( <> From 6a99c44f09d770c30ffa32154babd1869580eba3 Mon Sep 17 00:00:00 2001 From: Gabriel Bernal Date: Tue, 1 Jul 2025 11:33:52 +0200 Subject: [PATCH 2/3] refactor: remove shared components between perses and legacy dashboards --- .../custom-time-range-modal.tsx | 18 +-- .../legacy/dashboard-skeleton-legacy.tsx | 111 +++++++++++++ .../dashboards/{shared => legacy}/error.tsx | 0 .../components/dashboards/legacy/graph.tsx | 2 +- .../legacy/legacy-dashboard-page.tsx | 60 +++---- .../legacy/legacy-variable-dropdowns.tsx | 34 ++-- .../dashboards/legacy/single-stat.tsx | 2 +- .../components/dashboards/legacy/table.tsx | 2 +- .../dashboards/legacy/time-dropdowns.tsx | 152 ++++++++++++++++++ .../dashboards/legacy/useLegacyDashboards.ts | 2 +- .../dashboards/{shared => legacy}/utils.ts | 0 .../dashboards/perses/dashboard-page.tsx | 16 +- .../{shared => perses}/dashboard-skeleton.tsx | 68 ++++---- .../dashboards/shared/time-dropdowns.tsx | 19 --- web/src/reducers/observe.ts | 2 +- 15 files changed, 354 insertions(+), 134 deletions(-) rename web/src/components/dashboards/{shared => legacy}/custom-time-range-modal.tsx (94%) create mode 100644 web/src/components/dashboards/legacy/dashboard-skeleton-legacy.tsx rename web/src/components/dashboards/{shared => legacy}/error.tsx (100%) create mode 100644 web/src/components/dashboards/legacy/time-dropdowns.tsx rename web/src/components/dashboards/{shared => legacy}/utils.ts (100%) rename web/src/components/dashboards/{shared => perses}/dashboard-skeleton.tsx (61%) delete mode 100644 web/src/components/dashboards/shared/time-dropdowns.tsx diff --git a/web/src/components/dashboards/shared/custom-time-range-modal.tsx b/web/src/components/dashboards/legacy/custom-time-range-modal.tsx similarity index 94% rename from web/src/components/dashboards/shared/custom-time-range-modal.tsx rename to web/src/components/dashboards/legacy/custom-time-range-modal.tsx index f56bf539..31516cb8 100644 --- a/web/src/components/dashboards/shared/custom-time-range-modal.tsx +++ b/web/src/components/dashboards/legacy/custom-time-range-modal.tsx @@ -1,7 +1,3 @@ -import * as _ from 'lodash-es'; -import * as React from 'react'; -import { useTranslation } from 'react-i18next'; -import { useDispatch } from 'react-redux'; import { Button, DatePicker, @@ -11,12 +7,15 @@ import { ModalVariant, TimePicker, } from '@patternfly/react-core'; +import * as _ from 'lodash-es'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; +import { useDispatch } from 'react-redux'; import { dashboardsSetEndTime, dashboardsSetTimespan, Perspective } from '../../../actions/observe'; -import { QueryParams } from '../../query-params'; -import { useIsPerses } from './useIsPerses'; import { NumberParam, useQueryParam } from 'use-query-params'; +import { QueryParams } from '../../query-params'; const zeroPad = (number: number) => (number < 10 ? `0${number}` : number); @@ -48,7 +47,6 @@ const CustomTimeRangeModal: React.FC = ({ endTime, }) => { const { t } = useTranslation(process.env.I18N_NAMESPACE); - const isPerses = useIsPerses(); const [, setEndTime] = useQueryParam(QueryParams.EndTime, NumberParam); const [, setTimeRange] = useQueryParam(QueryParams.TimeRange, NumberParam); @@ -71,10 +69,8 @@ const CustomTimeRangeModal: React.FC = ({ const from = Date.parse(`${fromDate} ${fromTime}`); const to = Date.parse(`${toDate} ${toTime}`); if (_.isInteger(from) && _.isInteger(to)) { - if (!isPerses) { - dispatch(dashboardsSetEndTime(to, perspective)); - dispatch(dashboardsSetTimespan(to - from, perspective)); - } + dispatch(dashboardsSetEndTime(to, perspective)); + dispatch(dashboardsSetTimespan(to - from, perspective)); setEndTime(Number(to.toString())); setTimeRange(Number((to - from).toString())); setClosed(); diff --git a/web/src/components/dashboards/legacy/dashboard-skeleton-legacy.tsx b/web/src/components/dashboards/legacy/dashboard-skeleton-legacy.tsx new file mode 100644 index 00000000..b2bfadb3 --- /dev/null +++ b/web/src/components/dashboards/legacy/dashboard-skeleton-legacy.tsx @@ -0,0 +1,111 @@ +import * as _ from 'lodash-es'; +import * as React from 'react'; +import { Helmet } from 'react-helmet'; +import { useTranslation } from 'react-i18next'; + +import { + Divider, + PageSection, + Split, + SplitItem, + Stack, + StackItem, + Title, +} from '@patternfly/react-core'; +import { usePerspective } from '../../hooks/usePerspective'; +import { CombinedDashboardMetadata } from '../perses/hooks/useDashboardsData'; +import { DashboardDropdown } from '../shared/dashboard-dropdown'; +import { PollIntervalDropdown, TimespanDropdown } from './time-dropdowns'; +import { LegacyDashboardsAllVariableDropdowns } from './legacy-variable-dropdowns'; + +const HeaderTop: React.FC = React.memo(() => { + const { t } = useTranslation(process.env.I18N_NAMESPACE); + + return ( + + + {t('Dashboards')} + + + + + + + + + + + + + ); +}); + +type MonitoringDashboardsLegacyPageProps = React.PropsWithChildren<{ + boardItems: CombinedDashboardMetadata[]; + changeBoard: (dashboardName: string) => void; + dashboardName: string; +}>; + +export const DashboardSkeletonLegacy: React.FC = React.memo( + ({ children, boardItems, changeBoard, dashboardName }) => { + const { t } = useTranslation(process.env.I18N_NAMESPACE); + + const { perspective } = usePerspective(); + + const onChangeBoard = React.useCallback( + (selectedDashboard: string) => { + changeBoard(selectedDashboard); + }, + [changeBoard], + ); + + return ( + <> + {perspective !== 'dev' && ( + + {t('Metrics dashboards')} + + )} + + {perspective !== 'dev' && } + + {!_.isEmpty(boardItems) && ( + + + + )} + + + + + {perspective === 'dev' ? ( + + + + + + + + + + + + ) : ( + + + + + + )} + + + + {children} + + ); + }, +); diff --git a/web/src/components/dashboards/shared/error.tsx b/web/src/components/dashboards/legacy/error.tsx similarity index 100% rename from web/src/components/dashboards/shared/error.tsx rename to web/src/components/dashboards/legacy/error.tsx diff --git a/web/src/components/dashboards/legacy/graph.tsx b/web/src/components/dashboards/legacy/graph.tsx index 6570f248..47ea3549 100644 --- a/web/src/components/dashboards/legacy/graph.tsx +++ b/web/src/components/dashboards/legacy/graph.tsx @@ -5,7 +5,7 @@ import { dashboardsSetEndTime, dashboardsSetTimespan, Perspective } from '../../ import { FormatSeriesTitle, QueryBrowser } from '../../query-browser'; import { MonitoringState } from '../../../reducers/observe'; import { getLegacyObserveState } from '../../hooks/usePerspective'; -import { DEFAULT_GRAPH_SAMPLES } from '../shared/utils'; +import { DEFAULT_GRAPH_SAMPLES } from './utils'; import { CustomDataSource } from '@openshift-console/dynamic-plugin-sdk/lib/extensions/dashboard-data-source'; type Props = { diff --git a/web/src/components/dashboards/legacy/legacy-dashboard-page.tsx b/web/src/components/dashboards/legacy/legacy-dashboard-page.tsx index aacd7d78..f4c04a6a 100644 --- a/web/src/components/dashboards/legacy/legacy-dashboard-page.tsx +++ b/web/src/components/dashboards/legacy/legacy-dashboard-page.tsx @@ -1,24 +1,21 @@ import { Overview } from '@openshift-console/dynamic-plugin-sdk'; import * as React from 'react'; -import { RouteComponentProps, withRouter } from 'react-router-dom'; - -import ErrorAlert from '../shared/error'; - -import { LegacyDashboard } from '../legacy/legacy-dashboard'; -import DashboardSkeleton from '../shared/dashboard-skeleton'; -import { usePerspective } from '../../hooks/usePerspective'; import { useTranslation } from 'react-i18next'; -import { useLegacyDashboards } from './useLegacyDashboards'; -import { PersesContext } from '../../router'; +import { RouteComponentProps, withRouter } from 'react-router-dom'; +import { usePerspective } from 'src/components/hooks/usePerspective'; import { LoadingInline } from '../../../components/console/console-shared/src/components/loading/LoadingInline'; import withFallback from '../../console/console-shared/error/fallbacks/withFallback'; +import { LegacyDashboard } from '../legacy/legacy-dashboard'; +import { DashboardSkeletonLegacy } from './dashboard-skeleton-legacy'; +import ErrorAlert from './error'; +import { useLegacyDashboards } from './useLegacyDashboards'; type MonitoringLegacyDashboardsPageProps = { urlBoard: string; namespace?: string; }; -const MonitoringLegacyDashboardsPage_: React.FC = ({ +const LegacyDashboardsPage_: React.FC = ({ urlBoard, namespace, // only used in developer perspective }) => { @@ -34,25 +31,23 @@ const MonitoringLegacyDashboardsPage_: React.FC - - - {legacyDashboardsLoading ? ( - - ) : legacyDashboardsError ? ( - - ) : ( - - )} - - - + + + {legacyDashboardsLoading ? ( + + ) : legacyDashboardsError ? ( + + ) : ( + + )} + + ); }; @@ -65,12 +60,7 @@ const MonitoringLegacyDashboardsPageWrapper: React.FC { return ( - - - + ); }; diff --git a/web/src/components/dashboards/legacy/legacy-variable-dropdowns.tsx b/web/src/components/dashboards/legacy/legacy-variable-dropdowns.tsx index 81ffae10..29acd1f0 100644 --- a/web/src/components/dashboards/legacy/legacy-variable-dropdowns.tsx +++ b/web/src/components/dashboards/legacy/legacy-variable-dropdowns.tsx @@ -1,4 +1,3 @@ -import * as _ from 'lodash-es'; import { PrometheusEndpoint, RedExclamationCircleIcon, @@ -6,38 +5,37 @@ import { useResolvedExtensions, } from '@openshift-console/dynamic-plugin-sdk'; import { - Tooltip, - Select, - SelectOption, MenuToggle, MenuToggleElement, + Select, + SelectOption, + Split, + Tooltip, } from '@patternfly/react-core'; +import { Map as ImmutableMap } from 'immutable'; +import * as _ from 'lodash-es'; import * as React from 'react'; import { useTranslation } from 'react-i18next'; import { useDispatch, useSelector } from 'react-redux'; -import { Map as ImmutableMap } from 'immutable'; -import { SingleTypeaheadDropdown } from '../../console/utils/single-typeahead-dropdown'; import { getPrometheusURL } from '../../console/graphs/helpers'; import { getQueryArgument, setQueryArgument } from '../../console/utils/router'; import { useSafeFetch } from '../../console/utils/safe-fetch-hook'; +import { SingleTypeaheadDropdown } from '../../console/utils/single-typeahead-dropdown'; +import { + DataSource, + isDataSource, +} from '@openshift-console/dynamic-plugin-sdk/lib/extensions/dashboard-data-source'; import { dashboardsPatchVariable, dashboardsVariableOptionsLoaded, Perspective, } from '../../../actions/observe'; -import { getTimeRanges, isTimeoutError, QUERY_CHUNK_SIZE } from '../../utils'; -import { getLegacyObserveState, usePerspective } from '../../hooks/usePerspective'; import { MonitoringState } from '../../../reducers/observe'; -import { - DEFAULT_GRAPH_SAMPLES, - MONITORING_DASHBOARDS_VARIABLE_ALL_OPTION_KEY, -} from '../shared/utils'; -import { - DataSource, - isDataSource, -} from '@openshift-console/dynamic-plugin-sdk/lib/extensions/dashboard-data-source'; +import { getLegacyObserveState, usePerspective } from '../../hooks/usePerspective'; +import { getTimeRanges, isTimeoutError, QUERY_CHUNK_SIZE } from '../../utils'; +import { DEFAULT_GRAPH_SAMPLES, MONITORING_DASHBOARDS_VARIABLE_ALL_OPTION_KEY } from './utils'; const intervalVariableRegExps = ['__interval', '__rate_interval', '__auto_interval_[a-z]+']; @@ -321,7 +319,7 @@ export const LegacyDashboardsAllVariableDropdowns: React.FC = () => { } return ( - <> + {variables.keySeq().map((name: string) => ( { perspective={perspective} /> ))} - + ); }; diff --git a/web/src/components/dashboards/legacy/single-stat.tsx b/web/src/components/dashboards/legacy/single-stat.tsx index b08e0947..f61f347b 100644 --- a/web/src/components/dashboards/legacy/single-stat.tsx +++ b/web/src/components/dashboards/legacy/single-stat.tsx @@ -3,7 +3,7 @@ import * as React from 'react'; import { PrometheusEndpoint, PrometheusResponse } from '@openshift-console/dynamic-plugin-sdk'; import { Bullseye } from '@patternfly/react-core'; -import ErrorAlert from '../shared/error'; +import ErrorAlert from './error'; import { getPrometheusURL } from '../../console/graphs/helpers'; import { usePoll } from '../../console/utils/poll-hook'; import { useSafeFetch } from '../../console/utils/safe-fetch-hook'; diff --git a/web/src/components/dashboards/legacy/table.tsx b/web/src/components/dashboards/legacy/table.tsx index a9ba4dcb..b6feed41 100644 --- a/web/src/components/dashboards/legacy/table.tsx +++ b/web/src/components/dashboards/legacy/table.tsx @@ -21,7 +21,7 @@ import * as _ from 'lodash-es'; import * as React from 'react'; import { useTranslation } from 'react-i18next'; -import ErrorAlert from '../shared/error'; +import ErrorAlert from './error'; import { getPrometheusURL } from '../../console/graphs/helpers'; import { usePoll } from '../../console/utils/poll-hook'; import { useSafeFetch } from '../../console/utils/safe-fetch-hook'; diff --git a/web/src/components/dashboards/legacy/time-dropdowns.tsx b/web/src/components/dashboards/legacy/time-dropdowns.tsx new file mode 100644 index 00000000..627d50cf --- /dev/null +++ b/web/src/components/dashboards/legacy/time-dropdowns.tsx @@ -0,0 +1,152 @@ +import { Stack, StackItem } from '@patternfly/react-core'; +import * as _ from 'lodash-es'; +import * as React from 'react'; +import { useTranslation } from 'react-i18next'; +import { useDispatch, useSelector } from 'react-redux'; +import { NumberParam, useQueryParam } from 'use-query-params'; +import { + dashboardsSetEndTime, + dashboardsSetPollInterval, + dashboardsSetTimespan, +} from '../../../actions/observe'; +import { SimpleSelect, SimpleSelectOption } from '../../../components/SimpleSelect'; +import { MonitoringState } from '../../../reducers/observe'; +import { + formatPrometheusDuration, + parsePrometheusDuration, +} from '../../console/console-shared/src/datetime/prometheus'; +import { DEFAULT_REFRESH_INTERVAL, DropDownPollInterval } from '../../dropdown-poll-interval'; +import { useBoolean } from '../../hooks/useBoolean'; +import { getLegacyObserveState, usePerspective } from '../../hooks/usePerspective'; +import { QueryParams } from '../../query-params'; +import CustomTimeRangeModal from './custom-time-range-modal'; + +const CUSTOM_TIME_RANGE_KEY = 'CUSTOM_TIME_RANGE_KEY'; +const DEFAULT_TIMERANGE = '30m'; + +export const TimespanDropdown: React.FC = () => { + const { t } = useTranslation(process.env.I18N_NAMESPACE); + + const { perspective } = usePerspective(); + + const [isModalOpen, , setModalOpen, setModalClosed] = useBoolean(false); + + const timespan = useSelector((state: MonitoringState) => + getLegacyObserveState(perspective, state)?.getIn(['dashboards', perspective, 'timespan']), + ); + const endTime = useSelector((state: MonitoringState) => + getLegacyObserveState(perspective, state)?.getIn(['dashboards', perspective, 'endTime']), + ); + + const [timeRangeFromParams, setTimeRange] = useQueryParam(QueryParams.TimeRange, NumberParam); + const [endTimeFromParams, setEndTime] = useQueryParam(QueryParams.EndTime, NumberParam); + + const selectedKey = + endTime || endTimeFromParams + ? CUSTOM_TIME_RANGE_KEY + : formatPrometheusDuration(_.toNumber(timeRangeFromParams) || timespan); + + const dispatch = useDispatch(); + const onChange = React.useCallback( + (v: string) => { + if (v === CUSTOM_TIME_RANGE_KEY) { + setModalOpen(); + } else { + setTimeRange(parsePrometheusDuration(v)); + setEndTime(undefined); + dispatch(dashboardsSetTimespan(parsePrometheusDuration(v), perspective)); + dispatch(dashboardsSetEndTime(null, perspective)); + } + }, + [setModalOpen, dispatch, perspective, setTimeRange, setEndTime], + ); + + const initialOptions = React.useMemo(() => { + const intervalOptions: SimpleSelectOption[] = [ + { content: t('Custom time range'), value: CUSTOM_TIME_RANGE_KEY }, + { content: t('Last {{count}} minute', { count: 5 }), value: '5m' }, + { content: t('Last {{count}} minute', { count: 15 }), value: '15m' }, + { content: t('Last {{count}} minute', { count: 30 }), value: '30m' }, + { content: t('Last {{count}} hour', { count: 1 }), value: '1h' }, + { content: t('Last {{count}} hour', { count: 2 }), value: '2h' }, + { content: t('Last {{count}} hour', { count: 6 }), value: '6h' }, + { content: t('Last {{count}} hour', { count: 12 }), value: '12h' }, + { content: t('Last {{count}} day', { count: 1 }), value: '1d' }, + { content: t('Last {{count}} day', { count: 2 }), value: '2d' }, + { content: t('Last {{count}} week', { count: 1 }), value: '1w' }, + { content: t('Last {{count}} week', { count: 2 }), value: '2w' }, + ]; + + // If selectedKey is empty, the dashboard has changed. Reset selected to default value. + if (selectedKey === '' || (selectedKey === DEFAULT_TIMERANGE && !timeRangeFromParams)) { + setTimeRange(parsePrometheusDuration(DEFAULT_TIMERANGE)); + setEndTime(undefined); + } + return intervalOptions.map((o) => ({ ...o, selected: o.value === selectedKey })); + }, [selectedKey, t, timeRangeFromParams, setTimeRange, setEndTime]); + + const defaultTimerange = timespan ?? undefined; + const defaultEndTime = endTime ?? undefined; + + return ( + <> + + + + + + + { + if (selection) { + onChange(String(selection)); + } + }} + placeholder={t('Last {{count}} minute', { count: 30 })} + /> + + + + ); +}; + +export const PollIntervalDropdown: React.FC = () => { + const { t } = useTranslation(process.env.I18N_NAMESPACE); + const { perspective } = usePerspective(); + const [selectedInterval, setSelectedInterval] = React.useState(DEFAULT_REFRESH_INTERVAL); + + const dispatch = useDispatch(); + const [, setRefreshInterval] = useQueryParam(QueryParams.RefreshInterval, NumberParam); + + const setInterval = React.useCallback( + (v: number) => { + setSelectedInterval(v); + setRefreshInterval(v); + dispatch(dashboardsSetPollInterval(v, perspective)); + }, + [dispatch, perspective, setRefreshInterval], + ); + + return ( + + + + + + + + + ); +}; diff --git a/web/src/components/dashboards/legacy/useLegacyDashboards.ts b/web/src/components/dashboards/legacy/useLegacyDashboards.ts index 71a39933..86c94e9c 100644 --- a/web/src/components/dashboards/legacy/useLegacyDashboards.ts +++ b/web/src/components/dashboards/legacy/useLegacyDashboards.ts @@ -13,7 +13,7 @@ import { getQueryArgument } from '../../console/utils/router'; import { MONITORING_DASHBOARDS_DEFAULT_TIMESPAN, MONITORING_DASHBOARDS_VARIABLE_ALL_OPTION_KEY, -} from '../shared/utils'; +} from './utils'; import { DashboardsClearVariables, dashboardsPatchAllVariables, diff --git a/web/src/components/dashboards/shared/utils.ts b/web/src/components/dashboards/legacy/utils.ts similarity index 100% rename from web/src/components/dashboards/shared/utils.ts rename to web/src/components/dashboards/legacy/utils.ts diff --git a/web/src/components/dashboards/perses/dashboard-page.tsx b/web/src/components/dashboards/perses/dashboard-page.tsx index f09b8b71..130eebbf 100644 --- a/web/src/components/dashboards/perses/dashboard-page.tsx +++ b/web/src/components/dashboards/perses/dashboard-page.tsx @@ -2,17 +2,15 @@ import { Overview } from '@openshift-console/dynamic-plugin-sdk'; import * as React from 'react'; import { RouteComponentProps, withRouter } from 'react-router-dom'; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { LoadingInline } from '../../console/console-shared/src/components/loading/LoadingInline'; -import DashboardSkeleton from '../shared/dashboard-skeleton'; import { PersesWrapper } from './PersesWrapper'; - +import { DashboardSkeleton } from './dashboard-skeleton'; +import { DashboardEmptyState } from './emptystates/DashboardEmptyState'; +import { ProjectEmptyState } from './emptystates/ProjectEmptyState'; +import { useDashboardsData } from './hooks/useDashboardsData'; import PersesBoard from './perses-dashboards'; import { ProjectBar } from './project/ProjectBar'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { useDashboardsData } from './hooks/useDashboardsData'; -import { ProjectEmptyState } from './emptystates/ProjectEmptyState'; -import { DashboardEmptyState } from './emptystates/DashboardEmptyState'; -import { PersesContext } from '../../router'; const queryClient = new QueryClient({ defaultOptions: { @@ -68,9 +66,7 @@ const MonitoringDashboardsPage_: React.FC = () => { const MonitoringDashboardsPageWrapper: React.FC = () => { return ( - - - + ); }; diff --git a/web/src/components/dashboards/shared/dashboard-skeleton.tsx b/web/src/components/dashboards/perses/dashboard-skeleton.tsx similarity index 61% rename from web/src/components/dashboards/shared/dashboard-skeleton.tsx rename to web/src/components/dashboards/perses/dashboard-skeleton.tsx index 77def6b7..47c49b8f 100644 --- a/web/src/components/dashboards/shared/dashboard-skeleton.tsx +++ b/web/src/components/dashboards/perses/dashboard-skeleton.tsx @@ -3,12 +3,6 @@ import * as React from 'react'; import { Helmet } from 'react-helmet'; import { useTranslation } from 'react-i18next'; -import { usePerspective } from '../../hooks/usePerspective'; -import { DashboardDropdown } from './dashboard-dropdown'; -import { LegacyDashboardsAllVariableDropdowns } from '../legacy/legacy-variable-dropdowns'; -import { TimeDropdowns } from './time-dropdowns'; -import { CombinedDashboardMetadata } from '../perses/hooks/useDashboardsData'; -import { useIsPerses } from './useIsPerses'; import { Divider, PageSection, @@ -19,12 +13,15 @@ import { StackItem, Title, } from '@patternfly/react-core'; -import { TimeRangeControls } from '@perses-dev/plugin-system'; import { DashboardStickyToolbar, useDashboardActions, useVariableDefinitions, } from '@perses-dev/dashboards'; +import { TimeRangeControls } from '@perses-dev/plugin-system'; +import { usePerspective } from '../../hooks/usePerspective'; +import { DashboardDropdown } from '../shared/dashboard-dropdown'; +import { CombinedDashboardMetadata } from './hooks/useDashboardsData'; const HeaderTop: React.FC = React.memo(() => { const { t } = useTranslation(process.env.I18N_NAMESPACE); @@ -37,7 +34,6 @@ const HeaderTop: React.FC = React.memo(() => { - {t('Time Range Controls')} @@ -53,11 +49,9 @@ type MonitoringDashboardsPageProps = React.PropsWithChildren<{ activeProject?: string; }>; -const DashboardSkeleton: React.FC = React.memo( +export const DashboardSkeleton: React.FC = React.memo( ({ children, boardItems, changeBoard, dashboardName, activeProject }) => { const { t } = useTranslation(process.env.I18N_NAMESPACE); - const isPerses = useIsPerses(); - const { perspective } = usePerspective(); const { setDashboard } = useDashboardActions(); const variables = useVariableDefinitions(); @@ -66,26 +60,22 @@ const DashboardSkeleton: React.FC = React.memo( (selectedDashboard: string) => { changeBoard(selectedDashboard); - if (isPerses) { - const selectedBoard = boardItems.find( - (item) => - item.name.toLowerCase() === selectedDashboard.toLowerCase() && - item.project?.toLowerCase() === activeProject?.toLowerCase(), - ); + const selectedBoard = boardItems.find( + (item) => + item.name.toLowerCase() === selectedDashboard.toLowerCase() && + item.project?.toLowerCase() === activeProject?.toLowerCase(), + ); - if (selectedBoard) { - setDashboard(selectedBoard.persesDashboard); - } + if (selectedBoard) { + setDashboard(selectedBoard.persesDashboard); } }, - [changeBoard, boardItems, activeProject, isPerses, setDashboard], + [changeBoard, boardItems, activeProject, setDashboard], ); React.useEffect(() => { - if (isPerses) { - onChangeBoard(dashboardName); - } - }, [dashboardName, isPerses, onChangeBoard]); + onChangeBoard(dashboardName); + }, [dashboardName, onChangeBoard]); return ( <> @@ -106,19 +96,27 @@ const DashboardSkeleton: React.FC = React.memo( /> )} - {isPerses ? ( - variables.length > 0 ? ( - - {t('Dashboard Variables')} - - - ) : null + {variables.length > 0 ? ( + + {t('Dashboard Variables')} + + + ) : null} + {perspective === 'dev' ? ( + + + + + + + ) : ( - + + + )} - {perspective === 'dev' && } @@ -127,5 +125,3 @@ const DashboardSkeleton: React.FC = React.memo( ); }, ); - -export default DashboardSkeleton; diff --git a/web/src/components/dashboards/shared/time-dropdowns.tsx b/web/src/components/dashboards/shared/time-dropdowns.tsx deleted file mode 100644 index 7e7597fd..00000000 --- a/web/src/components/dashboards/shared/time-dropdowns.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import * as React from 'react'; -import { useTranslation } from 'react-i18next'; -import { Stack, StackItem } from '@patternfly/react-core'; -import { TimeRangeControls } from '@perses-dev/plugin-system'; - -export const TimeDropdowns: React.FC = React.memo(() => { - const { t } = useTranslation(process.env.I18N_NAMESPACE); - - return ( - - - {t('Time Range Controls')} - - - - - - ); -}); diff --git a/web/src/reducers/observe.ts b/web/src/reducers/observe.ts index fcbe70d6..ee842056 100644 --- a/web/src/reducers/observe.ts +++ b/web/src/reducers/observe.ts @@ -14,7 +14,7 @@ import { getAlertsKey, getSilencesKey } from '../components/hooks/usePerspective import { MONITORING_DASHBOARDS_DEFAULT_TIMESPAN, MONITORING_DASHBOARDS_VARIABLE_ALL_OPTION_KEY, -} from '../components/dashboards/shared/utils'; +} from '../components/dashboards/legacy/utils'; export type ObserveState = ImmutableMap; From 1dda391a809e682345bedb4392be4967dfca9163 Mon Sep 17 00:00:00 2001 From: Gabriel Bernal Date: Tue, 1 Jul 2025 18:30:02 +0200 Subject: [PATCH 3/3] fix: patternfly 5 and import adjustments --- .../legacy/dashboard-skeleton-legacy.tsx | 7 +++-- .../legacy/legacy-dashboard-page.tsx | 2 +- .../dashboards/perses/perses-dashboards.tsx | 31 +++++-------------- 3 files changed, 12 insertions(+), 28 deletions(-) diff --git a/web/src/components/dashboards/legacy/dashboard-skeleton-legacy.tsx b/web/src/components/dashboards/legacy/dashboard-skeleton-legacy.tsx index b2bfadb3..b4473105 100644 --- a/web/src/components/dashboards/legacy/dashboard-skeleton-legacy.tsx +++ b/web/src/components/dashboards/legacy/dashboard-skeleton-legacy.tsx @@ -6,17 +6,18 @@ import { useTranslation } from 'react-i18next'; import { Divider, PageSection, + PageSectionVariants, Split, SplitItem, Stack, StackItem, Title, } from '@patternfly/react-core'; -import { usePerspective } from '../../hooks/usePerspective'; +import { usePerspective } from '../../../components/hooks/usePerspective'; import { CombinedDashboardMetadata } from '../perses/hooks/useDashboardsData'; import { DashboardDropdown } from '../shared/dashboard-dropdown'; -import { PollIntervalDropdown, TimespanDropdown } from './time-dropdowns'; import { LegacyDashboardsAllVariableDropdowns } from './legacy-variable-dropdowns'; +import { PollIntervalDropdown, TimespanDropdown } from './time-dropdowns'; const HeaderTop: React.FC = React.memo(() => { const { t } = useTranslation(process.env.I18N_NAMESPACE); @@ -66,7 +67,7 @@ export const DashboardSkeletonLegacy: React.FC{t('Metrics dashboards')} )} - + {perspective !== 'dev' && } {!_.isEmpty(boardItems) && ( diff --git a/web/src/components/dashboards/legacy/legacy-dashboard-page.tsx b/web/src/components/dashboards/legacy/legacy-dashboard-page.tsx index f4c04a6a..7a6398bf 100644 --- a/web/src/components/dashboards/legacy/legacy-dashboard-page.tsx +++ b/web/src/components/dashboards/legacy/legacy-dashboard-page.tsx @@ -2,7 +2,7 @@ import { Overview } from '@openshift-console/dynamic-plugin-sdk'; import * as React from 'react'; import { useTranslation } from 'react-i18next'; import { RouteComponentProps, withRouter } from 'react-router-dom'; -import { usePerspective } from 'src/components/hooks/usePerspective'; +import { usePerspective } from '../../../components/hooks/usePerspective'; import { LoadingInline } from '../../../components/console/console-shared/src/components/loading/LoadingInline'; import withFallback from '../../console/console-shared/error/fallbacks/withFallback'; import { LegacyDashboard } from '../legacy/legacy-dashboard'; diff --git a/web/src/components/dashboards/perses/perses-dashboards.tsx b/web/src/components/dashboards/perses/perses-dashboards.tsx index 2d38fe06..56e3f07a 100644 --- a/web/src/components/dashboards/perses/perses-dashboards.tsx +++ b/web/src/components/dashboards/perses/perses-dashboards.tsx @@ -1,7 +1,5 @@ -import React from 'react'; -import { combineSx } from '@perses-dev/components'; -import { Box } from '@mui/material'; import { Dashboard } from '@perses-dev/dashboards'; +import React from 'react'; import { useTranslation } from 'react-i18next'; /** @@ -17,27 +15,12 @@ function PersesBoard() { const { t } = useTranslation(process.env.I18N_NAMESPACE); return ( - - - - - + ); }