Skip to content
Open
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
66 changes: 41 additions & 25 deletions web/src/components/dashboards/perses/PersesWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -356,13 +356,9 @@ export function PersesWrapper({ children, project }: PersesWrapperProps) {
content=""
>
<PluginRegistry pluginLoader={pluginLoader}>
{!project ? (
<>{children}</>
) : (
<InnerWrapper project={project} dashboardName={dashboardName}>
{children}
</InnerWrapper>
)}
<InnerWrapper project={project} dashboardName={dashboardName}>
{children}
</InnerWrapper>
</PluginRegistry>
</SnackbarProvider>
</ChartsProvider>
Expand All @@ -379,6 +375,31 @@ function InnerWrapper({ children, project, dashboardName }) {
const DEFAULT_DASHBOARD_DURATION = '30m';
const DEFAULT_REFRESH_INTERVAL = '0s';

// Always have a dashboard resource to prevent context issues
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this is the right approach. The issue is that the providers should not load if there is no dashboard or is loading. This code is also like this in the coo-0.5 branch. So I'd assume we have the same issue there.

const effectiveDashboard: DashboardResource = React.useMemo(() => {
if (persesDashboard) {
return persesDashboard;
}
// Create a temporary dashboard when the real one isn't available
return {
kind: 'Dashboard' as const,
metadata: {
name: 'loading',
project: null,
version: 0,
},
spec: {
display: { name: 'Loading...' },
datasources: {},
panels: {},
layouts: [],
variables: [],
duration: '1h',
refreshInterval: '30s',
},
};
}, [persesDashboard]);

const dashboardDuration = persesDashboard?.spec?.duration;
const dashboardTimeInterval = persesDashboard?.spec?.refreshInterval;

Expand Down Expand Up @@ -423,32 +444,27 @@ function InnerWrapper({ children, project, dashboardName }) {
return result;
}, [data, project, dashboardName]);

if (persesDashboardLoading) {
return <LoadingBox />;
}

return (
<TimeRangeProviderWithQueryParams
initialTimeRange={initialTimeRange}
initialRefreshInterval={initialRefreshInterval}
>
<VariableProviderWithQueryParams
builtinVariableDefinitions={builtinVariables}
initialVariableDefinitions={persesDashboard?.spec?.variables}
key={persesDashboard?.metadata.name}
initialVariableDefinitions={effectiveDashboard?.spec?.variables}
key={effectiveDashboard.metadata.name}
>
<PersesPrometheusDatasourceWrapper queries={[]} dashboardResource={persesDashboard}>
{persesDashboard ? (
<DashboardProvider
initialState={{
dashboardResource: persesDashboard,
}}
>
<ValidationProvider>{children}</ValidationProvider>
</DashboardProvider>
) : (
<>{children}</>
)}
<PersesPrometheusDatasourceWrapper queries={[]} dashboardResource={effectiveDashboard}>
<DashboardProvider
initialState={{
dashboardResource: effectiveDashboard,
}}
key={effectiveDashboard.metadata.name}
>
<ValidationProvider>
{persesDashboardLoading ? <LoadingBox /> : children}
</ValidationProvider>
</DashboardProvider>
</PersesPrometheusDatasourceWrapper>
</VariableProviderWithQueryParams>
</TimeRangeProviderWithQueryParams>
Expand Down
63 changes: 52 additions & 11 deletions web/src/components/dashboards/perses/dashboard-page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,15 @@ import { OCPDashboardApp } from './dashboard-app';
import { DashboardFrame } from './dashboard-frame';
import { ProjectEmptyState } from './emptystates/ProjectEmptyState';
import { useDashboardsData } from './hooks/useDashboardsData';
import {
Bullseye,
EmptyState,
EmptyStateBody,
EmptyStateHeader,
EmptyStateIcon,
Spinner,
} from '@patternfly/react-core';
import { SearchIcon } from '@patternfly/react-icons';

const queryClient = new QueryClient({
defaultOptions: {
Expand All @@ -19,6 +28,39 @@ const queryClient = new QueryClient({
},
});

export const EmptyStateSpinner: React.FunctionComponent = () => (
<Bullseye>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is different from what we have in the coo-0.5 branch. If we are going to adjust we need to adjust there as well.

<EmptyState>
<EmptyStateHeader
titleText="Loading"
headingLevel="h4"
icon={<EmptyStateIcon icon={Spinner} />}
/>
</EmptyState>
</Bullseye>
);

interface EmptyStateNoMatchFoundProps {
headerMsg: string;
bodyMsg: string;
}

export const EmptyStateNoMatchFound: React.FunctionComponent<EmptyStateNoMatchFoundProps> = ({
headerMsg,
bodyMsg,
}) => (
<Bullseye>
<EmptyState>
<EmptyStateHeader
titleText={headerMsg}
headingLevel="h4"
icon={<EmptyStateIcon icon={SearchIcon} />}
/>
<EmptyStateBody>{bodyMsg}</EmptyStateBody>
</EmptyState>
</Bullseye>
);

const DashboardPage_: React.FC = () => {
const { t } = useTranslation(process.env.I18N_NAMESPACE);
const location = useLocation();
Expand Down Expand Up @@ -65,17 +107,16 @@ const DashboardPage_: React.FC = () => {
);

if (!currentDashboard) {
return (
<div style={{ padding: '2rem' }}>
<h2>{t('Dashboard not found')}</h2>
<p>
{t('The dashboard "{{name}}" was not found in project "{{project}}".', {
name: targetDashboardName,
project: activeProject || urlProject,
})}
</p>
</div>
);
const headerMsg = t('Dashboard not found');
const bodyMsg = t('The dashboard "{{name}}" was not found in project "{{project}}".', {
name: targetDashboardName,
project: activeProject || urlProject,
});
return <EmptyStateNoMatchFound headerMsg={headerMsg} bodyMsg={bodyMsg} />;
}

if (!currentDashboard.persesDashboard) {
return <EmptyStateSpinner />;
}

return (
Expand Down