Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 3 additions & 4 deletions web/src/components/dashboards/perses/dashboard-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import * as React from 'react';
import { QueryParamProvider } from 'use-query-params';
import { ReactRouter5Adapter } from 'use-query-params/adapters/react-router-5';
import withFallback from '../../console/console-shared/error/fallbacks/withFallback';
import { LoadingInline } from '../../console/console-shared/src/components/loading/LoadingInline';
import DashboardSkeleton from '../shared/dashboard-skeleton';
import { PersesContext } from '../shared/useIsPerses';
Expand All @@ -27,13 +26,13 @@ const MonitoringDashboardsPage_: React.FC = () => {
const {
changeBoard,
activeProjectDashboardsMetadata,
combinedIntialLoad,
combinedInitialLoad,
activeProject,
setActiveProject,
dashboardName,
} = useDashboardsData();

if (combinedIntialLoad) {
if (combinedInitialLoad) {
return <LoadingInline />;
}

Expand Down Expand Up @@ -74,4 +73,4 @@ const MonitoringDashboardsPageWrapper: React.FC = () => {
);
};

export default withFallback(MonitoringDashboardsPageWrapper);
export default MonitoringDashboardsPageWrapper;
32 changes: 17 additions & 15 deletions web/src/components/dashboards/perses/hooks/useDashboardsData.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import * as React from 'react';

import { usePerses } from './usePerses';
import { getDashboardsUrl, usePerspective } from '../../../hooks/usePerspective';
import { getAllQueryArguments } from '../../../console/utils/router';
import { DashboardResource } from '@perses-dev/core';
import { useNavigate } from 'react-router-dom-v5-compat';
import { useActiveProject } from '../project/useActiveProject';
import { StringParam, useQueryParam } from 'use-query-params';
import { getAllQueryArguments } from '../../../console/utils/router';
import { useBoolean } from '../../../hooks/useBoolean';
import { getDashboardsUrl, usePerspective } from '../../../hooks/usePerspective';
import { QueryParams } from '../../../query-params';
import { StringParam, useQueryParam } from 'use-query-params';
import { useActiveProject } from '../project/useActiveProject';
import { usePerses } from './usePerses';

// This hook syncs with mutliple external API's, redux, and URL state. Its a lot, but needs to all
// be in a single location
Expand All @@ -27,7 +28,7 @@ export const useDashboardsData = () => {
const [dashboardName] = useQueryParam(QueryParams.Dashboard, StringParam);

// Determine when to stop having the full page loader be used
const combinedIntialLoad = React.useMemo(() => {
const combinedInitialLoad = React.useMemo(() => {
if (!initialPageLoad) {
return false;
}
Expand All @@ -41,22 +42,22 @@ export const useDashboardsData = () => {
// Homogenize data needed for dashboards dropdown between legacy and perses dashboards
// to enable both to use the same component
const combinedDashboardsMetadata = React.useMemo<CombinedDashboardMetadata[]>(() => {
if (combinedIntialLoad) {
if (combinedInitialLoad) {
return [];
}
return persesDashboards.map((persesDashboard) => {
// Locate display name of project
const matchingProject = persesProjects.find(
(persesProject) => persesProject?.metadata?.name === persesDashboard?.metadata?.project,
);
const name = persesDashboard?.metadata?.name;
const displayName = persesDashboard?.spec?.display?.name || name;

return {
name: persesDashboard?.metadata?.name,
name,
project: persesDashboard?.metadata?.project,
tags: ['perses'],
title: `${matchingProject.spec?.display?.name} / ${persesDashboard?.spec?.display?.name}`,
title: displayName,
persesDashboard,
};
});
}, [persesDashboards, persesProjects, combinedIntialLoad]);
}, [persesDashboards, combinedInitialLoad]);

// Retrieve dashboard metadata for the currently selected project
const activeProjectDashboardsMetadata = React.useMemo<CombinedDashboardMetadata[]>(() => {
Expand Down Expand Up @@ -109,7 +110,7 @@ export const useDashboardsData = () => {
dashboardName,
changeBoard,
activeProjectDashboardsMetadata,
combinedIntialLoad,
combinedInitialLoad,
setActiveProject,
activeProject,
};
Expand All @@ -120,4 +121,5 @@ export type CombinedDashboardMetadata = {
project?: string;
tags: string[];
title: string;
persesDashboard?: DashboardResource;
};
139 changes: 74 additions & 65 deletions web/src/components/dashboards/shared/dashboard-skeleton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
Title,
} from '@patternfly/react-core';
import { TimeRangeControls } from '@perses-dev/plugin-system';
import { DashboardStickyToolbar } from '@perses-dev/dashboards';
import { DashboardStickyToolbar, useDashboardActions } from '@perses-dev/dashboards';

const HeaderTop: React.FC = React.memo(() => {
const { t } = useTranslation(process.env.I18N_NAMESPACE);
Expand Down Expand Up @@ -47,71 +47,80 @@ type MonitoringDashboardsPageProps = React.PropsWithChildren<{
dashboardName: string;
}>;

const DashboardSkeleton: React.FC<MonitoringDashboardsPageProps> = ({
children,
boardItems,
changeBoard,
dashboardName,
}) => {
const { t } = useTranslation(process.env.I18N_NAMESPACE);
const isPerses = useIsPerses();
const DashboardSkeleton: React.FC<MonitoringDashboardsPageProps> = React.memo(
({ children, boardItems, changeBoard, dashboardName }) => {
const { t } = useTranslation(process.env.I18N_NAMESPACE);
const isPerses = useIsPerses();

const { perspective } = usePerspective();
const { perspective } = usePerspective();
const { setDashboard } = useDashboardActions();

return (
<>
{perspective !== 'dev' && (
<Helmet>
<title>{t('Metrics dashboards')}</title>
</Helmet>
)}
<PageSection hasBodyWrapper={false}>
{perspective !== 'dev' && <HeaderTop />}
<Stack hasGutter>
{!_.isEmpty(boardItems) && (
<StackItem>
<DashboardDropdown
items={boardItems}
onChange={changeBoard}
selectedKey={dashboardName}
/>
</StackItem>
)}
{isPerses ? (
<StackItem>
<b> {t('Dashboard Variables')} </b>
<DashboardStickyToolbar initialVariableIsSticky={false} />
</StackItem>
) : (
<StackItem>
<LegacyDashboardsAllVariableDropdowns key={dashboardName} />
</StackItem>
)}
{perspective === 'dev' ? (
<StackItem>
<Split hasGutter>
<SplitItem isFilled />
<SplitItem>
<TimespanDropdown />
</SplitItem>
<SplitItem>
<PollIntervalDropdown />
</SplitItem>
</Split>
</StackItem>
) : (
<StackItem>
<Split>
<SplitItem isFilled />
</Split>
</StackItem>
)}
</Stack>
</PageSection>
<Divider />
{children}
</>
);
};
const onChangeBoard = (selectedDashboard: string) => {
changeBoard(selectedDashboard);

if (isPerses) {
const selectedBoard = boardItems.find((item) => item.name === selectedDashboard);
if (selectedBoard) {
setDashboard(selectedBoard.persesDashboard);
}
}
};

return (
<>
{perspective !== 'dev' && (
<Helmet>
<title>{t('Metrics dashboards')}</title>
</Helmet>
)}
<PageSection hasBodyWrapper={false}>
{perspective !== 'dev' && <HeaderTop />}
<Stack hasGutter>
{!_.isEmpty(boardItems) && (
<StackItem>
<DashboardDropdown
items={boardItems}
onChange={onChangeBoard}
selectedKey={dashboardName}
/>
</StackItem>
)}
{isPerses ? (
<StackItem>
<b> {t('Dashboard Variables')} </b>
<DashboardStickyToolbar initialVariableIsSticky={false} />
</StackItem>
) : (
<StackItem>
<LegacyDashboardsAllVariableDropdowns key={dashboardName} />
</StackItem>
)}
{perspective === 'dev' ? (
<StackItem>
<Split hasGutter>
<SplitItem isFilled />
<SplitItem>
<TimespanDropdown />
</SplitItem>
<SplitItem>
<PollIntervalDropdown />
</SplitItem>
</Split>
</StackItem>
) : (
<StackItem>
<Split>
<SplitItem isFilled />
</Split>
</StackItem>
)}
</Stack>
</PageSection>
<Divider />
{children}
</>
);
},
);

export default DashboardSkeleton;