diff --git a/public/app/features/dashboard-scene/pages/DashboardScenePage.tsx b/public/app/features/dashboard-scene/pages/DashboardScenePage.tsx index 83e72d3b1ca..3303244cb22 100644 --- a/public/app/features/dashboard-scene/pages/DashboardScenePage.tsx +++ b/public/app/features/dashboard-scene/pages/DashboardScenePage.tsx @@ -14,6 +14,7 @@ import { DashboardPageRouteParams, DashboardPageRouteSearchParams } from 'app/fe import { DashboardRoutes } from 'app/types'; import { DashboardPrompt } from '../saving/DashboardPrompt'; +import { DashboardPreviewBanner } from '../saving/provisioned/DashboardPreviewBanner'; import { getDashboardScenePageStateManager } from './DashboardScenePageStateManager'; @@ -76,6 +77,7 @@ export function DashboardScenePage({ route, queryParams, location }: Props) { return ( + diff --git a/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.ts b/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.ts index 2bd41da5e4f..ddb7496795e 100644 --- a/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.ts +++ b/public/app/features/dashboard-scene/pages/DashboardScenePageStateManager.ts @@ -61,8 +61,8 @@ interface DashboardCacheEntry { export interface LoadDashboardOptions { uid: string; route: DashboardRoutes; - type?: string; slug?: string; + type?: string; urlFolderUid?: string; params?: { version: number; diff --git a/public/app/features/dashboard-scene/saving/provisioned/DashboardPreviewBanner.tsx b/public/app/features/dashboard-scene/saving/provisioned/DashboardPreviewBanner.tsx new file mode 100644 index 00000000000..f96bcbfd1b4 --- /dev/null +++ b/public/app/features/dashboard-scene/saving/provisioned/DashboardPreviewBanner.tsx @@ -0,0 +1,119 @@ +import { config } from '@grafana/runtime'; +import { Alert, Icon, Stack } from '@grafana/ui'; +import { useGetRepositoryFilesWithPathQuery } from 'app/api/clients/provisioning'; +import { t, Trans } from 'app/core/internationalization'; +import { DashboardPageRouteSearchParams } from 'app/features/dashboard/containers/types'; +import { usePullRequestParam } from 'app/features/provisioning/hooks/usePullRequestParam'; +import { DashboardRoutes } from 'app/types'; + +interface CommonBannerProps { + queryParams: DashboardPageRouteSearchParams; + path?: string; + slug?: string; +} + +interface DashboardPreviewBannerProps extends CommonBannerProps { + route?: string; +} + +interface DashboardPreviewBannerContentProps extends Required> {} + +const commonAlertProps = { + severity: 'info' as const, + style: { flex: 0 } as const, +}; + +function DashboardPreviewBannerContent({ queryParams, slug, path }: DashboardPreviewBannerContentProps) { + const prParam = usePullRequestParam(); + const file = useGetRepositoryFilesWithPathQuery({ name: slug, path, ref: queryParams.ref }); + + if (file.data?.errors) { + return ( + + {file.data.errors.map((error, index) => ( +
{error}
+ ))} +
+ ); + } + + // This page was loaded with a `pull_request_url` in the URL + if (prParam?.length) { + return ( + + + View pull request in GitHub + + + + } + onRemove={() => window.open(prParam, '_blank')} + > + + The value is not yet saved in the Grafana database + + + ); + } + + // Check if this is a GitHub link + const githubURL = file.data?.urls?.newPullRequestURL ?? file.data?.urls?.compareURL; + if (githubURL) { + return ( + + + Open pull request in GitHub + + + + } + onRemove={() => window.open(githubURL, '_blank')} + > + + The value is not yet saved in the Grafana database + + + ); + } + + return ( + + + The value is not saved in the Grafana database + + + ); +} + +export function DashboardPreviewBanner({ queryParams, route, slug, path }: DashboardPreviewBannerProps) { + const provisioningEnabled = config.featureToggles.provisioning; + if (!provisioningEnabled || 'kiosk' in queryParams || !path || route !== DashboardRoutes.Provisioning || !slug) { + return null; + } + + return ; +} diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index 910818911ef..9e12bd9e2c1 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -1438,6 +1438,17 @@ "it-cannot-contain-or": "It cannot contain '//' or '..'.", "least-valid-character": "It must have at least one valid character." }, + "dashboard-preview-banner": { + "not-saved": "The value is not yet saved in the Grafana database", + "not-yet-saved": "The value is not saved in the Grafana database", + "open-pull-request-in-git-hub": "Open pull request in GitHub", + "title-dashboard-loaded-branch-git-hub": "This dashboard is loaded from a branch in GitHub.", + "title-dashboard-loaded-external-repository": "This dashboard is loaded from an external repository", + "title-dashboard-loaded-request-git-hub": "This dashboard is loaded from a pull request in GitHub.", + "title-error-loading-dashboard": "Error loading dashboard", + "value-not-saved": "The value is not yet saved in the Grafana database", + "view-pull-request-in-git-hub": "View pull request in GitHub" + }, "provisioned-resource-delete-modal": { "file-path": "File path:", "managed-by-version-control": "This {type} is managed by version control and cannot be deleted. To remove it, delete it from the repository and synchronise to apply the changes.",