diff --git a/pkg/services/dashboards/errors.go b/pkg/services/dashboards/errors.go
index af11c84f652..93f6b1152e0 100644
--- a/pkg/services/dashboards/errors.go
+++ b/pkg/services/dashboards/errors.go
@@ -70,6 +70,10 @@ var (
Reason: "uid too long, max 40 characters",
StatusCode: 400,
}
+ ErrDashboardMessageTooLong = DashboardErr{
+ Reason: "message too long, max 500 characters",
+ StatusCode: 400,
+ }
ErrDashboardCannotSaveProvisionedDashboard = DashboardErr{
Reason: "Cannot save provisioned dashboard",
StatusCode: 400,
diff --git a/pkg/services/dashboards/service/dashboard_service.go b/pkg/services/dashboards/service/dashboard_service.go
index 77df8b33da7..037cf3b53d0 100644
--- a/pkg/services/dashboards/service/dashboard_service.go
+++ b/pkg/services/dashboards/service/dashboard_service.go
@@ -353,6 +353,10 @@ func (dr *DashboardServiceImpl) BuildSaveDashboardCommand(ctx context.Context, d
return nil, dashboards.ErrDashboardTitleEmpty
}
+ if len(dto.Message) > 500 {
+ return nil, dashboards.ErrDashboardMessageTooLong
+ }
+
metrics.MFolderIDsServiceCount.WithLabelValues(metrics.Dashboard).Inc()
// nolint:staticcheck
if dash.IsFolder && dash.FolderID > 0 {
diff --git a/pkg/services/dashboards/service/dashboard_service_test.go b/pkg/services/dashboards/service/dashboard_service_test.go
index cada629f1d5..eff505300b6 100644
--- a/pkg/services/dashboards/service/dashboard_service_test.go
+++ b/pkg/services/dashboards/service/dashboard_service_test.go
@@ -67,6 +67,22 @@ func TestDashboardService(t *testing.T) {
}
})
+ t.Run("Should return validation error if message is too long", func(t *testing.T) {
+ dto.Dashboard = dashboards.NewDashboard("Dash")
+ dto.Message = `Here we go, 500+ characters for testing. I'm sorry that you're
+ having to read this. I spent too long trying to come up with something clever
+ to say or a funny joke. Unforuntately, nothing came to mind. So instead, I'm
+ will share this with you, as a form of payment for having to read this:
+ https://youtu.be/dQw4w9WgXcQ?si=KeoTIpn9tUtQnOBk! Enjoy :) Now lets see if
+ this test passes or if the result is more exciting than these 500 characters
+ I wrote. Best of luck to the both of us!`
+ _, err := service.SaveDashboard(context.Background(), dto, false)
+ require.Equal(t, err, dashboards.ErrDashboardMessageTooLong)
+
+ // set to a shorter message for the rest of the tests
+ dto.Message = `message`
+ })
+
t.Run("Should return validation error if folder is named General", func(t *testing.T) {
dto.Dashboard = dashboards.NewDashboardFolder("General")
_, err := service.SaveDashboard(context.Background(), dto, false)
diff --git a/public/app/features/dashboard-scene/saving/SaveDashboardForm.tsx b/public/app/features/dashboard-scene/saving/SaveDashboardForm.tsx
index 39933216aa8..7845c4b8ee8 100644
--- a/public/app/features/dashboard-scene/saving/SaveDashboardForm.tsx
+++ b/public/app/features/dashboard-scene/saving/SaveDashboardForm.tsx
@@ -2,6 +2,7 @@ import { useState } from 'react';
import { selectors } from '@grafana/e2e-selectors';
import { Button, Checkbox, TextArea, Stack, Alert, Box, Field } from '@grafana/ui';
+import { Trans, t } from 'app/core/internationalization';
import { SaveDashboardOptions } from 'app/features/dashboard/components/SaveDashboard/types';
import { DashboardScene } from '../scene/DashboardScene';
@@ -49,7 +50,26 @@ export function SaveDashboardForm({ dashboard, drawer, changeInfo }: Props) {
);
+ const isMessageTooLongError = (message?: string) => {
+ return message && message.length > 500;
+ };
+
function renderFooter(error?: Error) {
+ if (isMessageTooLongError(options.message)) {
+ const messageLength = options.message?.length ?? 0;
+
+ return (
+
+
+
+ The message is {{ messageLength }} characters, which exceeds the maximum length of 500 characters. Please
+ shorten it before saving.
+
+
+
+ );
+ }
+
if (isVersionMismatchError(error)) {
return (
diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json
index f68a771ff6b..536293a7b70 100644
--- a/public/locales/en-US/grafana.json
+++ b/public/locales/en-US/grafana.json
@@ -2886,6 +2886,10 @@
"title": "Unable to find application file"
},
"save-dashboards": {
+ "message-length": {
+ "info": "The message is {{messageLength}} characters, which exceeds the maximum length of 500 characters. Please shorten it before saving.",
+ "title": "Message too long"
+ },
"name-exists": {
"message-info": "A dashboard with the same name in the selected folder already exists, including recently deleted dashboards.",
"message-suggestion": "Please choose a different name or folder.",
diff --git a/public/locales/pseudo-LOCALE/grafana.json b/public/locales/pseudo-LOCALE/grafana.json
index 88ca996b76a..e016299a6c3 100644
--- a/public/locales/pseudo-LOCALE/grafana.json
+++ b/public/locales/pseudo-LOCALE/grafana.json
@@ -2886,6 +2886,10 @@
"title": "Ůʼnäþľę ŧő ƒįʼnđ äppľįčäŧįőʼn ƒįľę"
},
"save-dashboards": {
+ "message-length": {
+ "info": "Ŧĥę męşşäģę įş {{messageLength}} čĥäřäčŧęřş, ŵĥįčĥ ęχčęęđş ŧĥę mäχįmūm ľęʼnģŧĥ őƒ 500 čĥäřäčŧęřş. Pľęäşę şĥőřŧęʼn įŧ þęƒőřę şävįʼnģ.",
+ "title": "Męşşäģę ŧőő ľőʼnģ"
+ },
"name-exists": {
"message-info": "Å đäşĥþőäřđ ŵįŧĥ ŧĥę şämę ʼnämę įʼn ŧĥę şęľęčŧęđ ƒőľđęř äľřęäđy ęχįşŧş, įʼnčľūđįʼnģ řęčęʼnŧľy đęľęŧęđ đäşĥþőäřđş.",
"message-suggestion": "Pľęäşę čĥőőşę ä đįƒƒęřęʼnŧ ʼnämę őř ƒőľđęř.",