Provisioning: Redirect to the new URL after save (#101757)

Co-authored-by: Alex Khomenko <Clarity-89@users.noreply.github.com>
pull/101857/head
Ryan McKinley 5 months ago committed by GitHub
parent 67eff1e898
commit c6435dc5c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 7
      .betterer.results
  2. 15
      public/app/features/dashboard-scene/saving/provisioned/SaveProvisionedDashboard.test.tsx
  3. 33
      public/app/features/dashboard-scene/saving/provisioned/SaveProvisionedDashboard.tsx
  4. 15
      public/app/features/dashboard-scene/scene/DashboardScene.tsx

@ -3280,7 +3280,7 @@ exports[`better eslint`] = {
],
"public/app/features/dashboard-scene/saving/provisioned/SaveProvisionedDashboard.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "1"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "2"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "3"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "4"],
@ -3292,14 +3292,15 @@ exports[`better eslint`] = {
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "10"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "11"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "12"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "13"],
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "13"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "14"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "15"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "16"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "17"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "18"],
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "19"],
[0, 0, 0, "Unexpected any. Specify a different type.", "20"]
[0, 0, 0, "No untranslated strings. Wrap text with <Trans />", "20"],
[0, 0, 0, "Unexpected any. Specify a different type.", "21"]
],
"public/app/features/dashboard-scene/saving/shared.tsx:5381": [
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"],

@ -4,7 +4,6 @@ import userEvent from '@testing-library/user-event';
import { AppEvents } from '@grafana/data';
import { getAppEvents, locationService } from '@grafana/runtime';
import { Dashboard } from '@grafana/schema';
import { ManagerKind } from 'app/features/apiserver/types';
import { validationSrv } from 'app/features/manage-dashboards/services/ValidationSrv';
import { useCreateOrUpdateRepositoryFile } from 'app/features/provisioning/hooks';
@ -152,6 +151,14 @@ function setup(props: Partial<Props> = {}) {
};
}
const mockRequestBase = {
isSuccess: true,
isError: false,
isLoading: false,
error: null,
data: { resource: { upsert: {} } },
};
describe('SaveProvisionedDashboard', () => {
beforeEach(() => {
jest.clearAllMocks();
@ -188,6 +195,7 @@ describe('SaveProvisionedDashboard', () => {
// Mock useCreateOrUpdateRepositoryFile
const mockAction = jest.fn();
const mockRequest = {
...mockRequestBase,
isSuccess: true,
isError: false,
isLoading: false,
@ -256,6 +264,7 @@ describe('SaveProvisionedDashboard', () => {
const mockAction = jest.fn();
const mockRequest = {
...mockRequestBase,
isSuccess: true,
isError: false,
isLoading: false,
@ -297,8 +306,6 @@ describe('SaveProvisionedDashboard', () => {
// Check if the action was called
expect(mockAction).toHaveBeenCalled();
});
// Check if manager was set
expect(props.dashboard.setManager).toHaveBeenCalledWith(ManagerKind.Repo, 'test-repo');
// Check if success alert was published
const appEvents = getAppEvents();
@ -362,6 +369,7 @@ describe('SaveProvisionedDashboard', () => {
const mockAction = jest.fn();
const mockRequest = {
...mockRequestBase,
isSuccess: true,
isError: false,
isLoading: false,
@ -419,6 +427,7 @@ describe('SaveProvisionedDashboard', () => {
const mockAction = jest.fn();
const mockRequest = {
...mockRequestBase,
isSuccess: false,
isError: true,
isLoading: false,

@ -2,12 +2,14 @@ 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 { AppEvents, locationUtil } from '@grafana/data';
import { getAppEvents, locationService } from '@grafana/runtime';
import { Dashboard } from '@grafana/schema/dist/esm/raw/dashboard/x/dashboard_types.gen';
import { Alert, Button, Field, Input, RadioButtonGroup, Stack, TextArea } from '@grafana/ui';
import { FolderPicker } from 'app/core/components/Select/FolderPicker';
import { useUrlParams } from 'app/core/navigation/hooks';
import { AnnoKeyManagerIdentity, ManagerKind } from 'app/features/apiserver/types';
import kbn from 'app/core/utils/kbn';
import { AnnoKeyManagerIdentity, Resource } from 'app/features/apiserver/types';
import { validationSrv } from 'app/features/manage-dashboards/services/ValidationSrv';
import { RepositoryView } from 'app/features/provisioning/api';
import { PROVISIONING_URL } from 'app/features/provisioning/constants';
@ -16,6 +18,7 @@ import { WorkflowOption } from 'app/features/provisioning/types';
import { validateBranchName } from 'app/features/provisioning/utils/git';
import { DashboardScene } from '../../scene/DashboardScene';
import { getDashboardUrl } from '../../utils/getDashboardUrl';
import { SaveDashboardDrawer } from '../SaveDashboardDrawer';
import { SaveDashboardFormCommonOptions } from '../SaveDashboardForm';
import { DashboardChangeInfo } from '../shared';
@ -72,23 +75,38 @@ export function SaveProvisionedDashboard({ drawer, changeInfo, dashboard }: Prop
const appEvents = getAppEvents();
if (request.isSuccess) {
dashboard.setState({ isDirty: false });
if (isNew) {
dashboard.setManager(ManagerKind.Repo, defaultValues.repo);
}
if (workflow === 'branch' && ref !== '' && path !== '') {
// Redirect to the provisioning preview pages
navigate(`${PROVISIONING_URL}/${defaultValues.repo}/dashboard/preview/${path}?ref=${ref}`);
} else {
return;
}
appEvents.publish({
type: AppEvents.alertSuccess.name,
payload: ['Dashboard changes saved'],
});
// Load the new URL
const upsert = request.data.resource.upsert as Resource<Dashboard>;
if (isNew && upsert?.metadata?.name) {
const url = locationUtil.assureBaseUrl(
getDashboardUrl({
uid: upsert.metadata.name,
slug: kbn.slugifyForUrl(upsert.spec.title ?? ''),
currentQueryParams: window.location.search,
})
);
navigate(url);
return;
}
// Keep the same URL
dashboard.closeModal();
locationService.partial({
viewPanel: null,
editPanel: null,
});
}
} else if (request.isError) {
appEvents.publish({
type: AppEvents.alertError.name,
@ -99,6 +117,7 @@ export function SaveProvisionedDashboard({ drawer, changeInfo, dashboard }: Prop
request.isSuccess,
request.isError,
request.error,
request.data,
dashboard,
workflow,
isNew,

@ -42,7 +42,7 @@ import { VariablesChanged } from 'app/features/variables/types';
import { DashboardDTO, DashboardMeta, KioskMode, SaveDashboardResponseDTO } from 'app/types';
import { ShowConfirmModalEvent } from 'app/types/events';
import { AnnoKeyManagerIdentity, AnnoKeyManagerKind, AnnoKeySourcePath, ManagerKind } from '../../apiserver/types';
import { AnnoKeyManagerKind, AnnoKeySourcePath, ManagerKind } from '../../apiserver/types';
import { DashboardEditPane } from '../edit-pane/DashboardEditPane';
import { PanelEditor } from '../panel-edit/PanelEditor';
import { DashboardSceneChangeTracker } from '../saving/DashboardSceneChangeTracker';
@ -777,19 +777,6 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> impleme
getPath() {
return this.state.meta.k8s?.annotations?.[AnnoKeySourcePath];
}
setManager(kind: ManagerKind, id: string) {
this.setState({
meta: {
k8s: {
annotations: {
[AnnoKeyManagerKind]: kind,
[AnnoKeyManagerIdentity]: id,
},
},
},
});
}
}
export class DashboardVariableDependency implements SceneVariableDependencyConfigLike {

Loading…
Cancel
Save