diff --git a/.betterer.results b/.betterer.results
index c9e38b92ea1..f6934188d82 100644
--- a/.betterer.results
+++ b/.betterer.results
@@ -2074,7 +2074,8 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings. Wrap text with ", "5"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "6"],
[0, 0, 0, "No untranslated strings. Wrap text with ", "7"],
- [0, 0, 0, "No untranslated strings. Wrap text with ", "8"]
+ [0, 0, 0, "No untranslated strings. Wrap text with ", "8"],
+ [0, 0, 0, "No untranslated strings. Wrap text with ", "9"]
],
"public/app/features/dashboard-scene/saving/SaveProvisionedDashboardForm.tsx:5381": [
[0, 0, 0, "No untranslated strings. Wrap text with ", "0"],
diff --git a/public/app/features/dashboard-scene/saving/SaveDashboardDrawer.tsx b/public/app/features/dashboard-scene/saving/SaveDashboardDrawer.tsx
index 2069179469b..5f12ce0c39e 100644
--- a/public/app/features/dashboard-scene/saving/SaveDashboardDrawer.tsx
+++ b/public/app/features/dashboard-scene/saving/SaveDashboardDrawer.tsx
@@ -19,6 +19,7 @@ interface SaveDashboardDrawerState extends SceneObjectState {
saveRefresh?: boolean;
saveAsCopy?: boolean;
onSaveSuccess?: () => void;
+ saveProvisioned?: boolean;
}
export class SaveDashboardDrawer extends SceneObjectBase {
@@ -39,7 +40,7 @@ export class SaveDashboardDrawer extends SceneObjectBase) => {
- const { showDiff, saveAsCopy, saveTimeRange, saveVariables, saveRefresh } = model.useState();
+ const { saveProvisioned, showDiff, saveAsCopy, saveTimeRange, saveVariables, saveRefresh } = model.useState();
const changeInfo = getDashboardChangesFromScene(
model.state.dashboardRef.resolve(),
saveTimeRange,
@@ -51,9 +52,8 @@ export class SaveDashboardDrawer extends SceneObjectBase
diff --git a/public/app/features/dashboard-scene/saving/SaveProvisionedDashboard.tsx b/public/app/features/dashboard-scene/saving/SaveProvisionedDashboard.tsx
index 56b68d7dcf3..35a777b8889 100644
--- a/public/app/features/dashboard-scene/saving/SaveProvisionedDashboard.tsx
+++ b/public/app/features/dashboard-scene/saving/SaveProvisionedDashboard.tsx
@@ -1,13 +1,29 @@
import { useEffect } from 'react';
import { Controller, useForm } from 'react-hook-form';
+import { useNavigate } from 'react-router-dom-v5-compat';
import { AppEvents } from '@grafana/data';
import { getAppEvents } from '@grafana/runtime';
-import { Alert, Button, Field, Input, LinkButton, RadioButtonGroup, Stack, TextArea } from '@grafana/ui';
+import {
+ Alert,
+ Button,
+ Field,
+ Input,
+ LinkButton,
+ RadioButtonGroup,
+ Spinner,
+ Stack,
+ TextArea,
+ TextLink,
+} from '@grafana/ui';
import { AnnoKeyRepoName, AnnoKeyRepoPath } from 'app/features/apiserver/types';
import { DashboardMeta } from 'app/types';
-import { useGetRepositoryQuery, useUpdateRepositoryFilesMutation } from '../../provisioning/api';
+import { RepositorySelect } from '../../provisioning/RepositorySelect';
+import { useGetRepositoryQuery } from '../../provisioning/api';
+import { RepositorySpec } from '../../provisioning/api/types';
+import { PROVISIONING_URL } from '../../provisioning/constants';
+import { useCreateOrUpdateRepositoryFile, usePullRequestParam } from '../../provisioning/hooks';
import { WorkflowOption } from '../../provisioning/types';
import { createPRLink, validateBranchName } from '../../provisioning/utils/git';
import { DashboardScene } from '../scene/DashboardScene';
@@ -27,7 +43,7 @@ type FormData = {
function getDefaultValues(meta: DashboardMeta) {
const anno = meta.k8s?.annotations;
let ref = '';
- let path = anno?.[AnnoKeyRepoPath] ?? '';
+ let path = anno?.[AnnoKeyRepoPath] ?? `${meta.slug}.json` ?? '';
const repo = anno?.[AnnoKeyRepoName] ?? '';
const idx = path.indexOf('#');
if (idx > 0) {
@@ -42,6 +58,10 @@ function getDefaultValues(meta: DashboardMeta) {
};
}
+const getDefaultWorkflow = (config?: RepositorySpec) => {
+ return config?.github?.branchWorkflow ? WorkflowOption.Branch : WorkflowOption.PullRequest;
+};
+
function getWorkflowOptions(branch = 'main') {
return [
{ label: `Commit to ${branch}`, value: WorkflowOption.Branch },
@@ -57,26 +77,31 @@ export interface Props {
}
export function SaveProvisionedDashboard({ meta, drawer, changeInfo, dashboard }: Props) {
- const [saveDashboard, request] = useUpdateRepositoryFilesMutation();
+ // Saving as a new provisioned dashboard
+ const { saveProvisioned } = drawer.useState();
+ const prURL = usePullRequestParam();
const defaultValues = getDefaultValues(meta);
- const repositoryConfigQuery = useGetRepositoryQuery({ name: defaultValues.repo });
- const repositoryConfig = repositoryConfigQuery?.data?.spec;
- const isGitHub = repositoryConfig?.type === 'github';
+ const [action, request] = useCreateOrUpdateRepositoryFile(saveProvisioned ? undefined : defaultValues.path);
const {
register,
handleSubmit,
watch,
formState: { errors },
control,
+ setValue,
} = useForm({
defaultValues: {
...defaultValues,
- workflow: repositoryConfig?.github?.branchWorkflow ? WorkflowOption.Branch : WorkflowOption.PullRequest,
+ workflow: WorkflowOption.PullRequest,
},
});
- const [repo, ref, workflow] = watch(['repo', 'ref', 'workflow']);
+ const [repo, ref, workflow, path] = watch(['repo', 'ref', 'workflow', 'path']);
+ const repositoryConfigQuery = useGetRepositoryQuery({ name: repo });
+ const repositoryConfig = repositoryConfigQuery?.data?.spec;
+ const isGitHub = repositoryConfig?.type === 'github';
const href = createPRLink(repositoryConfig, repo, ref);
const { isDirty } = dashboard.state;
+ const navigate = useNavigate();
useEffect(() => {
const appEvents = getAppEvents();
@@ -86,13 +111,21 @@ export function SaveProvisionedDashboard({ meta, drawer, changeInfo, dashboard }
payload: ['Dashboard saved'],
});
dashboard.setState({ isDirty: false });
+
+ if (saveProvisioned) {
+ navigate(`${PROVISIONING_URL}/${repo}/dashboard/preview/${path}?ref=${ref}`);
+ }
} else if (request.isError) {
appEvents.publish({
type: AppEvents.alertError.name,
payload: ['Error saving dashboard', request.error],
});
}
- }, [request.isSuccess, request.isError, request.error, dashboard]);
+ }, [request.isSuccess, request.isError, request.error, dashboard, path, saveProvisioned, navigate, repo, ref]);
+
+ useEffect(() => {
+ setValue('workflow', getDefaultWorkflow(repositoryConfig));
+ }, [repositoryConfig, setValue]);
const doSave = ({ ref, path, comment, repo }: FormData) => {
if (!repo || !path) {
@@ -102,9 +135,16 @@ export function SaveProvisionedDashboard({ meta, drawer, changeInfo, dashboard }
if (workflow === WorkflowOption.Branch) {
ref = repositoryConfig?.github?.branch || 'main';
}
- saveDashboard({ ref, name: repo, path, message: comment, body: changeInfo.changedSaveModel });
+ action({ ref, name: repo, path, message: comment, body: changeInfo.changedSaveModel });
};
+ if (repositoryConfigQuery.isLoading) {
+ return (
+
+
+
+ );
+ }
return (