From fd6a4908f1e776f0661d5565546adc83b6ffb7b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20=C5=A0tibran=C3=BD?= Date: Mon, 10 Mar 2025 12:33:52 +0100 Subject: [PATCH 01/63] Support Spanner's UNION syntax, which needs to be UNION DISTINCT or UNION ALL. (#101768) * Support Spanner's UNION syntax, which needs to be UNION DISTINCT or UNION ALL. --- pkg/infra/db/sqlbuilder.go | 2 +- pkg/services/accesscontrol/database/database.go | 5 +++-- pkg/services/accesscontrol/filter.go | 7 ++++--- .../annotations/accesscontrol/accesscontrol.go | 2 +- pkg/services/dashboards/database/database.go | 2 +- pkg/services/libraryelements/database.go | 8 ++++++-- pkg/services/sqlstore/migrator/dialect.go | 10 ++++++++++ pkg/services/sqlstore/migrator/spanner_dialect.go | 4 ++++ pkg/services/sqlstore/permissions/dashboard.go | 11 ++++++----- .../permissions/dashboard_filter_no_subquery.go | 5 +++-- pkg/services/sqlstore/permissions/dashboard_test.go | 10 +++++----- .../sqlstore/permissions/dashboards_bench_test.go | 2 +- pkg/services/sqlstore/searchstore/search_test.go | 1 + 13 files changed, 46 insertions(+), 23 deletions(-) diff --git a/pkg/infra/db/sqlbuilder.go b/pkg/infra/db/sqlbuilder.go index 0d9e655fe26..f30d1a7c2ea 100644 --- a/pkg/infra/db/sqlbuilder.go +++ b/pkg/infra/db/sqlbuilder.go @@ -72,7 +72,7 @@ func (sb *SQLBuilder) WriteDashboardPermissionFilter(user identity.Requester, pe leftJoin string ) - filterRBAC := permissions.NewAccessControlDashboardPermissionFilter(user, permission, queryType, sb.features, sb.recursiveQueriesAreSupported) + filterRBAC := permissions.NewAccessControlDashboardPermissionFilter(user, permission, queryType, sb.features, sb.recursiveQueriesAreSupported, sb.dialect) leftJoin = filterRBAC.LeftJoin() sql, params = filterRBAC.Where() recQry, recQryParams = filterRBAC.With() diff --git a/pkg/services/accesscontrol/database/database.go b/pkg/services/accesscontrol/database/database.go index cb89e51145c..ce6dd393f77 100644 --- a/pkg/services/accesscontrol/database/database.go +++ b/pkg/services/accesscontrol/database/database.go @@ -6,9 +6,10 @@ import ( "strconv" "strings" + "go.opentelemetry.io/otel" + "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/services/accesscontrol" - "go.opentelemetry.io/otel" ) var tracer = otel.Tracer("github.com/grafana/grafana/pkg/services/accesscontrol/database") @@ -58,7 +59,7 @@ func (s *AccessControlStore) GetUserPermissions(ctx context.Context, query acces return nil } - filter, params := accesscontrol.UserRolesFilter(query.OrgID, query.UserID, query.TeamIDs, query.Roles) + filter, params := accesscontrol.UserRolesFilter(query.OrgID, query.UserID, query.TeamIDs, query.Roles, s.sql.GetDialect()) q := ` SELECT diff --git a/pkg/services/accesscontrol/filter.go b/pkg/services/accesscontrol/filter.go index 934b3ad9636..8ecd12d5108 100644 --- a/pkg/services/accesscontrol/filter.go +++ b/pkg/services/accesscontrol/filter.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/grafana/grafana/pkg/apimachinery/identity" + "github.com/grafana/grafana/pkg/services/sqlstore/migrator" ) var sqlIDAcceptList = map[string]struct{}{ @@ -127,7 +128,7 @@ func SetAcceptListForTest(list map[string]struct{}) func() { } } -func UserRolesFilter(orgID, userID int64, teamIDs []int64, roles []string) (string, []any) { +func UserRolesFilter(orgID, userID int64, teamIDs []int64, roles []string, dialect migrator.Dialect) (string, []any) { var params []any builder := strings.Builder{} @@ -145,7 +146,7 @@ func UserRolesFilter(orgID, userID int64, teamIDs []int64, roles []string) (stri if len(teamIDs) > 0 { if builder.Len() > 0 { - builder.WriteString("UNION") + builder.WriteString(dialect.UnionDistinct()) } builder.WriteString(` SELECT tr.role_id FROM team_role as tr @@ -160,7 +161,7 @@ func UserRolesFilter(orgID, userID int64, teamIDs []int64, roles []string) (stri if len(roles) != 0 { if builder.Len() > 0 { - builder.WriteString("UNION") + builder.WriteString(dialect.UnionDistinct()) } builder.WriteString(` diff --git a/pkg/services/annotations/accesscontrol/accesscontrol.go b/pkg/services/annotations/accesscontrol/accesscontrol.go index d29eed7d1e7..f2e89acd23b 100644 --- a/pkg/services/annotations/accesscontrol/accesscontrol.go +++ b/pkg/services/annotations/accesscontrol/accesscontrol.go @@ -121,7 +121,7 @@ func (authz *AuthService) dashboardsWithVisibleAnnotations(ctx context.Context, } filters := []any{ - permissions.NewAccessControlDashboardPermissionFilter(query.SignedInUser, dashboardaccess.PERMISSION_VIEW, filterType, authz.features, recursiveQueriesSupported), + permissions.NewAccessControlDashboardPermissionFilter(query.SignedInUser, dashboardaccess.PERMISSION_VIEW, filterType, authz.features, recursiveQueriesSupported, authz.db.GetDialect()), searchstore.OrgFilter{OrgId: query.OrgID}, } diff --git a/pkg/services/dashboards/database/database.go b/pkg/services/dashboards/database/database.go index b4946486c48..2f0ccba7f3e 100644 --- a/pkg/services/dashboards/database/database.go +++ b/pkg/services/dashboards/database/database.go @@ -1002,7 +1002,7 @@ func (d *dashboardStore) FindDashboards(ctx context.Context, query *dashboards.F } if !query.SkipAccessControlFilter { - filters = append(filters, permissions.NewAccessControlDashboardPermissionFilter(query.SignedInUser, query.Permission, query.Type, d.features, recursiveQueriesAreSupported)) + filters = append(filters, permissions.NewAccessControlDashboardPermissionFilter(query.SignedInUser, query.Permission, query.Type, d.features, recursiveQueriesAreSupported, d.store.GetDialect())) } filters = append(filters, searchstore.DeletedFilter{Deleted: query.IsDeleted}) diff --git a/pkg/services/libraryelements/database.go b/pkg/services/libraryelements/database.go index fef92e60225..9a9f287d875 100644 --- a/pkg/services/libraryelements/database.go +++ b/pkg/services/libraryelements/database.go @@ -455,7 +455,9 @@ func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedI writeSearchStringSQL(query, l.SQLStore, &builder) writeExcludeSQL(query, &builder) writeTypeFilterSQL(typeFilter, &builder) - builder.Write(" UNION ") + builder.Write(" ") + builder.Write(l.SQLStore.GetDialect().UnionDistinct()) + builder.Write(" ") } builder.Write(selectLibraryElementDTOWithMeta) builder.Write(", le.folder_uid as folder_uid ") @@ -544,7 +546,9 @@ func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedI writeSearchStringSQL(query, l.SQLStore, &countBuilder) writeExcludeSQL(query, &countBuilder) writeTypeFilterSQL(typeFilter, &countBuilder) - countBuilder.Write(" UNION ") + countBuilder.Write(" ") + countBuilder.Write(l.SQLStore.GetDialect().UnionDistinct()) + countBuilder.Write(" ") } countBuilder.Write(selectLibraryElementDTOWithMeta) countBuilder.Write(getFromLibraryElementDTOWithMeta(l.SQLStore.GetDialect())) diff --git a/pkg/services/sqlstore/migrator/dialect.go b/pkg/services/sqlstore/migrator/dialect.go index 92ed26156fa..4a9b62766d7 100644 --- a/pkg/services/sqlstore/migrator/dialect.go +++ b/pkg/services/sqlstore/migrator/dialect.go @@ -32,6 +32,8 @@ type Dialect interface { BooleanStr(bool) string DateTimeFunc(string) string BatchSize() int + UnionDistinct() string // this is the default UNION type + UnionAll() string OrderBy(order string) string @@ -467,3 +469,11 @@ func (b *BaseDialect) Update(ctx context.Context, tx *session.SessionTx, tableNa func (b *BaseDialect) Concat(strs ...string) string { return fmt.Sprintf("CONCAT(%s)", strings.Join(strs, ", ")) } + +func (b *BaseDialect) UnionDistinct() string { + return "UNION" +} + +func (b *BaseDialect) UnionAll() string { + return "UNION ALL" +} diff --git a/pkg/services/sqlstore/migrator/spanner_dialect.go b/pkg/services/sqlstore/migrator/spanner_dialect.go index 70a10ad1775..33a20520e36 100644 --- a/pkg/services/sqlstore/migrator/spanner_dialect.go +++ b/pkg/services/sqlstore/migrator/spanner_dialect.go @@ -325,3 +325,7 @@ func confToClientOptions(connectorConfig spannerdriver.ConnectorConfig) []option } return opts } + +func (s *SpannerDialect) UnionDistinct() string { + return "UNION DISTINCT" +} diff --git a/pkg/services/sqlstore/permissions/dashboard.go b/pkg/services/sqlstore/permissions/dashboard.go index 945a7c53e1e..cdf22a15569 100644 --- a/pkg/services/sqlstore/permissions/dashboard.go +++ b/pkg/services/sqlstore/permissions/dashboard.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/login" + "github.com/grafana/grafana/pkg/services/sqlstore/migrator" "github.com/grafana/grafana/pkg/services/sqlstore/searchstore" ) @@ -44,14 +45,14 @@ type PermissionsFilter interface { With() (string, []any) Where() (string, []any) - buildClauses() + buildClauses(dialect migrator.Dialect) nestedFoldersSelectors(permSelector string, permSelectorArgs []any, leftTable string, Col string, rightTableCol string, orgID int64) (string, []any) } // NewAccessControlDashboardPermissionFilter creates a new AccessControlDashboardPermissionFilter that is configured with specific actions calculated based on the dashboardaccess.PermissionType and query type // The filter is configured to use the new permissions filter (without subqueries) if the feature flag is enabled // The filter is configured to use the old permissions filter (with subqueries) if the feature flag is disabled -func NewAccessControlDashboardPermissionFilter(user identity.Requester, permissionLevel dashboardaccess.PermissionType, queryType string, features featuremgmt.FeatureToggles, recursiveQueriesAreSupported bool) PermissionsFilter { +func NewAccessControlDashboardPermissionFilter(user identity.Requester, permissionLevel dashboardaccess.PermissionType, queryType string, features featuremgmt.FeatureToggles, recursiveQueriesAreSupported bool, dialect migrator.Dialect) PermissionsFilter { needEdit := permissionLevel > dashboardaccess.PERMISSION_VIEW var folderAction string @@ -129,7 +130,7 @@ func NewAccessControlDashboardPermissionFilter(user identity.Requester, permissi features: features, recursiveQueriesAreSupported: recursiveQueriesAreSupported, } } - f.buildClauses() + f.buildClauses(dialect) return f } @@ -157,7 +158,7 @@ func (f *accessControlDashboardPermissionFilter) hasRequiredActions() bool { return false } -func (f *accessControlDashboardPermissionFilter) buildClauses() { +func (f *accessControlDashboardPermissionFilter) buildClauses(dialect migrator.Dialect) { if f.user == nil || f.user.IsNil() || !f.hasRequiredActions() { f.where = clause{string: "(1 = 0)"} return @@ -171,7 +172,7 @@ func (f *accessControlDashboardPermissionFilter) buildClauses() { } orgID := f.user.GetOrgID() - filter, params := accesscontrol.UserRolesFilter(orgID, userID, f.user.GetTeams(), accesscontrol.GetOrgRoles(f.user)) + filter, params := accesscontrol.UserRolesFilter(orgID, userID, f.user.GetTeams(), accesscontrol.GetOrgRoles(f.user), dialect) rolesFilter := " AND role_id IN(SELECT id FROM role " + filter + ") " var args []any builder := strings.Builder{} diff --git a/pkg/services/sqlstore/permissions/dashboard_filter_no_subquery.go b/pkg/services/sqlstore/permissions/dashboard_filter_no_subquery.go index 8f7f16c6303..6fee82f9766 100644 --- a/pkg/services/sqlstore/permissions/dashboard_filter_no_subquery.go +++ b/pkg/services/sqlstore/permissions/dashboard_filter_no_subquery.go @@ -10,6 +10,7 @@ import ( "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/folder" "github.com/grafana/grafana/pkg/services/login" + "github.com/grafana/grafana/pkg/services/sqlstore/migrator" ) type accessControlDashboardPermissionFilterNoFolderSubquery struct { @@ -25,7 +26,7 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) LeftJoin() stri return " dashboard AS folder ON dashboard.org_id = folder.org_id AND dashboard.folder_id = folder.id" } -func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses() { +func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses(dialect migrator.Dialect) { if f.user == nil || f.user.IsNil() || len(f.user.GetPermissions()) == 0 { f.where = clause{string: "(1 = 0)"} return @@ -39,7 +40,7 @@ func (f *accessControlDashboardPermissionFilterNoFolderSubquery) buildClauses() } orgID := f.user.GetOrgID() - filter, params := accesscontrol.UserRolesFilter(orgID, userID, f.user.GetTeams(), accesscontrol.GetOrgRoles(f.user)) + filter, params := accesscontrol.UserRolesFilter(orgID, userID, f.user.GetTeams(), accesscontrol.GetOrgRoles(f.user), dialect) rolesFilter := " AND role_id IN(SELECT id FROM role " + filter + ") " var args []any builder := strings.Builder{} diff --git a/pkg/services/sqlstore/permissions/dashboard_test.go b/pkg/services/sqlstore/permissions/dashboard_test.go index 3174db18373..efc72764d9d 100644 --- a/pkg/services/sqlstore/permissions/dashboard_test.go +++ b/pkg/services/sqlstore/permissions/dashboard_test.go @@ -183,7 +183,7 @@ func TestIntegration_DashboardPermissionFilter(t *testing.T) { keys = append(keys, k) } t.Run(tt.desc+" with features "+strings.Join(keys, ","), func(t *testing.T) { - filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tt.permission, tt.queryType, features, recursiveQueriesAreSupported) + filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tt.permission, tt.queryType, features, recursiveQueriesAreSupported, store.GetDialect()) var result int err = store.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error { @@ -355,7 +355,7 @@ func TestIntegration_DashboardPermissionFilter_WithSelfContainedPermissions(t *t keys = append(keys, k) } t.Run(tt.desc+" with features "+strings.Join(keys, ","), func(t *testing.T) { - filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tt.permission, tt.queryType, features, recursiveQueriesAreSupported) + filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tt.permission, tt.queryType, features, recursiveQueriesAreSupported, store.GetDialect()) var result int err = store.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error { @@ -470,7 +470,7 @@ func TestIntegration_DashboardNestedPermissionFilter(t *testing.T) { db := setupNestedTest(t, usr, tc.permissions, orgID, features) recursiveQueriesAreSupported, err := db.RecursiveQueriesAreSupported() require.NoError(t, err) - filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tc.permission, tc.queryType, features, recursiveQueriesAreSupported) + filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tc.permission, tc.queryType, features, recursiveQueriesAreSupported, db.GetDialect()) var result []string err = db.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error { q, params := filter.Where() @@ -588,7 +588,7 @@ func TestIntegration_DashboardNestedPermissionFilter_WithSelfContainedPermission db := setupNestedTest(t, helperUser, []accesscontrol.Permission{}, orgID, features) recursiveQueriesAreSupported, err := db.RecursiveQueriesAreSupported() require.NoError(t, err) - filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tc.permission, tc.queryType, features, recursiveQueriesAreSupported) + filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tc.permission, tc.queryType, features, recursiveQueriesAreSupported, db.GetDialect()) var result []string err = db.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error { q, params := filter.Where() @@ -707,7 +707,7 @@ func TestIntegration_DashboardNestedPermissionFilter_WithActionSets(t *testing.T db := setupNestedTest(t, usr, tc.signedInUserPermissions, orgID, features) recursiveQueriesAreSupported, err := db.RecursiveQueriesAreSupported() require.NoError(t, err) - filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tc.permission, tc.queryType, features, recursiveQueriesAreSupported) + filter := permissions.NewAccessControlDashboardPermissionFilter(usr, tc.permission, tc.queryType, features, recursiveQueriesAreSupported, db.GetDialect()) var result []string err = db.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error { q, params := filter.Where() diff --git a/pkg/services/sqlstore/permissions/dashboards_bench_test.go b/pkg/services/sqlstore/permissions/dashboards_bench_test.go index e4fa2de1dbe..b396bb955fb 100644 --- a/pkg/services/sqlstore/permissions/dashboards_bench_test.go +++ b/pkg/services/sqlstore/permissions/dashboards_bench_test.go @@ -56,7 +56,7 @@ func benchmarkDashboardPermissionFilter(b *testing.B, numUsers, numDashboards, n b.ResetTimer() for i := 0; i < b.N; i++ { - filter := permissions.NewAccessControlDashboardPermissionFilter(&usr, dashboardaccess.PERMISSION_VIEW, "", features, recursiveQueriesAreSupported) + filter := permissions.NewAccessControlDashboardPermissionFilter(&usr, dashboardaccess.PERMISSION_VIEW, "", features, recursiveQueriesAreSupported, store.GetDialect()) var result int err := store.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error { q, params := filter.Where() diff --git a/pkg/services/sqlstore/searchstore/search_test.go b/pkg/services/sqlstore/searchstore/search_test.go index 7bccffef1d6..4b0786f4ceb 100644 --- a/pkg/services/sqlstore/searchstore/search_test.go +++ b/pkg/services/sqlstore/searchstore/search_test.go @@ -334,6 +334,7 @@ func TestBuilder_RBAC(t *testing.T) { "", tc.features, recursiveQueriesAreSupported, + store.GetDialect(), ), }, Dialect: store.GetDialect(), From 852243c8f0300c1a1ecaeb75f1726609c4833c5d Mon Sep 17 00:00:00 2001 From: Tom Ratcliffe Date: Mon, 10 Mar 2025 12:02:31 +0000 Subject: [PATCH 02/63] Chore: Remove pseudoizer and use i18next-pseudo instead (#101690) * Remove pseudoizer and use i18next-pseudo instead * Remove pseudo.mjs script * Conditionally add pseudo post processing to i18n config * Remove pseudo-locale in favour of post processing * Add wrapped property to pseudo strings --- Makefile | 2 - package.json | 2 +- packages/grafana-ui/src/utils/i18n.tsx | 17 + .../core/internationalization/constants.ts | 4 +- public/locales/pseudo-LOCALE/grafana.json | 4018 ----------------- public/locales/pseudo.mjs | 63 - yarn.lock | 27 +- 7 files changed, 40 insertions(+), 4093 deletions(-) delete mode 100644 public/locales/pseudo-LOCALE/grafana.json delete mode 100644 public/locales/pseudo.mjs diff --git a/Makefile b/Makefile index 842ce5b65e9..699cfb0652e 100644 --- a/Makefile +++ b/Makefile @@ -131,14 +131,12 @@ else i18n-extract-enterprise: @echo "Extracting i18n strings for Enterprise" yarn run i18next --config public/locales/i18next-parser-enterprise.config.cjs - node ./public/locales/pseudo.mjs --mode enterprise endif .PHONY: i18n-extract i18n-extract: i18n-extract-enterprise @echo "Extracting i18n strings for OSS" yarn run i18next --config public/locales/i18next-parser.config.cjs - node ./public/locales/pseudo.mjs --mode oss ##@ Building .PHONY: gen-cue diff --git a/package.json b/package.json index 77b946e8711..52da476b137 100644 --- a/package.json +++ b/package.json @@ -223,7 +223,6 @@ "postcss-reporter": "7.1.0", "postcss-scss": "4.0.9", "prettier": "3.4.2", - "pseudoizer": "^0.1.0", "react-refresh": "0.14.0", "react-select-event": "5.5.1", "redux-mock-store": "1.5.5", @@ -336,6 +335,7 @@ "history": "4.10.1", "i18next": "^24.0.0", "i18next-browser-languagedetector": "^8.0.0", + "i18next-pseudo": "^2.2.1", "immer": "10.1.1", "immutable": "5.0.3", "ix": "^7.0.0", diff --git a/packages/grafana-ui/src/utils/i18n.tsx b/packages/grafana-ui/src/utils/i18n.tsx index 5e688f48fee..6170b9bc76b 100644 --- a/packages/grafana-ui/src/utils/i18n.tsx +++ b/packages/grafana-ui/src/utils/i18n.tsx @@ -20,6 +20,23 @@ function initI18n() { resources: {}, returnEmptyString: false, lng: 'en-US', // this should be the locale of the phrases in our source JSX + postProcess: [ + // Add pseudo processing even if we aren't necessarily going to use it + 'pseudo', + ], + }); + } + + if (process.env.NODE_ENV === 'development') { + import('i18next-pseudo').then((module) => { + const Pseudo = module.default; + i18next.use( + new Pseudo({ + languageToPseudo: 'pseudo', + enabled: true, + wrapped: true, + }) + ); }); } } diff --git a/public/app/core/internationalization/constants.ts b/public/app/core/internationalization/constants.ts index b28e5499d92..0c79eb560ef 100644 --- a/public/app/core/internationalization/constants.ts +++ b/public/app/core/internationalization/constants.ts @@ -79,7 +79,9 @@ if (process.env.NODE_ENV === 'development') { code: PSEUDO_LOCALE, name: 'Pseudo-locale', loader: { - grafana: () => import('../../../locales/pseudo-LOCALE/grafana.json'), + // Load the English locale as the pseudo-locale, + // as it will be post-processed by i18next-pseudo library + grafana: () => import('../../../locales/en-US/grafana.json'), }, }); } diff --git a/public/locales/pseudo-LOCALE/grafana.json b/public/locales/pseudo-LOCALE/grafana.json deleted file mode 100644 index a2f227ebf67..00000000000 --- a/public/locales/pseudo-LOCALE/grafana.json +++ /dev/null @@ -1,4018 +0,0 @@ -{ - "_comment": "Ŧĥę čőđę įş ŧĥę şőūřčę őƒ ŧřūŧĥ ƒőř Ēʼnģľįşĥ pĥřäşęş. Ŧĥęy şĥőūľđ þę ūpđäŧęđ įʼn ŧĥę čőmpőʼnęʼnŧş đįřęčŧľy, äʼnđ äđđįŧįőʼnäľ pľūřäľş şpęčįƒįęđ įʼn ŧĥįş ƒįľę.", - "access-control": { - "add-permission": { - "role-label": "Ŗőľę", - "serviceaccount-label": "Ŝęřvįčę Åččőūʼnŧ", - "team-label": "Ŧęäm", - "title": "Åđđ pęřmįşşįőʼn ƒőř", - "user-label": "Ůşęř" - }, - "add-permissions": { - "save": "Ŝävę" - }, - "permission-list": { - "permission": "Pęřmįşşįőʼn" - }, - "permission-list-item": { - "inherited": "Ĩʼnĥęřįŧęđ ƒřőm ƒőľđęř" - }, - "permissions": { - "add-label": "Åđđ ä pęřmįşşįőʼn", - "no-permissions": "Ŧĥęřę äřę ʼnő pęřmįşşįőʼnş", - "permissions-change-warning": "Ŧĥįş ŵįľľ čĥäʼnģę pęřmįşşįőʼnş ƒőř ŧĥįş ƒőľđęř äʼnđ äľľ įŧş đęşčęʼnđäʼnŧş. Ĩʼn ŧőŧäľ, ŧĥįş ŵįľľ 䃃ęčŧ:", - "role": "Ŗőľę", - "serviceaccount": "Ŝęřvįčę Åččőūʼnŧ", - "team": "Ŧęäm", - "title": "Pęřmįşşįőʼnş", - "user": "Ůşęř" - } - }, - "action-editor": { - "modal": { - "cancel-button": "Cäʼnčęľ", - "save-button": "Ŝävę" - } - }, - "admin": { - "anon-users": { - "not-found": "Ńő äʼnőʼnymőūş ūşęřş ƒőūʼnđ." - }, - "edit-org": { - "access-denied": "Ÿőū đő ʼnőŧ ĥävę pęřmįşşįőʼn ŧő şęę ūşęřş įʼn ŧĥįş őřģäʼnįžäŧįőʼn. Ŧő ūpđäŧę ŧĥįş őřģäʼnįžäŧįőʼn, čőʼnŧäčŧ yőūř şęřvęř äđmįʼnįşŧřäŧőř.", - "heading": "Ēđįŧ Øřģäʼnįžäŧįőʼn", - "update-button": "Ůpđäŧę", - "users-heading": "Øřģäʼnįžäŧįőʼn ūşęřş" - }, - "feature-toggles": { - "sub-title": "Vįęŵ äʼnđ ęđįŧ ƒęäŧūřę ŧőģģľęş. Ŗęäđ mőřę äþőūŧ ƒęäŧūřę ŧőģģľęş äŧ <2>ģřäƒäʼnä.čőm." - }, - "get-enterprise": { - "contact-us": "Cőʼnŧäčŧ ūş äʼnđ ģęŧ ä ƒřęę ŧřįäľ", - "description": "Ÿőū čäʼn ūşę ŧĥę ŧřįäľ vęřşįőʼn ƒőř ƒřęę ƒőř 30 đäyş. Ŵę ŵįľľ řęmįʼnđ yőū äþőūŧ įŧ ƒįvę đäyş þęƒőřę ŧĥę ŧřįäľ pęřįőđ ęʼnđş.", - "features-heading": "Ēʼnĥäʼnčęđ ƒūʼnčŧįőʼnäľįŧy", - "included-description": "Ĩʼnđęmʼnįƒįčäŧįőʼn, ŵőřĸįʼnģ ŵįŧĥ Ğřäƒäʼnä Ŀäþş őʼn ƒūŧūřę přįőřįŧįžäŧįőʼn, äʼnđ ŧřäįʼnįʼnģ ƒřőm ŧĥę čőřę Ğřäƒäʼnä ŧęäm.", - "included-heading": "Åľşő įʼnčľūđęđ:", - "service-title": "Åŧ yőūř şęřvįčę", - "team-sync-details": "ĿĐÅP, ĞįŧĦūþ ØÅūŧĥ, Åūŧĥ Přőχy, Øĸŧä", - "title": "Ğęŧ Ğřäƒäʼnä Ēʼnŧęřpřįşę" - }, - "ldap": { - "test-mapping-heading": "Ŧęşŧ ūşęř mäppįʼnģ", - "test-mapping-run-button": "Ŗūʼn" - }, - "ldap-permissions": { - "active": "<0> Åčŧįvę", - "admin": "<0> Ÿęş", - "inactive": "<0> Ĩʼnäčŧįvę" - }, - "ldap-status": { - "title": "ĿĐÅP Cőʼnʼnęčŧįőʼn" - }, - "ldap-sync": { - "debug-button": "Đęþūģ ĿĐÅP Mäppįʼnģ", - "external-sync-description": "Ůşęř şyʼnčęđ vįä ĿĐÅP. Ŝőmę čĥäʼnģęş mūşŧ þę đőʼnę įʼn ĿĐÅP őř mäppįʼnģş.", - "external-sync-label": "Ēχŧęřʼnäľ şyʼnč", - "next-sync-label": "Ńęχŧ şčĥęđūľęđ şyʼnčĥřőʼnįžäŧįőʼn", - "not-enabled": "Ńőŧ ęʼnäþľęđ", - "sync-button": "Ŝyʼnč ūşęř", - "title": "ĿĐÅP Ŝyʼnčĥřőʼnįşäŧįőʼn" - }, - "ldap-sync-info": { - "title": "ĿĐÅP Ŝyʼnčĥřőʼnįžäŧįőʼn" - }, - "ldap-user-groups": { - "no-org-found": "Ńő mäŧčĥ <2><0>" - }, - "ldap-user-info": { - "no-team": "Ńő ŧęämş ƒőūʼnđ vįä ĿĐÅP" - }, - "org-uers": { - "last-seen-never": "Ńęvęř" - }, - "org-users": { - "not-editable": "Ŧĥįş ūşęř'ş řőľę įş ʼnőŧ ęđįŧäþľę þęčäūşę įŧ įş şyʼnčĥřőʼnįžęđ ƒřőm yőūř äūŧĥ přővįđęř. Ŗęƒęř ŧő ŧĥę <1>Ğřäƒäʼnä äūŧĥęʼnŧįčäŧįőʼn đőčş ƒőř đęŧäįľş." - }, - "orgs": { - "delete-body": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő đęľęŧę '{{deleteOrgName}}'?<3> <5>Åľľ đäşĥþőäřđş ƒőř ŧĥįş őřģäʼnįžäŧįőʼn ŵįľľ þę řęmővęđ!", - "id-header": "ĨĐ", - "name-header": "Ńämę", - "new-org-button": "Ńęŵ őřģ" - }, - "server-settings": { - "alerts-button": "Mäʼnäģę äľęřŧş", - "dashboards-button": "Mäʼnäģę đäşĥþőäřđş", - "data-sources-button": "Mäʼnäģę đäŧä şőūřčęş", - "not-found": "Ńő şŧäŧş ƒőūʼnđ.", - "title": "Ĩʼnşŧäʼnčę şŧäŧįşŧįčş", - "users-button": "Mäʼnäģę ūşęřş" - }, - "settings": { - "info-description": "Ŧĥęşę şyşŧęm şęŧŧįʼnģş äřę đęƒįʼnęđ įʼn ģřäƒäʼnä.įʼnį őř čūşŧőm.įʼnį (őř ővęřřįđđęʼn įʼn ĒŃV väřįäþľęş). Ŧő čĥäʼnģę ŧĥęşę yőū čūřřęʼnŧľy ʼnęęđ ŧő řęşŧäřŧ Ğřäƒäʼnä." - }, - "upgrade-info": { - "title": "Ēʼnŧęřpřįşę ľįčęʼnşę" - }, - "user-orgs": { - "add-button": "Åđđ ūşęř ŧő őřģäʼnįžäŧįőʼn", - "change-role-button": "Cĥäʼnģę řőľę", - "external-user-tooltip": "Ŧĥįş ūşęř'ş þūįľŧ-įʼn řőľę įş ʼnőŧ ęđįŧäþľę þęčäūşę įŧ įş şyʼnčĥřőʼnįžęđ ƒřőm yőūř äūŧĥ přővįđęř. Ŗęƒęř ŧő ŧĥę <1>Ğřäƒäʼnä äūŧĥęʼnŧįčäŧįőʼn đőčş ƒőř đęŧäįľş.", - "remove-button": "Ŗęmővę ƒřőm őřģäʼnįžäŧįőʼn", - "role-not-editable": "Ŧĥįş ūşęř'ş řőľę įş ʼnőŧ ęđįŧäþľę þęčäūşę įŧ įş şyʼnčĥřőʼnįžęđ ƒřőm yőūř äūŧĥ přővįđęř. Ŗęƒęř ŧő ŧĥę <1>Ğřäƒäʼnä äūŧĥęʼnŧįčäŧįőʼn đőčş ƒőř đęŧäįľş.", - "title": "Øřģäʼnįžäŧįőʼnş" - }, - "user-orgs-modal": { - "add-button": "Åđđ ŧő őřģäʼnįžäŧįőʼn", - "cancel-button": "Cäʼnčęľ" - }, - "user-permissions": { - "change-button": "Cĥäʼnģę", - "grafana-admin-key": "Ğřäƒäʼnä Åđmįʼn", - "grafana-admin-no": "Ńő", - "grafana-admin-yes": "Ÿęş", - "title": "Pęřmįşşįőʼnş" - }, - "user-profile": { - "delete-button": "Đęľęŧę ūşęř", - "disable-button": "Đįşäþľę ūşęř", - "edit-button": "Ēđįŧ", - "enable-button": "Ēʼnäþľę ūşęř", - "title": "Ůşęř įʼnƒőřmäŧįőʼn" - }, - "user-sessions": { - "browser-column": "ßřőŵşęř äʼnđ ØŜ", - "force-logout-all-button": "Főřčę ľőģőūŧ ƒřőm äľľ đęvįčęş", - "force-logout-button": "Főřčę ľőģőūŧ", - "ip-column": "ĨP äđđřęşş", - "last-seen-column": "Ŀäşŧ şęęʼn", - "logged-on-column": "Ŀőģģęđ őʼn", - "title": "Ŝęşşįőʼnş" - }, - "users-create": { - "create-button": "Cřęäŧę ūşęř" - }, - "users-list": { - "create-button": "Ńęŵ ūşęř" - }, - "users-table": { - "last-seen-never": "Ńęvęř", - "no-licensed-roles": "Ńőŧ äşşįģʼnęđ" - } - }, - "alert-labels": { - "button": { - "hide": "Ħįđę čőmmőʼn ľäþęľş", - "show": { - "tooltip": "Ŝĥőŵ čőmmőʼn ľäþęľş" - } - } - }, - "alerting": { - "alert": { - "alert-state": "Åľęřŧ şŧäŧę", - "annotations": "Åʼnʼnőŧäŧįőʼnş", - "evaluation": "Ēväľūäŧįőʼn", - "evaluation-paused": "Åľęřŧ ęväľūäŧįőʼn čūřřęʼnŧľy päūşęđ", - "evaluation-paused-description": "Ńőŧįƒįčäŧįőʼnş ƒőř ŧĥįş řūľę ŵįľľ ʼnőŧ ƒįřę äʼnđ ʼnő äľęřŧ įʼnşŧäʼnčęş ŵįľľ þę čřęäŧęđ ūʼnŧįľ ŧĥę řūľę įş ūʼn-päūşęđ.", - "last-evaluated": "Ŀäşŧ ęväľūäŧęđ", - "last-evaluation-duration": "Ŀäşŧ ęväľūäŧįőʼn đūřäŧįőʼn", - "last-updated-at": "Ŀäşŧ ūpđäŧęđ äŧ", - "last-updated-by": "Ŀäşŧ ūpđäŧęđ þy", - "no-annotations": "Ńő äʼnʼnőŧäŧįőʼnş", - "pending-period": "Pęʼnđįʼnģ pęřįőđ", - "rule": "Ŗūľę", - "rule-identifier": "Ŗūľę įđęʼnŧįƒįęř", - "rule-type": "Ŗūľę ŧypę", - "state-error-timeout": "Åľęřŧ şŧäŧę įƒ ęχęčūŧįőʼn ęřřőř őř ŧįmęőūŧ", - "state-no-data": "Åľęřŧ şŧäŧę įƒ ʼnő đäŧä őř äľľ väľūęş äřę ʼnūľľ" - }, - "alert-recording-rule-form": { - "evaluation-behaviour": { - "description": { - "text": "Đęƒįʼnę ĥőŵ ŧĥę řęčőřđįʼnģ řūľę įş ęväľūäŧęđ." - } - } - }, - "alert-rules": { - "firing-for": "Fįřįʼnģ ƒőř", - "next-evaluation": "Ńęχŧ ęväľūäŧįőʼn", - "next-evaluation-in": "ʼnęχŧ ęväľūäŧįőʼn įʼn", - "rule-definition": "Ŗūľę đęƒįʼnįŧįőʼn" - }, - "alertform": { - "labels": { - "alerting": "Åđđ ľäþęľş ŧő yőūř řūľę ƒőř şęäřčĥįʼnģ, şįľęʼnčįʼnģ, őř řőūŧįʼnģ ŧő ä ʼnőŧįƒįčäŧįőʼn pőľįčy.", - "recording": "Åđđ ľäþęľş ŧő yőūř řūľę." - } - }, - "alertVersionHistory": { - "alerting": "Åľęřŧįʼnģ", - "alerting-change-description": "Ŧĥįş ūpđäŧę ŵäş mäđę þy ŧĥę äľęřŧįʼnģ şyşŧęm đūę ŧő őŧĥęř čĥäʼnģęş. Főř ęχämpľę, ŵĥęʼn řęʼnämįʼnģ ä čőʼnŧäčŧ pőįʼnŧ ŧĥäŧ įş ūşęđ ƒőř şįmpľįƒįęđ řőūŧįʼnģ, ŧĥįş ŵįľľ ūpđäŧę 䃃ęčŧęđ řūľęş", - "annotations": "Åʼnʼnőŧäŧįőʼnş", - "compare": "Cőmpäřę", - "compare-with-latest": "Cőmpäřę ŵįŧĥ ľäŧęşŧ vęřşįőʼn", - "compareVersions": "Cőmpäřę vęřşįőʼnş", - "comparing-versions": "Cőmpäřįʼnģ vęřşįőʼnş", - "condition": "Åľęřŧ čőʼnđįŧįőʼn", - "contactPointRouting": "Cőʼnŧäčŧ pőįʼnŧ řőūŧįʼnģ", - "description": "Ēäčĥ ŧįmę yőū ęđįŧ ŧĥę äľęřŧ řūľę, ä ʼnęŵ vęřşįőʼn įş čřęäŧęđ. Ŝęľęčŧ ŧŵő vęřşįőʼnş þęľőŵ äʼnđ čőmpäřę ŧĥęįř đįƒƒęřęʼnčęş.", - "errorloading": "Fäįľęđ ŧő ľőäđ äľęřŧ řūľę vęřşįőʼnş", - "execErrorState": "Åľęřŧ şŧäŧę ŵĥęʼn ęχęčūŧįőʼn ęřřőř", - "intervalSeconds": "Ēväľūäŧįőʼn įʼnŧęřväľ", - "labels": "Ŀäþęľş", - "latest": "Ŀäŧęşŧ", - "name": "Ńämę", - "namespace_uid": "Főľđęř ŮĨĐ", - "noDataState": "Åľęřŧ şŧäŧę ŵĥęʼn ʼnő đäŧä", - "noVersionsFound": "Ńő vęřşįőʼnş ƒőūʼnđ ƒőř ŧĥįş řūľę", - "paused": "Päūşęđ şŧäŧę", - "pendingPeriod": "Pęʼnđįʼnģ pęřįőđ", - "provisioning": "Přővįşįőʼnįʼnģ", - "provisioning-change-description": "Vęřşįőʼn ūpđäŧę ŵäş mäđę vįä přővįşįőʼnįʼnģ", - "queryAndAlertCondition": "Qūęřy äʼnđ äľęřŧ čőʼnđįŧįőʼn", - "restore": "Ŗęşŧőřę", - "restore-manually": "Ÿőūř äľęřŧ řūľę čőūľđ ʼnőŧ þę řęşŧőřęđ. Ŧĥįş mäy þę đūę ŧő čĥäʼnģęş ŧő őŧĥęř ęʼnŧįŧįęş şūčĥ äş čőʼnŧäčŧ pőįʼnŧş, đäŧä şőūřčęş ęŧč. Pľęäşę mäʼnūäľľy řęşŧőřę ŧĥę řūľę vęřşįőʼn", - "restore-modal": { - "body": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő řęşŧőřę ŧĥę äľęřŧ řūľę đęƒįʼnįŧįőʼn ŧő ŧĥįş vęřşįőʼn? Åľľ ūʼnşävęđ čĥäʼnģęş ŵįľľ þę ľőşŧ.", - "confirm": "Ÿęş, řęşŧőřę čőʼnƒįģūřäŧįőʼn", - "error": "Cőūľđ ʼnőŧ řęşŧőřę äľęřŧ řūľę vęřşįőʼn ", - "summary": "Ŝūmmäřy őƒ čĥäʼnģęş ŧő þę äppľįęđ:", - "title": "Ŗęşŧőřę vęřşįőʼn" - }, - "restore-version": "Ŗęşŧőřę ŧő vęřşįőʼn {{version}}", - "rule_group": "Ŗūľę ģřőūp", - "unknown": "Ůʼnĸʼnőŵʼn", - "unknown-change-description": "Ŧĥįş ūpđäŧę ŵäş mäđę přįőř ŧő ŧĥę įmpľęmęʼnŧäŧįőʼn őƒ äľęřŧ řūľę vęřşįőʼn ĥįşŧőřy. Ŧĥę ūşęř ŵĥő mäđę ŧĥę čĥäʼnģę įş ʼnőŧ ŧřäčĸęđ, þūŧ ƒūŧūřę čĥäʼnģęş ŵįľľ įʼnčľūđę ŧĥę ūşęř", - "user-id": "Ůşęř ĨĐ {{uid}}", - "warning-restore-manually": "Ÿőū äřę mäʼnūäľľy řęşŧőřįʼnģ äʼn őľđ vęřşįőʼn őƒ ŧĥįş äľęřŧ řūľę. Pľęäşę řęvįęŵ ŧĥę čĥäʼnģęş čäřęƒūľľy þęƒőřę şävįʼnģ ŧĥę řūľę đęƒįʼnįŧįőʼn.", - "warning-restore-manually-title": "Ŗęşŧőřįʼnģ řūľę mäʼnūäľľy" - }, - "annotations": { - "description": "Åđđ mőřę čőʼnŧęχŧ ŧő yőūř äľęřŧ ʼnőŧįƒįčäŧįőʼnş.", - "title": "Cőʼnƒįģūřę ʼnőŧįƒįčäŧįőʼn męşşäģę" - }, - "central-alert-history": { - "details": { - "error": "Ēřřőř ľőäđįʼnģ řūľę ƒőř ŧĥįş ęvęʼnŧ.", - "header": { - "alert-rule": "Åľęřŧ řūľę", - "instance": "Ĩʼnşŧäʼnčę", - "state": "Ŝŧäŧę", - "timestamp": "Ŧįmęşŧämp" - }, - "loading": "Ŀőäđįʼnģ...", - "no-recognized-state": "Ńő řęčőģʼnįžęđ şŧäŧę", - "no-values": "Ńő väľūęş", - "not-found": "Ŗūľę ʼnőŧ ƒőūʼnđ ƒőř ŧĥįş ęvęʼnŧ.", - "number-transitions": "Ŝŧäŧę ŧřäʼnşįŧįőʼnş ƒőř şęľęčŧęđ pęřįőđ:", - "state": { - "alerting": "Åľęřŧįʼnģ", - "error": "Ēřřőř", - "no-data": "Ńő đäŧä", - "normal": "Ńőřmäľ", - "pending": "Pęʼnđįʼnģ" - }, - "state-transitions": "Ŝŧäŧę ŧřäʼnşįŧįőʼn", - "unknown-event-state": "Ůʼnĸʼnőŵʼn", - "unknown-rule": "Ůʼnĸʼnőŵʼn", - "value-in-transition": "Väľūę įʼn ŧřäʼnşįŧįőʼn" - }, - "error": "Ŝőmęŧĥįʼnģ ŵęʼnŧ ŵřőʼnģ ľőäđįʼnģ ŧĥę äľęřŧ şŧäŧę ĥįşŧőřy", - "filter": { - "clear": "Cľęäř ƒįľŧęřş", - "info": { - "label1": "Fįľŧęř ęvęʼnŧş ūşįʼnģ ľäþęľ qūęřyįʼnģ ŵįŧĥőūŧ şpäčęş, ęχ:", - "label2": "Ĩʼnväľįđ ūşę őƒ şpäčęş:", - "label3": "Väľįđ ūşę őƒ şpäčęş:", - "label4": "Fįľŧęř äľęřŧş ūşįʼnģ ľäþęľ qūęřyįʼnģ ŵįŧĥőūŧ þřäčęş, ęχ:" - } - }, - "filterBy": "Fįľŧęř þy:", - "too-many-events": { - "text": "Ŧĥę şęľęčŧęđ ŧįmę pęřįőđ ĥäş ŧőő mäʼny ęvęʼnŧş ŧő đįşpľäy. Đįpľäyįʼnģ ŧĥę ľäŧęşŧ 5000 ęvęʼnŧş. Ŧřy ūşįʼnģ ä şĥőřŧęř ŧįmę pęřįőđ.", - "title": "Ůʼnäþľę ŧő đįşpľäy äľľ ęvęʼnŧş" - } - }, - "common": { - "cancel": "Cäʼnčęľ", - "clear-filters": "Cľęäř ƒįľŧęřş", - "delete": "Đęľęŧę", - "edit": "Ēđįŧ", - "export": "Ēχpőřŧ", - "export-all": "Ēχpőřŧ äľľ", - "loading": "Ŀőäđįʼnģ...", - "search-by-matchers": "Ŝęäřčĥ þy mäŧčĥęřş", - "titles": { - "notification-templates": "Ńőŧįƒįčäŧįőʼn Ŧęmpľäŧęş" - }, - "view": "Vįęŵ" - }, - "contact-points": { - "create": "Cřęäŧę čőʼnŧäčŧ pőįʼnŧ", - "custom-template-value": "Cūşŧőm ŧęmpľäŧę väľūę", - "delete-reasons": { - "heading": "Cőʼnŧäčŧ pőįʼnŧ čäʼnʼnőŧ þę đęľęŧęđ ƒőř ŧĥę ƒőľľőŵįʼnģ řęäşőʼnş:", - "no-permissions": "Ÿőū đő ʼnőŧ ĥävę ŧĥę řęqūįřęđ pęřmįşşįőʼn ŧő đęľęŧę ŧĥįş čőʼnŧäčŧ pőįʼnŧ", - "policies": "Cőʼnŧäčŧ pőįʼnŧ įş řęƒęřęʼnčęđ þy őʼnę őř mőřę ʼnőŧįƒįčäŧįőʼn pőľįčįęş", - "provisioned": "Cőʼnŧäčŧ pőįʼnŧ įş přővįşįőʼnęđ äʼnđ čäʼnʼnőŧ þę đęľęŧęđ vįä ŧĥę ŮĨ", - "rules": "Cőʼnŧäčŧ pőįʼnŧ įş řęƒęřęʼnčęđ þy őʼnę őř mőřę äľęřŧ řūľęş" - }, - "delivered-to": "Đęľįvęřęđ ŧő", - "delivery-duration": "Ŀäşŧ đęľįvęřy ŧőőĸ <1>", - "empty-state": { - "title": "Ÿőū đőʼn'ŧ ĥävę äʼny čőʼnŧäčŧ pőįʼnŧş yęŧ" - }, - "key-value-map": { - "add": "Åđđ", - "confirm-add": "Cőʼnƒįřm ŧő äđđ" - }, - "last-delivery-attempt": "Ŀäşŧ đęľįvęřy äŧŧęmpŧ", - "last-delivery-failed": "Ŀäşŧ đęľįvęřy äŧŧęmpŧ ƒäįľęđ", - "no-contact-points-found": "Ńő čőʼnŧäčŧ pőįʼnŧş ƒőūʼnđ", - "no-delivery-attempts": "Ńő đęľįvęřy äŧŧęmpŧş", - "no-integrations": "Ńő įʼnŧęģřäŧįőʼnş čőʼnƒįģūřęđ", - "only-firing": "Đęľįvęřįʼnģ <1>őʼnľy ƒįřįʼnģ ʼnőŧįƒįčäŧįőʼnş", - "receiver-summary": { - "jira": "Cřęäŧęş ä \"{{issueType}}\" įşşūę įʼn ŧĥę \"{{project}}\" přőĵęčŧ" - }, - "telegram": { - "parse-mode-warning-body": "Ĩƒ yőū ūşę ä <1>päřşę_mőđę őpŧįőʼn őŧĥęř ŧĥäʼn <3>Ńőʼnę, ŧřūʼnčäŧįőʼn mäy řęşūľŧ įʼn äʼn įʼnväľįđ męşşäģę, čäūşįʼnģ ŧĥę ʼnőŧįƒįčäŧįőʼn ŧő ƒäįľ. Főř ľőʼnģęř męşşäģęş, ŵę řęčőmmęʼnđ ūşįʼnģ äʼn äľŧęřʼnäŧįvę čőʼnŧäčŧ męŧĥőđ.", - "parse-mode-warning-title": "Ŧęľęģřäm męşşäģęş äřę ľįmįŧęđ ŧő 4096 ŮŦF-8 čĥäřäčŧęřş." - }, - "used-by_one": "Ůşęđ þy {{ count }} ʼnőŧįƒįčäŧįőʼn pőľįčy", - "used-by_other": "Ůşęđ þy {{ count }} ʼnőŧįƒįčäŧįőʼn pőľįčy", - "used-by-rules_one": "Ůşęđ þy {{ count }} äľęřŧ řūľę", - "used-by-rules_other": "Ůşęđ þy {{ count }} äľęřŧ řūľę" - }, - "contactPointFilter": { - "label": "Cőʼnŧäčŧ pőįʼnŧ" - }, - "copy-to-clipboard": "Cőpy \"{{label}}\" ŧő čľįpþőäřđ", - "dag": { - "missing-reference": "Ēχpřęşşįőʼn \"{{source}}\" ƒäįľęđ ŧő řūʼn þęčäūşę \"{{target}}\" įş mįşşįʼnģ őř äľşő ƒäįľęđ.", - "self-reference": "Ÿőū čäʼn'ŧ ľįʼnĸ äʼn ęχpřęşşįőʼn ŧő įŧşęľƒ" - }, - "export": { - "subtitle": { - "formats": "Ŝęľęčŧ ŧĥę ƒőřmäŧ äʼnđ đőŵʼnľőäđ ŧĥę ƒįľę őř čőpy ŧĥę čőʼnŧęʼnŧş ŧő čľįpþőäřđ", - "one-format": "Đőŵʼnľőäđ ŧĥę ƒįľę őř čőpy ŧĥę čőʼnŧęʼnŧş ŧő čľįpþőäřđ" - } - }, - "folderAndGroup": { - "evaluation": { - "modal": { - "text": { - "alerting": "Cřęäŧę ä ʼnęŵ ęväľūäŧįőʼn ģřőūp ŧő ūşę ƒőř ŧĥįş äľęřŧ řūľę.", - "recording": "Cřęäŧę ä ʼnęŵ ęväľūäŧįőʼn ģřőūp ŧő ūşę ƒőř ŧĥįş řęčőřđįʼnģ řūľę." - } - } - } - }, - "group-actions": { - "actions-trigger": "Ŗūľę ģřőūp äčŧįőʼnş", - "delete": "Đęľęŧę", - "edit": "Ēđįŧ", - "export": "Ēχpőřŧ", - "reorder": "Ŗę-őřđęř řūľęş" - }, - "list-view": { - "empty": { - "new-alert-rule": "Ńęŵ äľęřŧ řūľę", - "new-recording-rule": "Ńęŵ řęčőřđįʼnģ řūľę", - "provisioning": "Ÿőū čäʼn äľşő đęƒįʼnę řūľęş ŧĥřőūģĥ ƒįľę přővįşįőʼnįʼnģ őř Ŧęřřäƒőřm. <2>Ŀęäřʼn mőřę" - }, - "section": { - "dataSourceManaged": { - "title": "Đäŧä şőūřčę-mäʼnäģęđ" - }, - "grafanaManaged": { - "export-new-rule": "Ēχpőřŧ řūľę đęƒįʼnįŧįőʼn", - "export-rules": "Ēχpőřŧ řūľęş", - "loading": "Ŀőäđįʼnģ...", - "new-recording-rule": "Ńęŵ řęčőřđįʼnģ řūľę", - "title": "Ğřäƒäʼnä-mäʼnäģęđ" - } - } - }, - "manage-permissions": { - "button": "Mäʼnäģę pęřmįşşįőʼnş", - "title": "Mäʼnäģę pęřmįşşįőʼnş" - }, - "mute_timings": { - "error-loading": { - "description": "Cőūľđ ʼnőŧ ľőäđ mūŧę ŧįmįʼnģş. Pľęäşę ŧřy äģäįʼn ľäŧęř.", - "title": "Ēřřőř ľőäđįʼnģ mūŧę ŧįmįʼnģş" - } - }, - "mute-timings": { - "add-mute-timing": "Åđđ mūŧę ŧįmįʼnģ", - "description": "Ēʼnŧęř şpęčįƒįč ŧįmę įʼnŧęřväľş ŵĥęʼn ʼnőŧ ŧő şęʼnđ ʼnőŧįƒįčäŧįőʼnş őř ƒřęęžę ʼnőŧįƒįčäŧįőʼnş ƒőř řęčūřřįʼnģ pęřįőđş őƒ ŧįmę.", - "save": "Ŝävę mūŧę ŧįmįʼnģ", - "saving": "Ŝävįʼnģ mūŧę ŧįmįʼnģ" - }, - "notification-preview": { - "alertmanager": "Åľęřŧmäʼnäģęř:", - "error": "Cőūľđ ʼnőŧ ľőäđ řőūŧįʼnģ přęvįęŵ ƒőř {{alertmanager}}", - "initialized": "ßäşęđ őʼn ŧĥę ľäþęľş äđđęđ, äľęřŧ įʼnşŧäʼnčęş äřę řőūŧęđ ŧő ŧĥę ƒőľľőŵįʼnģ ʼnőŧįƒįčäŧįőʼn pőľįčįęş. Ēχpäʼnđ ęäčĥ ʼnőŧįƒįčäŧįőʼn pőľįčy þęľőŵ ŧő vįęŵ mőřę đęŧäįľş.", - "preview-routing": "Přęvįęŵ řőūŧįʼnģ", - "title": "Åľęřŧ įʼnşŧäʼnčę řőūŧįʼnģ přęvįęŵ", - "uninitialized": "Ŵĥęʼn yőū ĥävę yőūř ƒőľđęř şęľęčŧęđ äʼnđ yőūř qūęřy äʼnđ ľäþęľş äřę čőʼnƒįģūřęđ, čľįčĸ \"Přęvįęŵ řőūŧįʼnģ\" ŧő şęę ŧĥę řęşūľŧş ĥęřę." - }, - "notification-templates": { - "duplicate": { - "subTitle": "Đūpľįčäŧę ä ģřőūp őƒ ʼnőŧįƒįčäŧįőʼn ŧęmpľäŧęş", - "title": "Đūpľįčäŧę ʼnőŧįƒįčäŧįőʼn ŧęmpľäŧę ģřőūp" - }, - "edit": { - "subTitle": "Ēđįŧ ä ģřőūp őƒ ʼnőŧįƒįčäŧįőʼn ŧęmpľäŧęş", - "title": "Ēđįŧ ʼnőŧįƒįčäŧįőʼn ŧęmpľäŧę ģřőūp" - }, - "new": { - "subTitle": "Cřęäŧę ä ʼnęŵ ģřőūp őƒ ʼnőŧįƒįčäŧįőʼn ŧęmpľäŧęş", - "title": "Ńęŵ ʼnőŧįƒįčäŧįőʼn ŧęmpľäŧę ģřőūp" - } - }, - "policies": { - "default-policy": { - "description": "Åľľ äľęřŧ įʼnşŧäʼnčęş ŵįľľ þę ĥäʼnđľęđ þy ŧĥę đęƒäūľŧ pőľįčy įƒ ʼnő őŧĥęř mäŧčĥįʼnģ pőľįčįęş äřę ƒőūʼnđ.", - "title": "Đęƒäūľŧ pőľįčy", - "update": "Ůpđäŧę đęƒäūľŧ pőľįčy" - }, - "delete": { - "confirm": "Ÿęş, đęľęŧę pőľįčy", - "warning-1": "Đęľęŧįʼnģ ŧĥįş ʼnőŧįƒįčäŧįőʼn pőľįčy ŵįľľ pęřmäʼnęʼnŧľy řęmővę įŧ.", - "warning-2": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő đęľęŧę ŧĥįş pőľįčy?" - }, - "filter-description": "Fįľŧęř ʼnőŧįƒįčäŧįőʼn pőľįčįęş þy ūşįʼnģ ä čőmmä şępäřäŧęđ ľįşŧ őƒ mäŧčĥęřş, ę.ģ.:<1>şęvęřįŧy=čřįŧįčäľ, řęģįőʼn=ĒMĒÅ", - "generated-policies": "Åūŧő-ģęʼnęřäŧęđ pőľįčįęş", - "matchers": "Mäŧčĥęřş", - "metadata": { - "active-time": "Åčŧįvę ŵĥęʼn", - "delivered-to": "Đęľįvęřęđ ŧő", - "grouped-by": "Ğřőūpęđ þy", - "grouping": { - "none": "Ńőŧ ģřőūpįʼnģ", - "single-group": "Ŝįʼnģľę ģřőūp" - }, - "inherited": "Ĩʼnĥęřįŧęđ", - "mute-time": "Mūŧęđ ŵĥęʼn", - "n-instances_one": "įʼnşŧäʼnčę", - "n-instances_other": "įʼnşŧäʼnčę", - "timingOptions": { - "groupInterval": { - "description": "Ħőŵ ľőʼnģ ŧő ŵäįŧ þęƒőřę şęʼnđįʼnģ ä ʼnőŧįƒįčäŧįőʼn äþőūŧ ʼnęŵ äľęřŧş ŧĥäŧ äřę äđđęđ ŧő ä ģřőūp őƒ äľęřŧş ƒőř ŵĥįčĥ äʼn įʼnįŧįäľ ʼnőŧįƒįčäŧįőʼn ĥäş äľřęäđy þęęʼn şęʼnŧ.", - "label": "Ŵäįŧ <1> þęƒőřę şęʼnđįʼnģ ūpđäŧęş" - }, - "groupWait": { - "description": "Ħőŵ ľőʼnģ ŧő įʼnįŧįäľľy ŵäįŧ ŧő şęʼnđ ä ʼnőŧįƒįčäŧįőʼn ƒőř ä ģřőūp őƒ äľęřŧ įʼnşŧäʼnčęş.", - "label": "Ŵäįŧ <1> ŧő ģřőūp įʼnşŧäʼnčęş" - }, - "repeatInterval": { - "description": "Ħőŵ őƒŧęʼn ʼnőŧįƒįčäŧįőʼnş äřę şęʼnŧ įƒ ŧĥę ģřőūp őƒ äľęřŧş ĥäş ʼnőŧ čĥäʼnģęđ şįʼnčę ŧĥę ľäşŧ ʼnőŧįƒįčäŧįőʼn.", - "label": "Ŗępęäŧęđ ęvęřy <1>" - } - } - }, - "n-more-policies_one": "{{count}} äđđįŧįőʼnäľ pőľįčįęş", - "n-more-policies_other": "{{count}} äđđįŧįőʼnäľ pőľįčįęş", - "new-child": "Ńęŵ čĥįľđ pőľįčy", - "new-policy": "Åđđ ʼnęŵ pőľįčy", - "no-matchers": "Ńő mäŧčĥęřş", - "reload-policies": "Ŗęľőäđ pőľįčįęş", - "save-policy": "Ŝävę pőľįčy", - "update": { - "please-wait": "Pľęäşę ŵäįŧ ŵĥįľę ŵę ūpđäŧę yőūř ʼnőŧįƒįčäŧįőʼn pőľįčįęş.", - "update-policy": "Ůpđäŧę pőľįčy", - "updating": "Ůpđäŧįʼnģ..." - }, - "update-errors": { - "conflict": "Ŧĥę ʼnőŧįƒįčäŧįőʼn pőľįčy ŧřęę ĥäş þęęʼn ūpđäŧęđ þy äʼnőŧĥęř ūşęř.", - "error-code": "Ēřřőř męşşäģę: \"{{error}}\"", - "fallback": "Ŝőmęŧĥįʼnģ ŵęʼnŧ ŵřőʼnģ ŵĥęʼn ūpđäŧįʼnģ yőūř ʼnőŧįƒįčäŧįőʼn pőľįčįęş.", - "suffix": "Pľęäşę řęƒřęşĥ ŧĥę päģę äʼnđ ŧřy äģäįʼn.", - "title": "Ēřřőř şävįʼnģ ʼnőŧįƒįčäŧįőʼn pőľįčy" - } - }, - "provisioning": { - "badge-tooltip-provenance": "Ŧĥįş řęşőūřčę ĥäş þęęʼn přővįşįőʼnęđ vįä {{provenance}} äʼnđ čäʼnʼnőŧ þę ęđįŧęđ ŧĥřőūģĥ ŧĥę ŮĨ", - "badge-tooltip-standard": "Ŧĥįş řęşőūřčę ĥäş þęęʼn přővįşįőʼnęđ äʼnđ čäʼnʼnőŧ þę ęđįŧęđ ŧĥřőūģĥ ŧĥę ŮĨ" - }, - "queryAndExpressionsStep": { - "disableAdvancedOptions": { - "text": "Ŧĥę şęľęčŧęđ qūęřįęş äʼnđ ęχpřęşşįőʼnş čäʼnʼnőŧ þę čőʼnvęřŧęđ ŧő đęƒäūľŧ. Ĩƒ yőū đęäčŧįväŧę äđväʼnčęđ őpŧįőʼnş, yőūř qūęřy äʼnđ čőʼnđįŧįőʼn ŵįľľ þę řęşęŧ ŧő đęƒäūľŧ şęŧŧįʼnģş." - }, - "preview": "Přęvįęŵ", - "previewCondition": "Přęvįęŵ äľęřŧ řūľę čőʼnđįŧįőʼn" - }, - "rule-form": { - "evaluation": { - "evaluation-group-and-interval": "Ēväľūäŧįőʼn ģřőūp äʼnđ įʼnŧęřväľ", - "group": { - "cancel": "Cäʼnčęľ", - "create": "Cřęäŧę", - "interval": "Ēväľūäŧįőʼn įʼnŧęřväľ" - }, - "group-name": "Ēväľūäŧįőʼn ģřőūp ʼnämę", - "group-text": "Åľľ řūľęş įʼn ŧĥę şęľęčŧęđ ģřőūp äřę ęväľūäŧęđ ęvęřy {{evaluateEvery}}.", - "new-group": "Ńęŵ ęväľūäŧįőʼn ģřőūp", - "pause": { - "alerting": "Ŧūřʼn őʼn ŧő päūşę ęväľūäŧįőʼn ƒőř ŧĥįş äľęřŧ řūľę.", - "recording": "Ŧūřʼn őʼn ŧő päūşę ęväľūäŧįőʼn ƒőř ŧĥįş řęčőřđįʼnģ řūľę." - }, - "select-folder-before": "Ŝęľęčŧ ä ƒőľđęř þęƒőřę şęŧŧįʼnģ ęväľūäŧįőʼn ģřőūp äʼnđ įʼnŧęřväľ" - }, - "evaluation-behaviour": { - "description": { - "text": "Đęƒįʼnę ĥőŵ ŧĥę äľęřŧ řūľę įş ęväľūäŧęđ." - }, - "info-help": { - "text": "Đęƒįʼnę ŧĥę äľęřŧ þęĥävįőř ŵĥęʼn ŧĥę ęväľūäŧįőʼn ƒäįľş őř ŧĥę qūęřy řęŧūřʼnş ʼnő đäŧä." - }, - "pending-period": "Pęʼnđįʼnģ pęřįőđ" - }, - "evaluation-behaviour-description1": "Ēväľūäŧįőʼn ģřőūpş äřę čőʼnŧäįʼnęřş ƒőř ęväľūäŧįʼnģ äľęřŧ äʼnđ řęčőřđįʼnģ řūľęş.", - "evaluation-behaviour-description2": "Åʼn ęväľūäŧįőʼn ģřőūp đęƒįʼnęş äʼn ęväľūäŧįőʼn įʼnŧęřväľ - ĥőŵ őƒŧęʼn ä řūľę įş ęväľūäŧęđ. Åľęřŧ řūľęş ŵįŧĥįʼn ŧĥę şämę ęväľūäŧįőʼn ģřőūp äřę ęväľūäŧęđ ővęř ŧĥę şämę ęväľūäŧįőʼn įʼnŧęřväľ.", - "evaluation-behaviour-description3": "Pęʼnđįʼnģ pęřįőđ şpęčįƒįęş ĥőŵ ľőʼnģ ŧĥę ŧĥřęşĥőľđ čőʼnđįŧįőʼn mūşŧ þę męŧ þęƒőřę ŧĥę äľęřŧ şŧäřŧş ƒįřįʼnģ. Ŧĥįş őpŧįőʼn ĥęľpş přęvęʼnŧ äľęřŧş ƒřőm þęįʼnģ ŧřįģģęřęđ þy ŧęmpőřäřy įşşūęş.", - "evaluation-behaviour-for": { - "error-parsing": "Fäįľęđ ŧő päřşę đūřäŧįőʼn", - "validation": "Pęʼnđįʼnģ pęřįőđ mūşŧ þę ģřęäŧęř ŧĥäʼn őř ęqūäľ ŧő ŧĥę ęväľūäŧįőʼn įʼnŧęřväľ." - }, - "folder": { - "cancel": "Cäʼnčęľ", - "create": "Cřęäŧę", - "create-folder": "Cřęäŧę ä ʼnęŵ ƒőľđęř ŧő şŧőřę yőūř äľęřŧ řūľę įʼn.", - "creating-new-folder": "Cřęäŧįʼnģ ʼnęŵ ƒőľđęř", - "label": "Főľđęř", - "name": "Főľđęř ʼnämę", - "new-folder": "Ńęŵ ƒőľđęř", - "new-folder-or": "őř" - }, - "folder-and-labels": "Øřģäʼnįžę yőūř äľęřŧ řūľę ŵįŧĥ ä ƒőľđęř äʼnđ şęŧ őƒ ľäþęľş.", - "folders": { - "help-info": "Főľđęřş äřę ūşęđ ƒőř şŧőřįʼnģ äľęřŧ řūľęş. Ÿőū čäʼn ęχŧęʼnđ ŧĥę äččęşş přővįđęđ þy ä řőľę ŧő äľęřŧ řūľęş äʼnđ äşşįģʼn pęřmįşşįőʼnş ŧő įʼnđįvįđūäľ ƒőľđęřş." - }, - "labels": { - "help-info": "Ŀäþęľş äřę ūşęđ ŧő đįƒƒęřęʼnŧįäŧę äʼn äľęřŧ ƒřőm äľľ őŧĥęř äľęřŧş.Ÿőū čäʼn ūşę ŧĥęm ƒőř şęäřčĥįʼnģ, şįľęʼnčįʼnģ, äʼnđ řőūŧįʼnģ ʼnőŧįƒįčäŧįőʼnş." - }, - "pause": { - "label": "Päūşę ęväľūäŧįőʼn" - }, - "threshold": { - "recovery": { - "stop-alerting-above": "Ŝŧőp äľęřŧįʼnģ ŵĥęʼn äþővę", - "stop-alerting-bellow": "Ŝŧőp äľęřŧįʼnģ ŵĥęʼn þęľőŵ", - "stop-alerting-equal": "Ŝŧőp äľęřŧįʼnģ ŵĥęʼn ęqūäľ ŧő", - "stop-alerting-inside-range": "Ŝŧőp äľęřŧįʼnģ ŵĥęʼn įʼnşįđę řäʼnģę", - "stop-alerting-less": "Ŝŧőp äľęřŧįʼnģ ŵĥęʼn ľęşş ŧĥäʼn", - "stop-alerting-more": "Ŝŧőp äľęřŧįʼnģ ŵĥęʼn mőřę ŧĥäʼn", - "stop-alerting-not-equal": "Ŝŧőp äľęřŧįʼnģ ŵĥęʼn ʼnőŧ ęqūäľ ŧő", - "stop-alerting-outside-range": "Ŝŧőp äľęřŧįʼnģ ŵĥęʼn őūŧşįđę řäʼnģę", - "title": "Cūşŧőm řęčővęřy ŧĥřęşĥőľđ" - } - } - }, - "rule-groups": { - "delete": { - "success": "Ŝūččęşşƒūľľy đęľęŧęđ řūľę ģřőūp" - }, - "move": { - "success": "Ŝūččęşşƒūľľy mővęđ řūľę ģřőūp" - }, - "rename": { - "success": "Ŝūččęşşƒūľľy řęʼnämęđ řūľę ģřőūp" - }, - "update": { - "success": "Ŝūččęşşƒūľľy ūpđäŧęđ řūľę ģřőūp" - } - }, - "rule-list": { - "configure-datasource": "Cőʼnƒįģūřę", - "ds-error-boundary": { - "description": "Cĥęčĸ ŧĥę đäŧä şőūřčę čőʼnƒįģūřäŧįőʼn. Đőęş ŧĥę đäŧä şőūřčę şūppőřŧ Přőmęŧĥęūş ÅPĨ?", - "title": "Ůʼnäþľę ŧő ľőäđ řūľęş ƒřőm ŧĥįş đäŧä şőūřčę" - }, - "filter-view": { - "no-more-results": "Ńő mőřę řęşūľŧş – şĥőŵįʼnģ {{numberOfRules}} řūľęş", - "no-rules-found": "Ńő äľęřŧ őř řęčőřđįʼnģ řūľęş mäŧčĥęđ yőūř čūřřęʼnŧ şęŧ őƒ ƒįľŧęřş." - }, - "new-alert-rule": "Ńęŵ äľęřŧ řūľę", - "pagination": { - "next-page": "ʼnęχŧ päģę", - "previous-page": "přęvįőūş päģę" - }, - "return-button": { - "title": "Åľęřŧ řūľęş" - }, - "rulerrule-loading-error": "Fäįľęđ ŧő ľőäđ ŧĥę řūľę" - }, - "rule-state": { - "creating": "Cřęäŧįʼnģ", - "deleting": "Đęľęŧįʼnģ", - "paused": "Päūşęđ", - "recording-rule": "Ŗęčőřđįʼnģ řūľę" - }, - "rule-view": { - "query": { - "datasources-na": { - "description": "Cäʼnʼnőŧ đįşpľäy ŧĥę qūęřy přęvįęŵ. Ŝőmę őƒ ŧĥę đäŧä şőūřčęş ūşęđ įʼn ŧĥę qūęřįęş äřę ʼnőŧ äväįľäþľę.", - "title": "Qūęřy ʼnőŧ äväįľäþľę" - } - } - }, - "rule-viewer": { - "error-loading": "Ŝőmęŧĥįʼnģ ŵęʼnŧ ŵřőʼnģ ľőäđįʼnģ ŧĥę řūľę", - "prometheus-consistency-check": { - "alert-message": "Åľęřŧ řūľę ĥäş þęęʼn ūpđäŧęđ. Cĥäʼnģęş mäy ŧäĸę ūp ŧő ä mįʼnūŧę ŧő äppęäř őʼn ŧĥę Åľęřŧ řūľęş ľįşŧ vįęŵ.", - "alert-title": "Ůpđäŧę įʼn přőģřęşş" - } - }, - "rules": { - "add-rule": { - "success": "Ŗūľę äđđęđ şūččęşşƒūľľy" - }, - "delete-rule": { - "success": "Ŗūľę şūččęşşƒūľľy đęľęŧęđ" - }, - "pause-rule": { - "success": "Ŗūľę ęväľūäŧįőʼn päūşęđ" - }, - "resume-rule": { - "success": "Ŗūľę ęväľūäŧįőʼn řęşūmęđ" - }, - "update-rule": { - "success": "Ŗūľę ūpđäŧęđ şūččęşşƒūľľy" - } - }, - "search": { - "property": { - "data-source": "Đäŧä şőūřčę", - "evaluation-group": "Ēväľūäŧįőʼn ģřőūp", - "labels": "Ŀäþęľş", - "namespace": "Főľđęř / Ńämęşpäčę", - "rule-health": "Ħęäľŧĥ", - "rule-name": "Åľęřŧįʼnģ řūľę ʼnämę", - "rule-type": "Ŧypę", - "state": "Ŝŧäŧę" - }, - "save-query": "Ŝävę čūřřęʼnŧ şęäřčĥ" - }, - "silences": { - "affected-instances": "Ńƒęčŧęđ äľęřŧ įʼnşŧäʼnčęş", - "only-firing-instances": "Øʼnľy äľęřŧ įʼnşŧäʼnčęş įʼn ŧĥę ƒįřįʼnģ şŧäŧę äřę đįşpľäyęđ.", - "preview-affected-instances": "Přęvįęŵ ŧĥę äľęřŧ įʼnşŧäʼnčęş äƒƒęčŧęđ þy ŧĥįş şįľęʼnčę." - }, - "simpleCondition": { - "alertCondition": "Åľęřŧ čőʼnđįŧįőʼn" - }, - "templates": { - "editor": { - "add-example": "Åđđ ęχämpľę", - "auto-complete": "Főř äūŧő-čőmpľęŧįőʼn őƒ čőmmőʼn ŧęmpľäŧįʼnģ čőđę, ŧypę ŧĥę ƒőľľőŵįʼnģ ĸęyŵőřđş įʼn ŧĥę čőʼnŧęʼnŧ ęđįŧőř:", - "goto-docs": "Ńőŧįƒįčäŧįőʼn ŧęmpľäŧęş đőčūmęʼnŧäŧįőʼn" - }, - "help": { - "intro": "Ńőŧįƒįčäŧįőʼn ŧęmpľäŧęş ūşę Ğő ŧęmpľäŧįʼnģ ľäʼnģūäģę ŧő čřęäŧę ʼnőŧįƒįčäŧįőʼn męşşäģęş.\n\nĨʼn Ğřäƒäʼnä, ä ŧęmpľäŧę ģřőūp čäʼn đęƒįʼnę mūľŧįpľę ʼnőŧįƒįčäŧįőʼn ŧęmpľäŧęş ūşįʼnģ {{ define \"\" }}.\nŦĥęşę ŧęmpľäŧęş čäʼn ŧĥęʼn þę ūşęđ įʼn čőʼnŧäčŧ pőįʼnŧş äʼnđ ŵįŧĥįʼn őŧĥęř ʼnőŧįƒįčäŧįőʼn ŧęmpľäŧęş þy čäľľįʼnģ {{ template \"\" }}.\nFőř đęŧäįľęđ įʼnƒőřmäŧįőʼn äþőūŧ ʼnőŧįƒįčäŧįőʼn ŧęmpľäŧęş, řęƒęř ŧő őūř đőčūmęʼnŧäŧįőʼn." - }, - "misconfigured-badge-text": "Mįşčőʼnƒįģūřęđ", - "misconfigured-warning": "Ŧĥįş ŧęmpľäŧę įş mįşčőʼnƒįģūřęđ.", - "misconfigured-warning-details": "Ŧęmpľäŧęş mūşŧ þę đęƒįʼnęđ įʼn þőŧĥ ŧĥę <1> äʼnđ <4> şęčŧįőʼnş őƒ yőūř äľęřŧmäʼnäģęř čőʼnƒįģūřäŧįőʼn." - }, - "threshold": { - "to": "ŦØ" - } - }, - "annotations": { - "empty-state": { - "button-title": "Åđđ äʼnʼnőŧäŧįőʼn qūęřy", - "info-box-content": "<0>Åʼnʼnőŧäŧįőʼnş přővįđę ä ŵäy ŧő įʼnŧęģřäŧę ęvęʼnŧ đäŧä įʼnŧő yőūř ģřäpĥş. Ŧĥęy äřę vįşūäľįžęđ äş vęřŧįčäľ ľįʼnęş äʼnđ įčőʼnş őʼn äľľ ģřäpĥ päʼnęľş. Ŵĥęʼn yőū ĥővęř ővęř äʼn äʼnʼnőŧäŧįőʼn įčőʼn yőū čäʼn ģęŧ ęvęʼnŧ ŧęχŧ & ŧäģş ƒőř ŧĥę ęvęʼnŧ. Ÿőū čäʼn äđđ äʼnʼnőŧäŧįőʼn ęvęʼnŧş đįřęčŧľy ƒřőm ģřäƒäʼnä þy ĥőľđįʼnģ CŦŖĿ őř CMĐ + čľįčĸ őʼn ģřäpĥ (őř đřäģ řęģįőʼn). Ŧĥęşę ŵįľľ þę şŧőřęđ įʼn Ğřäƒäʼnä'ş äʼnʼnőŧäŧįőʼn đäŧäþäşę.", - "info-box-content-2": "Cĥęčĸőūŧ ŧĥę <2>Åʼnʼnőŧäŧįőʼnş đőčūmęʼnŧäŧįőʼn ƒőř mőřę įʼnƒőřmäŧįőʼn.", - "title": "Ŧĥęřę äřę ʼnő čūşŧőm äʼnʼnőŧäŧįőʼn qūęřįęş äđđęđ yęŧ" - } - }, - "api-keys": { - "empty-state": { - "message": "Ńő ÅPĨ ĸęyş ƒőūʼnđ" - } - }, - "app-chrome": { - "skip-content-button": "Ŝĸįp ŧő mäįʼn čőʼnŧęʼnŧ", - "top-bar": { - "sign-in": "Ŝįģʼn įʼn" - } - }, - "app-notification": { - "item": { - "trace-id": "Ŧřäčę ĨĐ: {{traceId}}" - } - }, - "bookmarks-page": { - "empty": { - "message": "Ĩŧ ľőőĸş ľįĸę yőū ĥävęʼn’ŧ čřęäŧęđ äʼny þőőĸmäřĸş yęŧ", - "tip": "Ħővęř ővęř äʼny įŧęm įʼn ŧĥę ʼnäv męʼnū äʼnđ čľįčĸ őʼn ŧĥę þőőĸmäřĸ įčőʼn ŧő äđđ įŧ ĥęřę." - } - }, - "bouncing-loader": { - "label": "Ŀőäđįʼnģ" - }, - "browse-dashboards": { - "action": { - "cancel-button": "Cäʼnčęľ", - "cannot-move-folders": "Főľđęřş čäʼnʼnőŧ þę mővęđ", - "confirmation-text": "Đęľęŧę", - "delete-button": "Đęľęŧę", - "delete-modal-invalid-text": "Øʼnę őř mőřę ƒőľđęřş čőʼnŧäįʼn ľįþřäřy päʼnęľş őř äľęřŧ řūľęş. Đęľęŧę ŧĥęşę ƒįřşŧ įʼn őřđęř ŧő přőčęęđ.", - "delete-modal-invalid-title": "Cäʼnʼnőŧ đęľęŧę ƒőľđęř", - "delete-modal-restore-dashboards-text": "Ŧĥįş äčŧįőʼn ŵįľľ đęľęŧę ŧĥę şęľęčŧęđ ƒőľđęřş įmmęđįäŧęľy þūŧ ŧĥę şęľęčŧęđ đäşĥþőäřđş ŵįľľ þę mäřĸęđ ƒőř đęľęŧįőʼn įʼn 30 đäyş. Ÿőūř őřģäʼnįžäŧįőʼn äđmįʼnįşŧřäŧőř čäʼn řęşŧőřę ŧĥę đäşĥþőäřđş äʼnyŧįmę þęƒőřę ŧĥę 30 đäyş ęχpįřę. Főľđęřş čäʼnʼnőŧ þę řęşŧőřęđ.", - "delete-modal-text": "Ŧĥįş äčŧįőʼn ŵįľľ đęľęŧę ŧĥę ƒőľľőŵįʼnģ čőʼnŧęʼnŧ:", - "delete-modal-title": "Đęľęŧę", - "deleting": "Đęľęŧįʼnģ...", - "manage-permissions-button": "Mäʼnäģę pęřmįşşįőʼnş", - "move-button": "Mővę", - "move-modal-alert": "Mővįʼnģ ŧĥįş įŧęm mäy čĥäʼnģę įŧş pęřmįşşįőʼnş.", - "move-modal-field-label": "Főľđęř ʼnämę", - "move-modal-text": "Ŧĥįş äčŧįőʼn ŵįľľ mővę ŧĥę ƒőľľőŵįʼnģ čőʼnŧęʼnŧ:", - "move-modal-title": "Mővę", - "moving": "Mővįʼnģ...", - "new-folder-name-required-phrase": "Főľđęř ʼnämę įş řęqūįřęđ." - }, - "actions": { - "button-to-recently-deleted": "Ŗęčęʼnŧľy đęľęŧęđ" - }, - "counts": { - "alertRule_one": "{{count}} äľęřŧ řūľę", - "alertRule_other": "{{count}} äľęřŧ řūľę", - "dashboard_one": "{{count}} đäşĥþőäřđ", - "dashboard_other": "{{count}} đäşĥþőäřđ", - "folder_one": "{{count}} ƒőľđęř", - "folder_other": "{{count}} ƒőľđęř", - "libraryPanel_one": "{{count}} ľįþřäřy päʼnęľ", - "libraryPanel_other": "{{count}} ľįþřäřy päʼnęľ", - "total_one": "{{count}} įŧęm", - "total_other": "{{count}} įŧęm" - }, - "dashboards-tree": { - "collapse-folder-button": "Cőľľäpşę ƒőľđęř {{title}}", - "expand-folder-button": "Ēχpäʼnđ ƒőľđęř {{title}}", - "name-column": "Ńämę", - "select-all-header-checkbox": "Ŝęľęčŧ äľľ", - "select-checkbox": "Ŝęľęčŧ", - "tags-column": "Ŧäģş" - }, - "empty-state": { - "button-title": "Cřęäŧę đäşĥþőäřđ", - "pro-tip": "Åđđ/mővę đäşĥþőäřđş ŧő yőūř ƒőľđęř äŧ <2>ßřőŵşę đäşĥþőäřđş", - "title": "Ÿőū ĥävęʼn'ŧ čřęäŧęđ äʼny đäşĥþőäřđş yęŧ", - "title-folder": "Ŧĥįş ƒőľđęř đőęşʼn'ŧ ĥävę äʼny đäşĥþőäřđş yęŧ" - }, - "folder-actions-button": { - "delete": "Đęľęŧę", - "folder-actions": "Főľđęř äčŧįőʼnş", - "manage-permissions": "Mäʼnäģę pęřmįşşįőʼnş", - "move": "Mővę" - }, - "folder-picker": { - "accessible-label": "Ŝęľęčŧ ƒőľđęř: {{ label }} čūřřęʼnŧľy şęľęčŧęđ", - "button-label": "Ŝęľęčŧ ƒőľđęř", - "clear-selection": "Cľęäř şęľęčŧįőʼn", - "empty-message": "Ńő ƒőľđęřş ƒőūʼnđ", - "error-title": "Ēřřőř ľőäđįʼnģ ƒőľđęřş", - "non-folder-item": "Ńőʼn-ƒőľđęř {{itemKind}} {{itemUID}}", - "search-placeholder": "Ŝęäřčĥ ƒőľđęřş", - "unknown-error": "Ůʼnĸʼnőŵʼn ęřřőř" - }, - "hard-delete": { - "success": "Đäşĥþőäřđ {{name}} đęľęŧęđ" - }, - "manage-folder-nav": { - "alert-rules": "Åľęřŧ řūľęş", - "dashboards": "Đäşĥþőäřđş", - "panels": "Päʼnęľş" - }, - "new-folder-form": { - "cancel-label": "Cäʼnčęľ", - "create-label": "Cřęäŧę", - "name-label": "Főľđęř ʼnämę" - }, - "no-results": { - "clear": "Cľęäř şęäřčĥ äʼnđ ƒįľŧęřş", - "text": "Ńő řęşūľŧş ƒőūʼnđ ƒőř yőūř qūęřy" - }, - "soft-delete": { - "success": "Đäşĥþőäřđ {{name}} mővęđ ŧő Ŗęčęʼnŧľy đęľęŧęđ" - } - }, - "clipboard-button": { - "inline-toast": { - "success": "Cőpįęđ" - } - }, - "combobox": { - "async": { - "error": "Åʼn ęřřőř őččūřřęđ ŵĥįľę ľőäđįʼnģ őpŧįőʼnş." - }, - "clear": { - "title": "Cľęäř väľūę" - }, - "custom-value": { - "description": "Ůşę čūşŧőm väľūę" - }, - "group": { - "undefined": "Ńő ģřőūp" - }, - "options": { - "no-found": "Ńő őpŧįőʼnş ƒőūʼnđ." - } - }, - "command-palette": { - "action": { - "change-theme": "Cĥäʼnģę ŧĥęmę...", - "dark-theme": "Đäřĸ", - "light-theme": "Ŀįģĥŧ" - }, - "empty-state": { - "message": "Ńő řęşūľŧş ƒőūʼnđ" - }, - "search-box": { - "placeholder": "Ŝęäřčĥ őř ĵūmp ŧő..." - }, - "section": { - "actions": "Åčŧįőʼnş", - "dashboard-search-results": "Đäşĥþőäřđş", - "folder-search-results": "Főľđęřş", - "pages": "Päģęş", - "preferences": "Přęƒęřęʼnčęş", - "recent-dashboards": "Ŗęčęʼnŧ đäşĥþőäřđş" - } - }, - "common": { - "apply": "Åppľy", - "cancel": "Cäʼnčęľ", - "clear": "Cľęäř", - "close": "Cľőşę", - "collapse": "Cőľľäpşę", - "edit": "Ēđįŧ", - "help": "Ħęľp", - "loading": "Ŀőäđįʼnģ...", - "locale": { - "default": "Đęƒäūľŧ" - }, - "save": "Ŝävę", - "search": "Ŝęäřčĥ", - "view": "Vįęŵ" - }, - "configuration-tracker": { - "config-card": { - "complete": "čőmpľęŧę" - } - }, - "connections": { - "connect-data": { - "category-header-label": "Đäŧä şőūřčęş", - "empty-message": "Ńő řęşūľŧş mäŧčĥįʼnģ yőūř qūęřy ŵęřę ƒőūʼnđ", - "request-data-source": "Ŗęqūęşŧ ä ʼnęŵ đäŧä şőūřčę", - "roadmap": "Vįęŵ řőäđmäp" - }, - "search": { - "placeholder": "Ŝęäřčĥ äľľ" - } - }, - "core": { - "versionHistory": { - "comparison": { - "header": { - "hide-json-diff": "Ħįđę ĴŜØŃ đįƒƒ ", - "show-json-diff": "Ŝĥőŵ ĴŜØŃ đįƒƒ ", - "text": "Vęřşįőʼn {{version}} ūpđäŧęđ þy {{createdBy}} ({{ageString}}) {{message}}" - }, - "select": "Ŝęľęčŧ ŧŵő vęřşįőʼnş ŧő şŧäřŧ čőmpäřįʼnģ" - }, - "no-properties-changed": "Ńő řęľęväʼnŧ přőpęřŧįęş čĥäʼnģęđ", - "table": { - "updated": "Đäŧę", - "updatedBy": "Ůpđäŧęđ ßy", - "version": "Vęřşįőʼn" - }, - "view-json-diff": "Vįęŵ ĴŜØŃ đįƒƒ ŧő şęę äľľ čĥäʼnģęş" - } - }, - "correlations": { - "add-new": "Åđđ ʼnęŵ", - "alert": { - "error-message": "Åʼn ūʼnĸʼnőŵʼn ęřřőř őččūřřęđ ŵĥįľę ƒęŧčĥįʼnģ čőřřęľäŧįőʼn đäŧä. Pľęäşę ŧřy äģäįʼn.", - "title": "Ēřřőř ƒęŧčĥįʼnģ čőřřęľäŧįőʼn đäŧä" - }, - "basic-info-form": { - "description-description": "Øpŧįőʼnäľ đęşčřįpŧįőʼn ŵįŧĥ mőřę įʼnƒőřmäŧįőʼn äþőūŧ ŧĥę ľįʼnĸ", - "description-label": "Đęşčřįpŧįőʼn", - "label-description": "Ŧĥįş ʼnämę ŵįľľ þę ūşęđ äş ŧĥę ľäþęľ ƒőř ŧĥę čőřřęľäŧįőʼn. Ŧĥįş ŵįľľ şĥőŵ äş þūŧŧőʼn ŧęχŧ, ä męʼnū įŧęm, őř ĥővęř ŧęχŧ őʼn ä ľįʼnĸ.", - "label-label": "Ŀäþęľ", - "label-placeholder": "ę.ģ. Ŧęmpő ŧřäčęş", - "label-required": "Ŧĥįş ƒįęľđ įş řęqūįřęđ.", - "sub-text": "<0>Đęƒįʼnę ŧęχŧ ŧĥäŧ ŵįľľ đęşčřįþę ŧĥę čőřřęľäŧįőʼn.", - "title": "Đęƒįʼnę čőřřęľäŧįőʼn ľäþęľ (Ŝŧęp 1 őƒ 3)" - }, - "empty-state": { - "button-title": "Åđđ čőřřęľäŧįőʼn", - "pro-tip": "Ÿőū čäʼn äľşő đęƒįʼnę čőřřęľäŧįőʼnş vįä đäŧäşőūřčę přővįşįőʼnįʼnģ", - "title": "Ÿőū ĥävęʼn'ŧ đęƒįʼnęđ äʼny čőřřęľäŧįőʼnş yęŧ" - }, - "list": { - "delete": "đęľęŧę čőřřęľäŧįőʼn", - "label": "Ŀäþęľ", - "loading": "ľőäđįʼnģ...", - "read-only": "Ŗęäđ őʼnľy", - "source": "Ŝőūřčę", - "target": "Ŧäřģęŧ" - }, - "navigation-form": { - "add-button": "Åđđ", - "back-button": "ßäčĸ", - "next-button": "Ńęχŧ", - "save-button": "Ŝävę" - }, - "page-content": "Ŧő ęʼnäþľę Cőřřęľäŧįőʼnş, äđđ įŧ įʼn ŧĥę Ğřäƒäʼnä čőʼnƒįģ:", - "page-heading": "Cőřřęľäŧįőʼnş äřę đįşäþľęđ", - "query-editor": { - "control-rules": "Ŧĥę şęľęčŧęđ ŧäřģęŧ đäŧä şőūřčę mūşŧ ęχpőřŧ ä qūęřy ęđįŧőř.", - "data-source-text": "Pľęäşę şęľęčŧ ä ŧäřģęŧ đäŧä şőūřčę ƒįřşŧ.", - "data-source-title": "Ńő đäŧä şőūřčę şęľęčŧęđ", - "error-text": "Ŧĥę şęľęčŧęđ đäŧä şőūřčę čőūľđ ʼnőŧ þę ľőäđęđ.", - "error-title": "Ēřřőř ľőäđįʼnģ đäŧä şőūřčę", - "loading": "Ŀőäđįʼnģ qūęřy ęđįŧőř...", - "query-description": "Đęƒįʼnę ŧĥę qūęřy ŧĥäŧ įş řūʼn ŵĥęʼn ŧĥę ľįʼnĸ įş čľįčĸęđ. Ÿőū čäʼn ūşę <2>väřįäþľęş ŧő äččęşş şpęčįƒįč ƒįęľđ väľūęş.", - "query-editor-title": "Đäŧä şőūřčę đőęş ʼnőŧ ęχpőřŧ ä qūęřy ęđįŧőř.", - "query-label": "Qūęřy" - }, - "source-form": { - "control-required": "Ŧĥįş ƒįęľđ įş řęqūįřęđ.", - "description": "Å đäŧä pőįʼnŧ ʼnęęđş ŧő přővįđę väľūęş ŧő äľľ väřįäþľęş äş ƒįęľđş őř äş ŧřäʼnşƒőřmäŧįőʼnş őūŧpūŧ ŧő mäĸę ŧĥę čőřřęľäŧįőʼn þūŧŧőʼn äppęäř įʼn ŧĥę vįşūäľįžäŧįőʼn.<1>Ńőŧę: Ńőŧ ęvęřy väřįäþľę ʼnęęđş ŧő þę ęχpľįčįŧľy đęƒįʼnęđ þęľőŵ. Å ŧřäʼnşƒőřmäŧįőʼn şūčĥ äş <4>ľőģƒmŧ ŵįľľ čřęäŧę väřįäþľęş ƒőř ęvęřy ĸęy/väľūę päįř.", - "description-external-pre": "Ÿőū ĥävę ūşęđ ƒőľľőŵįʼnģ väřįäþľęş įʼn ŧĥę ŧäřģęŧ ŮŖĿ:", - "description-query-pre": "Ÿőū ĥävę ūşęđ ƒőľľőŵįʼnģ väřįäþľęş įʼn ŧĥę ŧäřģęŧ qūęřy:", - "external-title": "Cőʼnƒįģūřę ŧĥę đäŧä şőūřčę ŧĥäŧ ŵįľľ ūşę ŧĥę ŮŖĿ (Ŝŧęp 3 őƒ 3)", - "heading-external": "Väřįäþľęş ūşęđ įʼn ŧĥę ŧäřģęŧ ŮŖĿ", - "heading-query": "Väřįäþľęş ūşęđ įʼn ŧĥę ŧäřģęŧ qūęřy", - "query-title": "Cőʼnƒįģūřę ŧĥę đäŧä şőūřčę ŧĥäŧ ŵįľľ ľįʼnĸ ŧő {{dataSourceName}} (Ŝŧęp 3 őƒ 3)", - "results-description": "Ŧĥę ľįʼnĸ ŵįľľ þę şĥőŵʼn ʼnęχŧ ŧő ŧĥę väľūę őƒ ŧĥįş ƒįęľđ", - "results-label": "Ŗęşūľŧş ƒįęľđ", - "results-required": "Ŧĥįş ƒįęľđ įş řęqūįřęđ.", - "source-description": "Ŗęşūľŧş ƒřőm şęľęčŧęđ şőūřčę đäŧä şőūřčę ĥävę ľįʼnĸş đįşpľäyęđ įʼn ŧĥę päʼnęľ", - "source-label": "Ŝőūřčę", - "sub-text": "<0>Đęƒįʼnę ŵĥäŧ đäŧä şőūřčę ŵįľľ đįşpľäy ŧĥę čőřřęľäŧįőʼn, äʼnđ ŵĥäŧ đäŧä ŵįľľ řępľäčę přęvįőūşľy đęƒįʼnęđ väřįäþľęş." - }, - "sub-title": "Đęƒįʼnę ĥőŵ đäŧä ľįvįʼnģ įʼn đįƒƒęřęʼnŧ đäŧä şőūřčęş řęľäŧęş ŧő ęäčĥ őŧĥęř. Ŗęäđ mőřę įʼn ŧĥę <2>đőčūmęʼnŧäŧįőʼn<1>", - "target-form": { - "control-rules": "Ŧĥįş ƒįęľđ įş řęqūįřęđ.", - "sub-text": "<0>Đęƒįʼnę ŵĥäŧ ŧĥę čőřřęľäŧįőʼn ŵįľľ ľįʼnĸ ŧő. Ŵįŧĥ ŧĥę qūęřy ŧypę, ä qūęřy ŵįľľ řūʼn ŵĥęʼn ŧĥę čőřřęľäŧįőʼn įş čľįčĸęđ. Ŵįŧĥ ŧĥę ęχŧęřʼnäľ ŧypę, čľįčĸįʼnģ ŧĥę čőřřęľäŧįőʼn ŵįľľ őpęʼn ä ŮŖĿ.", - "target-description-external": "Ŝpęčįƒy ŧĥę ŮŖĿ ŧĥäŧ ŵįľľ őpęʼn ŵĥęʼn ŧĥę ľįʼnĸ įş čľįčĸęđ", - "target-description-query": "Ŝpęčįƒy ŵĥįčĥ đäŧä şőūřčę įş qūęřįęđ ŵĥęʼn ŧĥę ľįʼnĸ įş čľįčĸęđ", - "target-label": "Ŧäřģęŧ", - "target-type-description": "Ŝpęčįƒy ŧĥę ŧypę őƒ čőřřęľäŧįőʼn", - "title": "Ŝęŧūp ŧĥę ŧäřģęŧ ƒőř ŧĥę čőřřęľäŧįőʼn (Ŝŧęp 2 őƒ 3)", - "type-label": "Ŧypę" - }, - "trans-details": { - "logfmt-description": "Päřşę přővįđęđ ƒįęľđ ŵįŧĥ ľőģƒmŧ ŧő ģęŧ väřįäþľęş", - "logfmt-label": "Ŀőģƒmŧ", - "regex-description": "Fįęľđ ŵįľľ þę päřşęđ ŵįŧĥ řęģęχ. Ůşę ʼnämęđ čäpŧūřę ģřőūpş ŧő řęŧūřʼn mūľŧįpľę väřįäþľęş, őř ä şįʼnģľę ūʼnʼnämęđ čäpŧūřę ģřőūp ŧő äđđ väřįäþľę ŧő ʼnämęđ mäp väľūę. Ŗęģęχ įş čäşę įʼnşęʼnşįŧįvę.", - "regex-expression": "Ůşę čäpŧūřę ģřőūpş ŧő ęχŧřäčŧ ä pőřŧįőʼn őƒ ŧĥę ƒįęľđ.", - "regex-label": "Ŗęģūľäř ęχpřęşşįőʼn", - "regex-map-values": "Đęƒįʼnęş ŧĥę ʼnämę őƒ ŧĥę väřįäþľę įƒ ŧĥę čäpŧūřę ģřőūp įş ʼnőŧ ʼnämęđ." - }, - "transform": { - "add-button": "Åđđ ŧřäʼnşƒőřmäŧįőʼn", - "heading": "Ŧřäʼnşƒőřmäŧįőʼnş", - "no-transform": "Ńő ŧřäʼnşƒőřmäŧįőʼnş đęƒįʼnęđ." - }, - "transform-row": { - "expression-label": "Ēχpřęşşįőʼn", - "expression-required": "Pľęäşę đęƒįʼnę äʼn ęχpřęşşįőʼn", - "expression-tooltip": "Ŗęqūįřęđ ƒőř řęģūľäř ęχpřęşşįőʼn. Ŧĥę ęχpřęşşįőʼn ŧĥę ŧřäʼnşƒőřmäŧįőʼn ŵįľľ ūşę. Ŀőģƒmŧ đőęş ʼnőŧ ūşę ƒūřŧĥęř şpęčįƒįčäŧįőʼnş.", - "field-input": "ƒįęľđ", - "field-label": "Fįęľđ", - "field-tooltip": "Øpŧįőʼnäľ. Ŧĥę ƒįęľđ ŧő ŧřäʼnşƒőřm. Ĩƒ ʼnőŧ şpęčįƒįęđ, ŧĥę ŧřäʼnşƒőřmäŧįőʼn ŵįľľ þę äppľįęđ ŧő ŧĥę řęşūľŧş ƒįęľđ.", - "map-value-label": "Mäp väľūę", - "map-value-tooltip": "Øpŧįőʼnäľ. Đęƒįʼnęş ŧĥę ʼnämę őƒ ŧĥę väřįäþľę. Ŧĥįş įş čūřřęʼnŧľy őʼnľy väľįđ ƒőř řęģūľäř ęχpřęşşįőʼnş ŵįŧĥ ä şįʼnģľę, ūʼnʼnämęđ čäpŧūřę ģřőūp.", - "remove-button": "Ŗęmővę", - "remove-tooltip": "Ŗęmővę ŧřäʼnşƒőřmäŧįőʼn", - "transform-required": "Pľęäşę şęľęčŧ ä ŧřäʼnşƒőřmäŧįőʼn ŧypę", - "type-label": "Ŧypę", - "type-tooltip": "Ŧĥę ŧypę őƒ ŧřäʼnşƒőřmäŧįőʼn ŧĥäŧ ŵįľľ þę äppľįęđ ŧő ŧĥę şőūřčę đäŧä." - } - }, - "dashboard": { - "add-menu": { - "import": "Ĩmpőřŧ ƒřőm ľįþřäřy", - "paste-panel": "Päşŧę päʼnęľ", - "row": "Ŗőŵ", - "visualization": "Vįşūäľįžäŧįőʼn" - }, - "alert-rules-drawer": { - "redirect-link": "Ŀįşŧ įʼn Ğřäƒäʼnä Åľęřŧįʼnģ", - "subtitle": "Åľęřŧ řūľęş řęľäŧęđ ŧő ŧĥįş đäşĥþőäřđ" - }, - "default-layout": { - "description": "Mäʼnūäľľy şįžę äʼnđ pőşįŧįőʼn päʼnęľş", - "item-options": { - "repeat": { - "direction": { - "horizontal": "Ħőřįžőʼnŧäľ", - "title": "Ŗępęäŧ đįřęčŧįőʼn", - "vertical": "Vęřŧįčäľ" - }, - "max": "Mäχ pęř řőŵ", - "title": "Ŗępęäŧ őpŧįőʼnş", - "variable": { - "description": "Ŗępęäŧ ŧĥįş päʼnęľ ƒőř ęäčĥ väľūę įʼn ŧĥę şęľęčŧęđ väřįäþľę. Ŧĥįş įş ʼnőŧ vįşįþľę ŵĥįľę įʼn ęđįŧ mőđę. Ÿőū ʼnęęđ ŧő ģő þäčĸ ŧő đäşĥþőäřđ äʼnđ ŧĥęʼn ūpđäŧę ŧĥę väřįäþľę őř řęľőäđ ŧĥę đäşĥþőäřđ.", - "title": "Ŗępęäŧ þy väřįäþľę" - } - } - }, - "name": "Cūşŧőm", - "row-actions": { - "delete": "Đęľęŧę řőŵ", - "modal": { - "alt-action": "Đęľęŧę řőŵ őʼnľy", - "text": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő řęmővę ŧĥįş řőŵ äʼnđ äľľ įŧş päʼnęľş?", - "title": "Đęľęŧę řőŵ" - } - }, - "row-options": { - "button": { - "label": "Ŗőŵ őpŧįőʼnş" - }, - "form": { - "cancel": "Cäʼnčęľ", - "repeat-for": { - "label": "Ŗępęäŧ ƒőř", - "learn-more": "Ŀęäřʼn mőřę", - "warning": { - "text": "Päʼnęľş įʼn ŧĥįş řőŵ ūşę ŧĥę {{SHARED_DASHBOARD_QUERY}} đäŧä şőūřčę. Ŧĥęşę päʼnęľş ŵįľľ řęƒęřęʼnčę ŧĥę päʼnęľ įʼn ŧĥę őřįģįʼnäľ řőŵ, ʼnőŧ ŧĥę őʼnęş įʼn ŧĥę řępęäŧęđ řőŵş." - } - }, - "title": "Ŧįŧľę", - "update": "Ůpđäŧę" - }, - "modal": { - "title": "Ŗőŵ őpŧįőʼnş" - }, - "repeat": { - "title": "Ŗępęäŧ őpŧįőʼnş", - "variable": { - "title": "Väřįäþľę" - } - }, - "title": "Ŗőŵ őpŧįőʼnş" - } - }, - "edit-pane": { - "elements": { - "dashboard": "Đäşĥþőäřđ", - "objects": "Øþĵęčŧş", - "panels": "Päʼnęľş", - "rows": "Ŗőŵş", - "tabs": "Ŧäþş" - }, - "objects": { - "multi-select": { - "selection-number": "Ńő. őƒ őþĵęčŧş şęľęčŧęđ: {{length}}" - } - }, - "open": "Øpęʼn őpŧįőʼnş päʼnę", - "row": { - "header": { - "hide": "Ħįđę", - "title": "Ŗőŵ ĥęäđęř" - }, - "multi-select": { - "title": "{{length}} řőŵş şęľęčŧęđ" - } - } - }, - "editpane": { - "add": "Åđđ", - "configure": "Cőʼnƒįģūřę", - "outline": "Øūŧľįʼnę" - }, - "empty": { - "add-library-panel-body": "Åđđ vįşūäľįžäŧįőʼnş ŧĥäŧ äřę şĥäřęđ ŵįŧĥ őŧĥęř đäşĥþőäřđş.", - "add-library-panel-button": "Åđđ ľįþřäřy päʼnęľ", - "add-library-panel-header": "Ĩmpőřŧ päʼnęľ", - "add-visualization-body": "Ŝęľęčŧ ä đäŧä şőūřčę äʼnđ ŧĥęʼn qūęřy äʼnđ vįşūäľįžę yőūř đäŧä ŵįŧĥ čĥäřŧş, şŧäŧş äʼnđ ŧäþľęş őř čřęäŧę ľįşŧş, mäřĸđőŵʼnş äʼnđ őŧĥęř ŵįđģęŧş.", - "add-visualization-button": "Åđđ vįşūäľįžäŧįőʼn", - "add-visualization-header": "Ŝŧäřŧ yőūř ʼnęŵ đäşĥþőäřđ þy äđđįʼnģ ä vįşūäľįžäŧįőʼn", - "import-a-dashboard-body": "Ĩmpőřŧ đäşĥþőäřđş ƒřőm ƒįľęş őř <1>ģřäƒäʼnä.čőm.", - "import-a-dashboard-header": "Ĩmpőřŧ ä đäşĥþőäřđ", - "import-dashboard-button": "Ĩmpőřŧ đäşĥþőäřđ" - }, - "errors": { - "failed-to-load": "Fäįľęđ ŧő ľőäđ đäşĥþőäřđ" - }, - "inspect": { - "data-tab": "Đäŧä", - "error-tab": "Ēřřőř", - "json-tab": "ĴŜØŃ", - "meta-tab": "Męŧä đäŧä", - "query-tab": "Qūęřy", - "stats-tab": "Ŝŧäŧş", - "subtitle": "{{queryCount}} qūęřįęş ŵįŧĥ ŧőŧäľ qūęřy ŧįmę őƒ {{formatted}}", - "title": "Ĩʼnşpęčŧ: {{panelTitle}}" - }, - "inspect-data": { - "data-options": "Đäŧä őpŧįőʼnş", - "dataframe-aria-label": "Ŝęľęčŧ đäŧäƒřämę", - "dataframe-label": "Ŝĥőŵ đäŧä ƒřämę", - "download-csv": "Đőŵʼnľőäđ CŜV", - "download-excel-description": "Åđđş ĥęäđęř ŧő CŜV ƒőř ūşę ŵįŧĥ Ēχčęľ", - "download-excel-label": "Đőŵʼnľőäđ ƒőř Ēχčęľ", - "download-logs": "Đőŵʼnľőäđ ľőģş", - "download-service": "Đőŵʼnľőäđ şęřvįčę ģřäpĥ", - "download-traces": "Đőŵʼnľőäđ ŧřäčęş", - "excel-header": "Ēχčęľ ĥęäđęř", - "formatted": "Főřmäŧŧęđ đäŧä", - "formatted-data-description": "Ŧäþľę đäŧä įş ƒőřmäŧŧęđ ŵįŧĥ őpŧįőʼnş đęƒįʼnęđ įʼn ŧĥę Fįęľđ äʼnđ Øvęřřįđę ŧäþş.", - "formatted-data-label": "Főřmäŧŧęđ đäŧä", - "panel-transforms": "Päʼnęľ ŧřäʼnşƒőřmş", - "series-to-columns": "Ŝęřįęş ĵőįʼnęđ þy ŧįmę", - "transformation": "Ŝęřįęş ĵőįʼnęđ þy ŧįmę", - "transformations-description": "Ŧäþľę đäŧä įş đįşpľäyęđ ŵįŧĥ ŧřäʼnşƒőřmäŧįőʼnş đęƒįʼnęđ įʼn ŧĥę päʼnęľ Ŧřäʼnşƒőřm ŧäþ.", - "transformations-label": "Åppľy päʼnęľ ŧřäʼnşƒőřmäŧįőʼnş" - }, - "inspect-json": { - "dataframe-description": "Ŗäŵ đäŧä ŵįŧĥőūŧ ŧřäʼnşƒőřmäŧįőʼnş äʼnđ ƒįęľđ čőʼnƒįģ äppľįęđ. ", - "dataframe-label": "ĐäŧäFřämę ĴŜØŃ (ƒřőm Qūęřy)", - "panel-data-description": "Ŧĥę řäŵ mőđęľ päşşęđ ŧő ŧĥę päʼnęľ vįşūäľįžäŧįőʼn", - "panel-data-label": "Päʼnęľ đäŧä", - "panel-json-description": "Ŧĥę mőđęľ şävęđ įʼn ŧĥę đäşĥþőäřđ ĴŜØŃ ŧĥäŧ čőʼnƒįģūřęş ĥőŵ ęvęřyŧĥįʼnģ ŵőřĸş.", - "panel-json-label": "Päʼnęľ ĴŜØŃ", - "select-source": "Ŝęľęčŧ şőūřčę", - "unknown": "Ůʼnĸʼnőŵʼn Øþĵęčŧ: {{show}}" - }, - "inspect-meta": { - "no-inspector": "Ńő Męŧäđäŧä Ĩʼnşpęčŧőř" - }, - "inspect-stats": { - "data-title": "Đäŧä şőūřčę şŧäŧş", - "data-traceids": "Ŧřäčę ĨĐş", - "processing-time": "Đäŧä přőčęşşįʼnģ ŧįmę", - "queries": "Ńūmþęř őƒ qūęřįęş", - "request-time": "Ŧőŧäľ řęqūęşŧ ŧįmę", - "rows": "Ŧőŧäľ ʼnūmþęř řőŵş", - "table-title": "Ŝŧäŧş" - }, - "layout": { - "common": { - "copy": "Cőpy", - "copy-or-duplicate": "Cőpy őř Đūpľįčäŧę", - "delete": "Đęľęŧę", - "duplicate": "Đūpľįčäŧę", - "layout": "Ŀäyőūŧ", - "panels-title": "{{length}} päʼnęľş şęľęčŧęđ" - } - }, - "options": { - "description": "Đęşčřįpŧįőʼn", - "title": "Đäşĥþőäřđ őpŧįőʼnş", - "title-option": "Ŧįŧľę" - }, - "outline": { - "tree": { - "item": { - "collapse": "Cőľľäpşę įŧęm", - "empty": "(ęmpŧy)", - "expand": "Ēχpäʼnđ įŧęm" - } - } - }, - "panel-edit": { - "alerting-tab": { - "dashboard-not-saved": "Đäşĥþőäřđ mūşŧ þę şävęđ þęƒőřę äľęřŧş čäʼn þę äđđęđ.", - "no-rules": "Ŧĥęřę äřę ʼnő äľęřŧ řūľęş ľįʼnĸęđ ŧő ŧĥįş päʼnęľ." - } - }, - "responsive-layout": { - "description": "Åūŧőmäŧįčäľľy pőşįŧįőʼnş päʼnęľş įʼnŧő ä ģřįđ.", - "item-options": { - "hide-no-data": "Ħįđę ŵĥęʼn ʼnő đäŧä", - "repeat": { - "variable": { - "description": "Ŗępęäŧ ŧĥįş päʼnęľ ƒőř ęäčĥ väľūę įʼn ŧĥę şęľęčŧęđ väřįäþľę. Ŧĥįş įş ʼnőŧ vįşįþľę ŵĥįľę įʼn ęđįŧ mőđę. Ÿőū ʼnęęđ ŧő ģő þäčĸ ŧő đäşĥþőäřđ äʼnđ ŧĥęʼn ūpđäŧę ŧĥę väřįäþľę őř řęľőäđ ŧĥę đäşĥþőäřđ.", - "title": "Ŗępęäŧ þy väřįäþľę" - } - }, - "title": "Ŀäyőūŧ őpŧįőʼnş" - }, - "name": "Åūŧő", - "options": { - "columns": "Cőľūmʼnş", - "fixed": "Fįχęđ: {{size}}pχ", - "min": "Mįʼn: {{size}}pχ", - "one-column": "1 čőľūmʼn", - "rows": "Ŗőŵş", - "three-columns": "3 čőľūmʼnş", - "two-columns": "2 čőľūmʼnş" - } - }, - "rows-layout": { - "description": "Ŗőŵş ľäyőūŧ", - "item-name": "Ŗőŵ", - "name": "Ŗőŵş", - "option": { - "height": "Ħęįģĥŧ", - "hide-header": "Ħįđę řőŵ ĥęäđęř", - "repeat": "Ŗępęäŧ ƒőř", - "title": "Ŧįŧľę" - }, - "options": { - "height-expand": "Ēχpäʼnđ", - "height-min": "Mįʼn" - }, - "row": { - "collapse": "Cőľľäpşę řőŵ", - "expand": "Ēχpäʼnđ řőŵ", - "menu": { - "add": "Åđđ řőŵ", - "add-panel": "Päʼnęľ", - "add-row-above": "Ŗőŵ äþővę", - "add-row-below": "Ŗőŵ þęľőŵ", - "move-down": "Mővę řőŵ đőŵʼn", - "move-row": "Mővę řőŵ", - "move-up": "Mővę řőŵ ūp" - }, - "new": "Ńęŵ řőŵ", - "repeat": { - "learn-more": "Ŀęäřʼn mőřę", - "warning": "Päʼnęľş įʼn ŧĥįş řőŵ ūşę ŧĥę {{SHARED_DASHBOARD_QUERY}} đäŧä şőūřčę. Ŧĥęşę päʼnęľş ŵįľľ řęƒęřęʼnčę ŧĥę päʼnęľ įʼn ŧĥę őřįģįʼnäľ řőŵ, ʼnőŧ ŧĥę őʼnęş įʼn ŧĥę řępęäŧęđ řőŵş." - } - }, - "row-options": { - "title-option": "Ŧįŧľę" - } - }, - "tabs-layout": { - "description": "Ŧäþş ľäyőūŧ", - "menu": { - "move-tab": "Mővę ŧäþ" - }, - "multi-select": { - "title": "{{length}} ŧäþş şęľęčŧęđ" - }, - "name": "Ŧäþş", - "tab": { - "menu": { - "add": "Åđđ ŧäþ", - "add-panel": "Päʼnęľ", - "add-tab-above": "Ŧäþ þęƒőřę", - "add-tab-after": "Ŧäþ äƒŧęř", - "add-tab-before": "Ŧäþ þęƒőřę", - "move-left": "Mővę ŧäþ ľęƒŧ", - "move-right": "Mővę ŧäþ řįģĥŧ" - }, - "new": "Ńęŵ ŧäþ" - }, - "tab-options": { - "title": "Ŧäþ", - "title-option": "Ŧįŧľę" - } - }, - "toolbar": { - "add": "Åđđ", - "add-panel": "Päʼnęľ", - "add-panel-description": "Å čőʼnŧäįʼnęř ƒőř vįşūäľįžäŧįőʼnş äʼnđ őŧĥęř čőʼnŧęʼnŧ", - "add-panel-lib": "Ĩmpőřŧ ľįþřäřy päʼnęľ", - "add-row": "Ŗőŵ", - "add-tab": "Ŧäþ", - "alert-rules": "Åľęřŧ řūľęş", - "back-to-dashboard": "ßäčĸ ŧő đäşĥþőäřđ", - "dashboard-settings": { - "label": "Ŝęŧŧįʼnģş", - "tooltip": "Đäşĥþőäřđ şęŧŧįʼnģş" - }, - "discard-library-panel-changes": "Đįşčäřđ ľįþřäřy päʼnęľ čĥäʼnģęş", - "discard-panel": "Đįşčäřđ päʼnęľ čĥäʼnģęş", - "discard-panel-new": "Đįşčäřđ päʼnęľ", - "edit": { - "label": "Ēđįŧ", - "tooltip": "Ēʼnŧęř ęđįŧ mőđę" - }, - "edit-dashboard-v2-schema": "Ēđįŧ đäşĥþőäřđ v2 şčĥęmä", - "enter-edit-mode": { - "label": "Mäĸę ęđįŧäþľę", - "tooltip": "Ŧĥįş đäşĥþőäřđ ŵäş mäřĸęđ äş řęäđ őʼnľy" - }, - "exit-edit-mode": { - "label": "Ēχįŧ ęđįŧ", - "tooltip": "Ēχįŧş ęđįŧ mőđę äʼnđ đįşčäřđş ūʼnşävęđ čĥäʼnģęş" - }, - "libray-panel-description": "Ŀįþřäy päʼnęľş äľľőŵ yőū şĥäřę äʼnđ řęūşę päʼnęľş þęŧŵęęʼn đäşĥþőäřđş", - "mark-favorite": "Mäřĸ äş ƒävőřįŧę", - "more-save-options": "Mőřę şävę őpŧįőʼnş", - "open-original": "Øpęʼn őřįģįʼnäľ đäşĥþőäřđ", - "playlist-next": "Ğő ŧő ʼnęχŧ đäşĥþőäřđ", - "playlist-previous": "Ğő ŧő přęvįőūş đäşĥþőäřđ", - "playlist-stop": "Ŝŧőp pľäyľįşŧ", - "public-dashboard": "Pūþľįč", - "refresh": "Ŗęƒřęşĥ đäşĥþőäřđ", - "row-description": "Å ģřőūp őƒ päʼnęľş ŵįŧĥ äʼn őpŧįőʼnäľ ĥęäđęř", - "save": "Ŝävę đäşĥþőäřđ", - "save-dashboard": { - "label": "Ŝävę đäşĥþőäřđ", - "tooltip": "Ŝävę čĥäʼnģęş" - }, - "save-dashboard-copy": { - "label": "Ŝävę äş čőpy", - "tooltip": "Ŝävę äş čőpy" - }, - "save-dashboard-short": "Ŝävę", - "save-library-panel": "Ŝävę ľįþřäřy päʼnęľ", - "settings": "Đäşĥþőäřđ şęŧŧįʼnģş", - "share": { - "label": "Ŝĥäřę", - "tooltip": "Ŝĥäřę đäşĥþőäřđ" - }, - "share-button": "Ŝĥäřę", - "show-hidden-elements": "Ŝĥőŵ ĥįđđęʼn", - "switch-old-dashboard": "Ŝŵįŧčĥ ŧő őľđ đäşĥþőäřđ päģę", - "tabs-description": "ßřęäĸ ūp yőūř đäşĥþőäřđ įʼnŧő đįƒƒęřęʼnŧ ĥőřįžőʼnŧäľ ŧäþş", - "unlink-library-panel": "Ůʼnľįʼnĸ ľįþřäřy päʼnęľ", - "unmark-favorite": "Ůʼnmäřĸ äş ƒävőřįŧę" - }, - "validation": { - "invalid-dashboard-id": "Cőūľđ ʼnőŧ ƒįʼnđ ä väľįđ Ğřäƒäʼnä.čőm ĨĐ", - "invalid-json": "Ńőŧ väľįđ ĴŜØŃ", - "tags-expected-array": "ŧäģş ęχpęčŧęđ äřřäy", - "tags-expected-strings": "ŧäģş ęχpęčŧęđ äřřäy őƒ şŧřįʼnģş" - }, - "viz-panel": { - "options": { - "description": "Đęşčřįpŧįőʼn", - "open-edit": "Øpęʼn Päʼnęľ Ēđįŧ", - "plugin-type-image": "Ĩmäģę őƒ pľūģįʼn ŧypę", - "title": "Päʼnęľ", - "title-option": "Ŧįŧľę", - "transparent-background": "Ŧřäʼnşpäřęʼnŧ þäčĸģřőūʼnđ" - } - } - }, - "dashboard-import": { - "file-dropzone": { - "primary-text": "Ůpľőäđ đäşĥþőäřđ ĴŜØŃ ƒįľę", - "secondary-text": "Đřäģ äʼnđ đřőp ĥęřę őř čľįčĸ ŧő þřőŵşę" - }, - "form-actions": { - "cancel": "Cäʼnčęľ", - "load": "Ŀőäđ" - }, - "gcom-field": { - "label": "Fįʼnđ äʼnđ įmpőřŧ đäşĥþőäřđş ƒőř čőmmőʼn äppľįčäŧįőʼnş äŧ <1>", - "load-button": "Ŀőäđ", - "placeholder": "Ğřäƒäʼnä.čőm đäşĥþőäřđ ŮŖĿ őř ĨĐ", - "validation-required": "Å Ğřäƒäʼnä đäşĥþőäřđ ŮŖĿ őř ĨĐ įş řęqūįřęđ" - }, - "json-field": { - "label": "Ĩmpőřŧ vįä đäşĥþőäřđ ĴŜØŃ mőđęľ", - "validation-required": "Ńęęđ ä đäşĥþőäřđ ĴŜØŃ mőđęľ" - } - }, - "dashboard-links": { - "empty-state": { - "button-title": "Åđđ đäşĥþőäřđ ľįʼnĸ", - "info-box-content": "Đäşĥþőäřđ ľįʼnĸş äľľőŵ yőū ŧő pľäčę ľįʼnĸş ŧő őŧĥęř đäşĥþőäřđş äʼnđ ŵęþ şįŧęş đįřęčŧľy þęľőŵ ŧĥę đäşĥþőäřđ ĥęäđęř. <2>Ŀęäřʼn mőřę", - "title": "Ŧĥęřę äřę ʼnő đäşĥþőäřđ ľįʼnĸş äđđęđ yęŧ" - } - }, - "dashboard-settings": { - "annotations": { - "title": "Åʼnʼnőŧäŧįőʼnş" - }, - "dashboard-delete-button": "Đęľęŧę đäşĥþőäřđ", - "delete-modal": { - "confirmation-text": "Đęľęŧę", - "delete-button": "Đęľęŧę", - "title": "Đęľęŧę" - }, - "delete-modal-restore-dashboards-text": "Ŧĥįş äčŧįőʼn ŵįľľ mäřĸ ŧĥę đäşĥþőäřđ ƒőř đęľęŧįőʼn įʼn 30 đäyş. Ÿőūř őřģäʼnįžäŧįőʼn äđmįʼnįşŧřäŧőř čäʼn řęşŧőřę įŧ äʼnyŧįmę þęƒőřę ŧĥę 30 đäyş ęχpįřę.", - "delete-modal-text": "Đő yőū ŵäʼnŧ ŧő đęľęŧę ŧĥįş đäşĥþőäřđ?", - "general": { - "auto-refresh-description": "Đęƒįʼnę ŧĥę äūŧő řęƒřęşĥ įʼnŧęřväľş ŧĥäŧ şĥőūľđ þę äväįľäþľę įʼn ŧĥę äūŧő řęƒřęşĥ ľįşŧ. Ůşę ŧĥę ƒőřmäŧ '5ş' ƒőř şęčőʼnđş, '1m' ƒőř mįʼnūŧęş, '1ĥ' ƒőř ĥőūřş, äʼnđ '1đ' ƒőř đäyş (ę.ģ.: '5ş,10ş,30ş,1m,5m,15m,30m,1ĥ,2ĥ,1đ').", - "auto-refresh-label": "Åūŧő řęƒřęşĥ", - "description-label": "Đęşčřįpŧįőʼn", - "editable-description": "Ŝęŧ ŧő řęäđ-őʼnľy ŧő đįşäþľę äľľ ęđįŧįʼnģ. Ŗęľőäđ ŧĥę đäşĥþőäřđ ƒőř čĥäʼnģęş ŧő ŧäĸę ęƒƒęčŧ", - "editable-label": "Ēđįŧäþľę", - "folder-label": "Főľđęř", - "panel-options-graph-tooltip-description": "Cőʼnŧřőľş ŧőőľŧįp äʼnđ ĥővęř ĥįģĥľįģĥŧ þęĥävįőř äčřőşş đįƒƒęřęʼnŧ päʼnęľş. Ŗęľőäđ ŧĥę đäşĥþőäřđ ƒőř čĥäʼnģęş ŧő ŧäĸę ęƒƒęčŧ", - "panel-options-graph-tooltip-label": "Ğřäpĥ ŧőőľŧįp", - "panel-options-label": "Päʼnęľ őpŧįőʼnş", - "panels-preload-description": "Ŵĥęʼn ęʼnäþľęđ äľľ päʼnęľş ŵįľľ şŧäřŧ ľőäđįʼnģ äş şőőʼn äş ŧĥę đäşĥþőäřđ ĥäş þęęʼn ľőäđęđ.", - "panels-preload-label": "Přęľőäđ päʼnęľş", - "tags-label": "Ŧäģş", - "title": "Ğęʼnęřäľ", - "title-label": "Ŧįŧľę" - }, - "json-editor": { - "save-button": "Ŝävę čĥäʼnģęş", - "subtitle": "Ŧĥę ĴŜØŃ mőđęľ þęľőŵ įş ŧĥę đäŧä şŧřūčŧūřę ŧĥäŧ đęƒįʼnęş ŧĥę đäşĥþőäřđ. Ŧĥįş įʼnčľūđęş đäşĥþőäřđ şęŧŧįʼnģş, päʼnęľ şęŧŧįʼnģş, ľäyőūŧ, qūęřįęş, äʼnđ şő őʼn.", - "title": "ĴŜØŃ Mőđęľ" - }, - "links": { - "title": "Ŀįʼnĸş" - }, - "permissions": { - "title": "Pęřmįşşįőʼnş" - }, - "provisioned-delete-modal": { - "confirm-button": "ØĶ", - "text-1": "Ŧĥįş đäşĥþőäřđ įş mäʼnäģęđ þy Ğřäƒäʼnä přővįşįőʼnįʼnģ äʼnđ čäʼnʼnőŧ þę đęľęŧęđ. Ŗęmővę ŧĥę đäşĥþőäřđ ƒřőm ŧĥę čőʼnƒįģ ƒįľę ŧő đęľęŧę įŧ.", - "text-2": "Ŝęę ģřäƒäʼnä đőčūmęʼnŧäŧįőʼn ƒőř mőřę įʼnƒőřmäŧįőʼn äþőūŧ přővįşįőʼnįʼnģ. ", - "text-3": "Fįľę päŧĥ: {{provisionedId}}", - "text-link": "Ğő ŧő đőčş päģę", - "title": "Cäʼnʼnőŧ đęľęŧę přővįşįőʼnęđ đäşĥþőäřđ" - }, - "settings": { - "title": "Ŝęŧŧįʼnģş" - }, - "time-picker": { - "hide-time-picker": "Ħįđę ŧįmę pįčĸęř", - "now-delay-description": "Ēχčľūđę řęčęʼnŧ đäŧä ŧĥäŧ mäy þę įʼnčőmpľęŧę.", - "now-delay-label": "Ńőŵ đęľäy", - "refresh-live-dashboards-description": "Cőʼnŧįʼnūőūşľy řę-đřäŵ päʼnęľş ŵĥęřę ŧĥę ŧįmę řäʼnģę řęƒęřęʼnčęş 'ʼnőŵ'", - "refresh-live-dashboards-label": "Ŗęƒřęşĥ ľįvę đäşĥþőäřđş", - "time-options-label": "Ŧįmę őpŧįőʼnş", - "time-zone-label": "Ŧįmę žőʼnę", - "week-start-label": "Ŵęęĸ şŧäřŧ" - }, - "time-regions": { - "advanced-description-cron": "Cřőʼn şyʼnŧäχ", - "advanced-description-rest": " ŧő đęƒįʼnę ä řęčūřřęʼnčę şčĥęđūľę äʼnđ đūřäŧįőʼn", - "advanced-description-use": "Ůşę ", - "advanced-label": "Åđväʼnčęđ" - }, - "variables": { - "title": "Väřįäþľęş" - }, - "versions": { - "title": "Vęřşįőʼnş" - } - }, - "dashboards": { - "panel-edit": { - "angular-deprecation-button-open-panel-json": "Øpęʼn ĴŜØŃ ęđįŧőř", - "angular-deprecation-description": "Åʼnģūľäř päʼnęľş őpŧįőʼnş čäʼn őʼnľy þę ęđįŧęđ ūşįʼnģ ŧĥę ĴŜØŃ ęđįŧőř.", - "angular-deprecation-heading": "Päʼnęľ őpŧįőʼnş" - }, - "panel-queries": { - "add-query-from-library": "Åđđ qūęřy ƒřőm ľįþřäřy" - }, - "settings": { - "variables": { - "dependencies": { - "button": "Ŝĥőŵ đępęʼnđęʼnčįęş", - "title": "Đępęʼnđęʼnčįęş" - } - } - } - }, - "data-source-list": { - "empty-state": { - "button-title": "Åđđ đäŧä şőūřčę", - "pro-tip": "Ÿőū čäʼn äľşő đęƒįʼnę đäŧä şőūřčęş ŧĥřőūģĥ čőʼnƒįģūřäŧįőʼn ƒįľęş. <2>Ŀęäřʼn mőřę", - "title": "Ńő đäŧä şőūřčęş đęƒįʼnęđ" - } - }, - "data-source-picker": { - "add-new-data-source": "Cőʼnƒįģūřę ä ʼnęŵ đäŧä şőūřčę", - "built-in-list": { - "description-dashboard": "Ŗęūşę qūęřy řęşūľŧş ƒřőm őŧĥęř vįşūäľįžäŧįőʼnş", - "description-grafana": "Đįşčővęř vįşūäľįžäŧįőʼnş ūşįʼnģ mőčĸ đäŧä", - "description-mixed": "Ůşę mūľŧįpľę đäŧä şőūřčęş" - }, - "list": { - "no-data-source-message": "Ńő đäŧä şőūřčęş ƒőūʼnđ" - }, - "modal": { - "configure-new-data-source": "Øpęʼn ä ʼnęŵ ŧäþ äʼnđ čőʼnƒįģūřę ä đäŧä şőūřčę", - "input-placeholder": "Ŝęľęčŧ đäŧä şőūřčę", - "title": "Ŝęľęčŧ đäŧä şőūřčę" - }, - "open-advanced-button": "Øpęʼn äđväʼnčęđ đäŧä şőūřčę pįčĸęř" - }, - "data-source-testing-status-page": { - "error-more-details-link": "Cľįčĸ <2>ĥęřę ŧő ľęäřʼn mőřę äþőūŧ ŧĥįş ęřřőř.", - "success-more-details-links": "Ńęχŧ, yőū čäʼn şŧäřŧ ŧő vįşūäľįžę đäŧä þy <2>þūįľđįʼnģ ä đäşĥþőäřđ, őř þy qūęřyįʼnģ đäŧä įʼn ŧĥę <5>Ēχpľőřę vįęŵ." - }, - "data-sources": { - "datasource-add-button": { - "label": "Åđđ ʼnęŵ đäŧä şőūřčę" - }, - "empty-state": { - "message": "Ńő đäŧä şőūřčęş ƒőūʼnđ" - } - }, - "embed": { - "share": { - "time-range-description": "Cĥäʼnģę ŧĥę čūřřęʼnŧ řęľäŧįvę ŧįmę řäʼnģę ŧő äʼn äþşőľūŧę ŧįmę řäʼnģę", - "time-range-label": "Ŀőčĸ ŧįmę řäʼnģę" - } - }, - "empty-list-cta": { - "pro-tip": "PřőŦįp: {{proTip}}" - }, - "entity-not-found": { - "description": "Ŵę'řę ľőőĸįʼnģ þūŧ čäʼn'ŧ şęęm ŧő ƒįʼnđ ŧĥįş {{lowerCaseEntity}}. Ŧřy řęŧūřʼnįʼnģ <4>ĥőmę őř şęęĸįʼnģ ĥęľp őʼn ŧĥę <7>čőmmūʼnįŧy şįŧę." - }, - "errors": { - "dashboard-settings": { - "annotations": { - "datasource": "Ŧĥę şęľęčŧęđ đäŧä şőūřčę đőęş ʼnőŧ şūppőřŧ äʼnʼnőŧäŧįőʼnş. Pľęäşę şęľęčŧ ä đįƒƒęřęʼnŧ đäŧä şőūřčę." - } - } - }, - "explore": { - "add-to-dashboard": "Åđđ ŧő đäşĥþőäřđ", - "drilldownInfo": { - "action": "Ğő ŧő Ğřäƒäʼnä Đřįľľđőŵʼn", - "description": "Ŀőőĸįʼnģ ƒőř ŧĥę Ğřäƒäʼnä Ēχpľőřę äppş? Ŧĥęy äřę ʼnőŵ čäľľęđ ŧĥę Ğřäƒäʼnä Đřįľľđőŵʼn äppş äʼnđ čäʼn þę ƒőūʼnđ ūʼnđęř <1>Męʼnū > Đřįľľđőŵʼn", - "title": "Ēχpľőřę Męŧřįčş, Ŀőģş, Ŧřäčęş äʼnđ Přőƒįľęş ĥävę mővęđ!" - }, - "logs": { - "logs-volume": { - "add-filters": "Åđđ mőřę ľäþęľş ŧő yőūř qūęřy ŧő ʼnäřřőŵ đőŵʼn yőūř şęäřčĥ.", - "decrease-timerange": "Đęčřęäşę ŧĥę ŧįmę řäʼnģę őƒ yőūř qūęřy.", - "much-data": "Ŧĥę qūęřy įş ŧřyįʼnģ ŧő äččęşş ŧőő mūčĥ đäŧä. Ŧřy őʼnę őř mőřę őƒ ŧĥę ƒőľľőŵįʼnģ:" - }, - "maximum-pinned-logs": "Mäχįmūm őƒ {{PINNED_LOGS_LIMIT}} pįʼnʼnęđ ľőģş řęäčĥęđ. Ůʼnpįʼn ä ľőģ ŧő äđđ äʼnőŧĥęř.", - "no-logs-found": "Ńő ľőģş ƒőūʼnđ.", - "scan-for-older-logs": "Ŝčäʼn ƒőř őľđęř ľőģş", - "stop-scan": "Ŝŧőp şčäʼn" - }, - "rich-history": { - "close-tooltip": "Cľőşę qūęřy ĥįşŧőřy", - "datasource-a-z": "Đäŧä şőūřčę Å-Ż", - "datasource-z-a": "Đäŧä şőūřčę Ż-Å", - "newest-first": "Ńęŵęşŧ ƒįřşŧ", - "oldest-first": "Øľđęşŧ ƒįřşŧ", - "query-history": "Qūęřy ĥįşŧőřy", - "query-library": "Qūęřy ľįþřäřy", - "settings": "Ŝęŧŧįʼnģş", - "starred": "Ŝŧäřřęđ" - }, - "rich-history-card": { - "add-comment-form": "Åđđ čőmmęʼnŧ ƒőřm", - "add-comment-tooltip": "Åđđ čőmmęʼnŧ", - "add-to-library": "Åđđ ŧő ľįþřäřy", - "cancel": "Cäʼnčęľ", - "confirm-delete": "Đęľęŧę", - "copy-query-tooltip": "Cőpy qūęřy ŧő čľįpþőäřđ", - "copy-shortened-link-tooltip": "Cőpy şĥőřŧęʼnęđ ľįʼnĸ ŧő čľįpþőäřđ", - "datasource-icon-label": "Đäŧä şőūřčę įčőʼn", - "datasource-name-label": "Đäŧä şőūřčę ʼnämę", - "datasource-not-exist": "Đäŧä şőūřčę đőęş ʼnőŧ ęχįşŧ äʼnymőřę", - "delete-query-confirmation-title": "Đęľęŧę", - "delete-query-title": "Đęľęŧę qūęřy", - "delete-query-tooltip": "Đęľęŧę qūęřy", - "delete-starred-query-confirmation-text": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő pęřmäʼnęʼnŧľy đęľęŧę yőūř şŧäřřęđ qūęřy?", - "edit-comment-tooltip": "Ēđįŧ čőmmęʼnŧ", - "optional-description": "Åʼn őpŧįőʼnäľ đęşčřįpŧįőʼn őƒ ŵĥäŧ ŧĥę qūęřy đőęş.", - "query-comment-label": "Qūęřy čőmmęʼnŧ", - "query-text-label": "Qūęřy ŧęχŧ", - "save-comment": "Ŝävę čőmmęʼnŧ", - "star-query-tooltip": "Ŝŧäř qūęřy", - "unstar-query-tooltip": "Ůʼnşŧäř qūęřy", - "update-comment-form": "Ůpđäŧę čőmmęʼnŧ ƒőřm" - }, - "rich-history-container": { - "loading": "Ŀőäđįʼnģ..." - }, - "rich-history-notification": { - "query-copied": "Qūęřy čőpįęđ ŧő čľįpþőäřđ", - "query-deleted": "Qūęřy đęľęŧęđ" - }, - "rich-history-queries-tab": { - "displaying-partial-queries": "Đįşpľäyįʼnģ {{ count }} qūęřįęş", - "displaying-queries": "{{ count }} qūęřįęş", - "filter-aria-label": "Fįľŧęř qūęřįęş ƒőř đäŧä şőūřčęş(ş)", - "filter-history": "Fįľŧęř ĥįşŧőřy", - "filter-placeholder": "Fįľŧęř qūęřįęş ƒőř đäŧä şőūřčęş(ş)", - "history-local": "Ŧĥę ĥįşŧőřy įş ľőčäľ ŧő yőūř þřőŵşęř äʼnđ įş ʼnőŧ şĥäřęđ ŵįŧĥ őŧĥęřş.", - "loading": "Ŀőäđįʼnģ...", - "loading-results": "Ŀőäđįʼnģ řęşūľŧş...", - "search-placeholder": "Ŝęäřčĥ qūęřįęş", - "showing-queries": "Ŝĥőŵįʼnģ {{ shown }} őƒ {{ total }} <0>Ŀőäđ mőřę", - "sort-aria-label": "Ŝőřŧ qūęřįęş", - "sort-placeholder": "Ŝőřŧ qūęřįęş þy" - }, - "rich-history-settings-tab": { - "alert-info": "Ğřäƒäʼnä ŵįľľ ĸęęp ęʼnŧřįęş ūp ŧő {{optionLabel}}.Ŝŧäřřęđ ęʼnŧřįęş ŵőʼn'ŧ þę đęľęŧęđ.", - "change-default-tab": "Cĥäʼnģę ŧĥę đęƒäūľŧ äčŧįvę ŧäþ ƒřőm “Qūęřy ĥįşŧőřy” ŧő “Ŝŧäřřęđ”", - "clear-history-info": "Đęľęŧę äľľ őƒ yőūř qūęřy ĥįşŧőřy, pęřmäʼnęʼnŧľy.", - "clear-query-history": "Cľęäř qūęřy ĥįşŧőřy", - "clear-query-history-button": "Cľęäř qūęřy ĥįşŧőřy", - "delete-confirm": "Đęľęŧę", - "delete-confirm-text": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő pęřmäʼnęʼnŧľy đęľęŧę yőūř qūęřy ĥįşŧőřy?", - "delete-title": "Đęľęŧę", - "history-time-span": "Ħįşŧőřy ŧįmę şpäʼn", - "history-time-span-description": "Ŝęľęčŧ ŧĥę pęřįőđ őƒ ŧįmę ƒőř ŵĥįčĥ Ğřäƒäʼnä ŵįľľ şävę yőūř qūęřy ĥįşŧőřy. Ůp ŧő {{MAX_HISTORY_ITEMS}} ęʼnŧřįęş ŵįľľ þę şŧőřęđ.", - "only-show-active-datasource": "Øʼnľy şĥőŵ qūęřįęş ƒőř đäŧä şőūřčę čūřřęʼnŧľy äčŧįvę įʼn Ēχpľőřę", - "query-history-deleted": "Qūęřy ĥįşŧőřy đęľęŧęđ", - "retention-period": { - "1-week": "1 ŵęęĸ", - "2-days": "2 đäyş", - "2-weeks": "2 ŵęęĸş", - "5-days": "5 đäyş" - } - }, - "rich-history-starred-tab": { - "filter-queries-aria-label": "Fįľŧęř qūęřįęş ƒőř đäŧä şőūřčęş(ş)", - "filter-queries-placeholder": "Fįľŧęř qūęřįęş ƒőř đäŧä şőūřčęş(ş)", - "loading": "Ŀőäđįʼnģ...", - "loading-results": "Ŀőäđįʼnģ řęşūľŧş...", - "local-history-message": "Ŧĥę ĥįşŧőřy įş ľőčäľ ŧő yőūř þřőŵşęř äʼnđ įş ʼnőŧ şĥäřęđ ŵįŧĥ őŧĥęřş.", - "search-queries-placeholder": "Ŝęäřčĥ qūęřįęş", - "showing-queries": "Ŝĥőŵįʼnģ {{ shown }} őƒ {{ total }} <0>Ŀőäđ mőřę", - "sort-queries-aria-label": "Ŝőřŧ qūęřįęş", - "sort-queries-placeholder": "Ŝőřŧ qūęřįęş þy" - }, - "rich-history-utils": { - "a-week-ago": "ä ŵęęĸ äģő", - "days-ago": "{{num}} đäyş äģő", - "default-from": "ʼnőŵ-1ĥ", - "default-to": "ʼnőŵ", - "today": "ŧőđäy", - "two-weeks-ago": "ŧŵő ŵęęĸş äģő", - "yesterday": "yęşŧęřđäy" - }, - "rich-history-utils-notification": { - "saving-failed": "Ŝävįʼnģ řįčĥ ĥįşŧőřy ƒäįľęđ", - "update-failed": "Ŗįčĥ Ħįşŧőřy ūpđäŧę ƒäįľęđ" - }, - "run-query": { - "left-pane": "Ŀęƒŧ päʼnę", - "right-pane": "Ŗįģĥŧ päʼnę", - "run-query-button": "Ŗūʼn qūęřy", - "switch-datasource-button": "Ŝŵįŧčĥ đäŧä şőūřčę äʼnđ řūʼn qūęřy" - }, - "secondary-actions": { - "add-from-query-library": "Åđđ qūęřy ƒřőm ľįþřäřy", - "query-add-button": "Åđđ qūęřy", - "query-add-button-aria-label": "Åđđ qūęřy", - "query-history-button": "Qūęřy ĥįşŧőřy", - "query-history-button-aria-label": "Qūęřy ĥįşŧőřy", - "query-inspector-button": "Qūęřy įʼnşpęčŧőř", - "query-inspector-button-aria-label": "Qūęřy įʼnşpęčŧőř" - }, - "table": { - "no-data": "0 şęřįęş řęŧūřʼnęđ", - "title": "Ŧäþľę", - "title-with-name": "Ŧäþľę - {{name}}" - }, - "toolbar": { - "add-to-extensions": "Åđđ", - "add-to-queryless-extensions": "Ğő qūęřyľęşş", - "aria-label": "Ēχpľőřę ŧőőľþäř", - "copy-link": "Cőpy ŮŖĿ", - "copy-link-abs-time": "Cőpy äþşőľūŧę ŮŖĿ", - "copy-links-absolute-category": "Ŧįmę-şyʼnč ŮŖĿ ľįʼnĸş (şĥäřę ŵįŧĥ ŧįmę řäʼnģę įʼnŧäčŧ)", - "copy-links-normal-category": "Ńőřmäľ ŮŖĿ ľįʼnĸş", - "copy-shortened-link": "Cőpy şĥőřŧęʼnęđ ŮŖĿ", - "copy-shortened-link-abs-time": "Cőpy äþşőľūŧę şĥőřŧęʼnęđ ŮŖĿ", - "copy-shortened-link-label": "Ŝĥäřę", - "copy-shortened-link-menu": "Øpęʼn čőpy ľįʼnĸ őpŧįőʼnş", - "refresh-picker-cancel": "Cäʼnčęľ", - "refresh-picker-run": "Ŗūʼn qūęřy", - "split-close": " Cľőşę ", - "split-close-tooltip": "Cľőşę şpľįŧ päʼnę", - "split-narrow": "Ńäřřőŵ päʼnę", - "split-title": "Ŝpľįŧ", - "split-tooltip": "Ŝpľįŧ ŧĥę päʼnę", - "split-widen": "Ŵįđęʼn päʼnę" - } - }, - "explore-metrics": { - "breakdown": { - "clearFilter": "Cľęäř ƒįľŧęř", - "labelSelect": "Ŝęľęčŧ", - "missing-otel-labels": "Ŧĥįş męŧřįč ĥäş ŧőő mäʼny ĵőþ äʼnđ įʼnşŧäʼnčę ľäþęľ väľūęş ŧő čäľľ ŧĥę Přőmęŧĥęūş ľäþęľ_väľūęş ęʼnđpőįʼnŧ ŵįŧĥ ŧĥę mäŧčĥ[] päřämęŧęř. Ŧĥęşę ľäþęľ väľūęş äřę ūşęđ ŧő ĵőįʼn ŧĥę męŧřįč ŵįŧĥ ŧäřģęŧ_įʼnƒő, ŵĥįčĥ čőʼnŧäįʼnş ŧĥę řęşőūřčę äŧŧřįþūŧęş. Pľęäşę įʼnčľūđę mőřę řęşőūřčę äŧŧřįþūŧęş ƒįľŧęřş.", - "noMatchingValue": "Ńő väľūęş ƒőūʼnđ mäŧčĥįʼnģ; {{filter}}", - "sortBy": "Ŝőřŧ þy" - }, - "related-logs": { - "LrrDocsLink": "Ŀőĸį Ŗęčőřđįʼnģ Ŗūľę", - "openExploreLogs": "Øpęʼn Ēχpľőřę Ŀőģş", - "relatedLogsUnavailable": "Ńő řęľäŧęđ ľőģş ƒőūʼnđ. Ŧő şęę řęľäŧęđ ľőģş, yőū čäʼn ęįŧĥęř:<1><0>äđĵūşŧ ŧĥę ľäþęľ ƒįľŧęř ŧő ƒįʼnđ ľőģş ŵįŧĥ ŧĥę şämę ľäþęľş äş ŧĥę čūřřęʼnŧľy-şęľęčŧęđ męŧřįč<1>şęľęčŧ ä męŧřįč čřęäŧęđ þy ä <2><0>Ŀőĸį Ŗęčőřđįʼnģ Ŗūľę", - "warnExperimentalFeature": "Ŗęľäŧęđ ľőģş įş äʼn ęχpęřįmęʼnŧäľ ƒęäŧūřę." - }, - "viewBy": "Vįęŵ þy" - }, - "export": { - "json": { - "cancel-button": "Cäʼnčęľ", - "copy-button": "Cőpy ŧő čľįpþőäřđ", - "download-button": "Đőŵʼnľőäđ ƒįľę", - "download-successful_toast_message": "Ÿőūř ĴŜØŃ ĥäş þęęʼn đőŵʼnľőäđęđ", - "export-externally-label": "Ēχpőřŧ ŧĥę đäşĥþőäřđ ŧő ūşę įʼn äʼnőŧĥęř įʼnşŧäʼnčę", - "info-text": "Cőpy őř đőŵʼnľőäđ ä ĴŜØŃ ƒįľę čőʼnŧäįʼnįʼnģ ŧĥę ĴŜØŃ őƒ yőūř đäşĥþőäřđ", - "title": "Ēχpőřŧ đäşĥþőäřđ ĴŜØŃ" - }, - "menu": { - "export-as-json-label": "Ēχpőřŧ", - "export-as-json-tooltip": "Ēχpőřŧ" - } - }, - "folder-filter": { - "clear-folder-button": "Cľęäř ƒőľđęřş" - }, - "folder-picker": { - "create-instructions": "Přęşş ęʼnŧęř ŧő čřęäŧę ŧĥę ʼnęŵ ƒőľđęř.", - "loading": "Ŀőäđįʼnģ ƒőľđęřş..." - }, - "forgot-password": { - "back-button": "ßäčĸ ŧő ľőģįʼn", - "change-password": { - "skip-button": "Ŝĸįp", - "submit-button": "Ŝūþmįŧ" - }, - "contact-admin": "Đįđ yőū ƒőřģęŧ yőūř ūşęřʼnämę őř ęmäįľ? Cőʼnŧäčŧ yőūř Ğřäƒäʼnä äđmįʼnįşŧřäŧőř.", - "email-sent": "Åʼn ęmäįľ ŵįŧĥ ä řęşęŧ ľįʼnĸ ĥäş þęęʼn şęʼnŧ ŧő ŧĥę ęmäįľ äđđřęşş. Ÿőū şĥőūľđ řęčęįvę įŧ şĥőřŧľy.", - "reset-password-header": "Ŗęşęŧ päşşŵőřđ", - "send-email-button": "Ŝęʼnđ řęşęŧ ęmäįľ" - }, - "form-prompt": { - "continue-button": "Cőʼnŧįʼnūę ęđįŧįʼnģ", - "description": "Cĥäʼnģęş ŧĥäŧ yőū mäđę mäy ʼnőŧ þę şävęđ.", - "discard-button": "Đįşčäřđ ūʼnşävęđ čĥäʼnģęş" - }, - "gen-ai": { - "apply-suggestion": "Åppľy", - "incomplete-request-error": "Ŝőřřy, Ĩ ŵäş ūʼnäþľę ŧő čőmpľęŧę yőūř řęqūęşŧ. Pľęäşę ŧřy äģäįʼn.", - "send-custom-feedback": "Ŝęʼnđ" - }, - "get-enterprise": { - "requires-license": "Ŗęqūįřęş ä Ğřäƒäʼnä Ēʼnŧęřpřįşę ľįčęʼnşę", - "title": "Ēʼnŧęřpřįşę" - }, - "grafana-ui": { - "action-editor": { - "button": { - "confirm": "Cőʼnƒįřm", - "confirm-action": "Cőʼnƒįřm äčŧįőʼn" - }, - "inline": { - "add-action": "Åđđ äčŧįőʼn", - "edit-action": "Ēđįŧ äčŧįőʼn" - }, - "modal": { - "action-body": "ßőđy", - "action-method": "Męŧĥőđ", - "action-query-params": "Qūęřy päřämęŧęřş", - "action-title": "Ŧįŧľę", - "action-title-placeholder": "Åčŧįőʼn ŧįŧľę", - "one-click-description": "Øʼnľy őʼnę ľįʼnĸ őř äčŧįőʼn čäʼn ĥävę őʼnę čľįčĸ ęʼnäþľęđ äŧ ä ŧįmę" - } - }, - "alert": { - "close-button": "Cľőşę äľęřŧ" - }, - "auto-save-field": { - "saved": "Ŝävęđ!", - "saving": "Ŝävįʼnģ <1>" - }, - "card": { - "option": "őpŧįőʼn" - }, - "cascader": { - "clear-button": "Cľęäř şęľęčŧįőʼn" - }, - "color-picker-popover": { - "palette-tab": "Cőľőřş", - "spectrum-tab": "Cūşŧőm" - }, - "confirm-button": { - "cancel": "Cäʼnčęľ" - }, - "confirm-content": { - "placeholder": "Ŧypę \"{{confirmPromptText}}\" ŧő čőʼnƒįřm" - }, - "data-link-editor": { - "info": "Ŵįŧĥ đäŧä ľįʼnĸş yőū čäʼn řęƒęřęʼnčę đäŧä väřįäþľęş ľįĸę şęřįęş ʼnämę, ľäþęľş äʼnđ väľūęş. Ŧypę CMĐ+Ŝpäčę, CŦŖĿ+Ŝpäčę, őř $ ŧő őpęʼn väřįäþľę şūģģęşŧįőʼnş.", - "new-tab-label": "Øpęʼn įʼn ʼnęŵ ŧäþ", - "title-label": "Ŧįŧľę", - "title-placeholder": "Ŝĥőŵ đęŧäįľş", - "url-label": "ŮŖĿ" - }, - "data-link-editor-modal": { - "cancel": "Cäʼnčęľ", - "one-click-description": "Øʼnľy őʼnę ľįʼnĸ čäʼn ĥävę őʼnę čľįčĸ ęʼnäþľęđ äŧ ä ŧįmę", - "save": "Ŝävę" - }, - "data-link-inline-editor": { - "one-click": "Øʼnę čľįčĸ" - }, - "data-links-inline-editor": { - "add-link": "Åđđ ľįʼnĸ", - "edit-link": "Ēđįŧ ľįʼnĸ", - "one-click": "Øʼnę čľįčĸ", - "one-click-enabled": "Øʼnę čľįčĸ ęʼnäþľęđ", - "title-not-provided": "Ŧįŧľę ʼnőŧ přővįđęđ", - "tooltip-edit": "Ēđįŧ", - "tooltip-remove": "Ŗęmővę", - "url-not-provided": "Đäŧä ľįʼnĸ ūřľ ʼnőŧ přővįđęđ" - }, - "data-source-basic-auth-settings": { - "user-label": "Ůşęř", - "user-placeholder": "ūşęř" - }, - "data-source-http-proxy-settings": { - "oauth-identity-label": "Főřŵäřđ ØÅūŧĥ Ĩđęʼnŧįŧy", - "oauth-identity-tooltip": "Főřŵäřđ ŧĥę ūşęř'ş ūpşŧřęäm ØÅūŧĥ įđęʼnŧįŧy ŧő ŧĥę đäŧä şőūřčę (Ŧĥęįř äččęşş ŧőĸęʼn ģęŧş päşşęđ äľőʼnģ).", - "skip-tls-verify-label": "Ŝĸįp ŦĿŜ Vęřįƒy", - "ts-client-auth-label": "ŦĿŜ Cľįęʼnŧ Åūŧĥ", - "with-ca-cert-label": "Ŵįŧĥ CÅ Cęřŧ", - "with-ca-cert-tooltip": "Ńęęđęđ ƒőř vęřįƒyįʼnģ şęľƒ-şįģʼnęđ ŦĿŜ Cęřŧş" - }, - "data-source-http-settings": { - "access-help": "Ħęľp <1>", - "access-help-details": "Åččęşş mőđę čőʼnŧřőľş ĥőŵ řęqūęşŧş ŧő ŧĥę đäŧä şőūřčę ŵįľľ þę ĥäʼnđľęđ.<1> <1>Ŝęřvęř şĥőūľđ þę ŧĥę přęƒęřřęđ ŵäy įƒ ʼnőŧĥįʼnģ ęľşę įş şŧäŧęđ.", - "access-label": "Åččęşş", - "access-options-browser": "ßřőŵşęř", - "access-options-proxy": "Ŝęřvęř (đęƒäūľŧ)", - "allowed-cookies": "Åľľőŵęđ čőőĸįęş", - "allowed-cookies-tooltip": "Ğřäƒäʼnä přőχy đęľęŧęş ƒőřŵäřđęđ čőőĸįęş þy đęƒäūľŧ. Ŝpęčįƒy čőőĸįęş þy ʼnämę ŧĥäŧ şĥőūľđ þę ƒőřŵäřđęđ ŧő ŧĥę đäŧä şőūřčę.", - "auth": "Åūŧĥ", - "azure-auth-label": "Åžūřę Åūŧĥęʼnŧįčäŧįőʼn", - "azure-auth-tooltip": "Ůşę Åžūřę äūŧĥęʼnŧįčäŧįőʼn ƒőř Åžūřę ęʼnđpőįʼnŧ.", - "basic-auth": "ßäşįč Åūŧĥ Đęŧäįľş", - "basic-auth-label": "ßäşįč äūŧĥ", - "browser-mode-description": "Åľľ řęqūęşŧş ŵįľľ þę mäđę ƒřőm ŧĥę þřőŵşęř đįřęčŧľy ŧő ŧĥę đäŧä şőūřčę äʼnđ mäy þę şūþĵęčŧ ŧő Cřőşş-Øřįģįʼn Ŗęşőūřčę Ŝĥäřįʼnģ (CØŖŜ) řęqūįřęmęʼnŧş. Ŧĥę ŮŖĿ ʼnęęđş ŧő þę äččęşşįþľę ƒřőm ŧĥę þřőŵşęř įƒ yőū şęľęčŧ ŧĥįş äččęşş mőđę.", - "browser-mode-title": "<0>ßřőŵşęř äččęşş mőđę:", - "default-url-access-select": "Åččęşş", - "default-url-tooltip": "Ŝpęčįƒy ä čőmpľęŧę ĦŦŦP ŮŖĿ (ƒőř ęχämpľę ĥŧŧp://yőūř_şęřvęř:8080)", - "direct-url-tooltip": "Ÿőūř äččęşş męŧĥőđ įş <1>ßřőŵşęř, ŧĥįş męäʼnş ŧĥę ŮŖĿ ʼnęęđş ŧő þę äččęşşįþľę ƒřőm ŧĥę þřőŵşęř.", - "heading": "ĦŦŦP", - "proxy-url-tooltip": "Ÿőūř äččęşş męŧĥőđ įş <1>Ŝęřvęř, ŧĥįş męäʼnş ŧĥę ŮŖĿ ʼnęęđş ŧő þę äččęşşįþľę ƒřőm ŧĥę ģřäƒäʼnä þäčĸęʼnđ/şęřvęř.", - "server-mode-description": "Åľľ řęqūęşŧş ŵįľľ þę mäđę ƒřőm ŧĥę þřőŵşęř ŧő Ğřäƒäʼnä þäčĸęʼnđ/şęřvęř ŵĥįčĥ įʼn ŧūřʼn ŵįľľ ƒőřŵäřđ ŧĥę řęqūęşŧş ŧő ŧĥę đäŧä şőūřčę äʼnđ þy ŧĥäŧ čįřčūmvęʼnŧ pőşşįþľę Cřőşş-Øřįģįʼn Ŗęşőūřčę Ŝĥäřįʼnģ (CØŖŜ) řęqūįřęmęʼnŧş. Ŧĥę ŮŖĿ ʼnęęđş ŧő þę äččęşşįþľę ƒřőm ŧĥę ģřäƒäʼnä þäčĸęʼnđ/şęřvęř įƒ yőū şęľęčŧ ŧĥįş äččęşş mőđę.", - "server-mode-title": "<0>Ŝęřvęř äččęşş mőđę (Đęƒäūľŧ):", - "timeout-form-label": "Ŧįmęőūŧ", - "timeout-label": "Ŧįmęőūŧ įʼn şęčőʼnđş", - "timeout-tooltip": "ĦŦŦP řęqūęşŧ ŧįmęőūŧ įʼn şęčőʼnđş", - "url-label": "ŮŖĿ", - "with-credential-label": "Ŵįŧĥ Cřęđęʼnŧįäľş", - "with-credential-tooltip": "Ŵĥęŧĥęř čřęđęʼnŧįäľş şūčĥ äş čőőĸįęş őř äūŧĥ ĥęäđęřş şĥőūľđ þę şęʼnŧ ŵįŧĥ čřőşş-şįŧę řęqūęşŧş." - }, - "data-source-settings": { - "alerting-settings-heading": "Åľęřŧįʼnģ", - "alerting-settings-label": "Mäʼnäģę äľęřŧ řūľęş įʼn Åľęřŧįʼnģ ŮĨ", - "alerting-settings-tooltip": "Mäʼnäģę äľęřŧ řūľęş ƒőř ŧĥįş đäŧä şőūřčę. Ŧő mäʼnäģę őŧĥęř äľęřŧįʼnģ řęşőūřčęş, äđđ äʼn Åľęřŧmäʼnäģęř đäŧä şőūřčę.", - "cert-key-reset": "Ŗęşęŧ", - "custom-headers-add": "Åđđ ĥęäđęř", - "custom-headers-header": "Ħęäđęř", - "custom-headers-header-placeholder": "Ħęäđęř Väľūę", - "custom-headers-header-remove": "Ŗęmővę ĥęäđęř", - "custom-headers-header-value": "Väľūę", - "custom-headers-title": "Cūşŧőm ĦŦŦP Ħęäđęřş", - "secure-socks-heading": "Ŝęčūřę Ŝőčĸş Přőχy", - "secure-socks-label": "Ēʼnäþľęđ", - "secure-socks-tooltip": "Cőʼnʼnęčŧ ŧő ŧĥįş đäŧäşőūřčę vįä ŧĥę şęčūřę şőčĸş přőχy.", - "tls-certification-label": "CÅ Cęřŧ", - "tls-certification-placeholder": "ßęģįʼnş ŵįŧĥ {{certificateBeginsWith}}", - "tls-client-certification-label": "Cľįęʼnŧ Cęřŧ", - "tls-client-key-label": "Cľįęʼnŧ Ķęy", - "tls-client-key-placeholder": "ßęģįʼnş ŵįŧĥ {{privateKeyBeginsWith}}", - "tls-heading": "ŦĿŜ/ŜŜĿ Åūŧĥ Đęŧäįľş", - "tls-server-name-label": "ŜęřvęřŃämę", - "tls-tooltip": "ŦĿŜ/ŜŜĿ Cęřŧş äřę ęʼnčřypŧęđ äʼnđ şŧőřęđ įʼn ŧĥę Ğřäƒäʼnä đäŧäþäşę." - }, - "date-time-picker": { - "apply": "Åppľy", - "calendar-icon-label": "Ŧįmę pįčĸęř", - "cancel": "Cäʼnčęľ", - "next-label": "Ńęχŧ mőʼnŧĥ", - "previous-label": "Přęvįőūş mőʼnŧĥ", - "select-placeholder": "Ŝęľęčŧ đäŧę/ŧįmę" - }, - "drawer": { - "close": "Cľőşę" - }, - "feature-badge": { - "experimental": "Ēχpęřįmęʼnŧäľ", - "new": "Ńęŵ!", - "preview": "Přęvįęŵ", - "private-preview": "Přįväŧę přęvįęŵ" - }, - "field-link-list": { - "external-links-heading": "Ēχŧęřʼnäľ ľįʼnĸş" - }, - "file-dropzone": { - "cancel-upload": "Cäʼnčęľ ūpľőäđ", - "file-too-large": "Fįľę įş ľäřģęř ŧĥäʼn {{size}}" - }, - "filter-input": { - "clear": "Cľęäř" - }, - "modal": { - "close-tooltip": "Cľőşę" - }, - "named-colors-palette": { - "text-color-swatch": "Ŧęχŧ čőľőř", - "transparent-swatch": "Ŧřäʼnşpäřęʼnŧ" - }, - "page-toolbar": { - "go-back": "Ğő þäčĸ (Ēşč)", - "search-dashboard-name": "Ŝęäřčĥ đäşĥþőäřđ þy ʼnämę", - "search-links": "Ŝęäřčĥ ľįʼnĸş", - "search-parent-folder": "Ŝęäřčĥ đäşĥþőäřđ įʼn ŧĥę {{parent}} ƒőľđęř" - }, - "pagination": { - "next-page": "ʼnęχŧ päģę", - "previous-page": "přęvįőūş päģę" - }, - "secret-form-field": { - "reset": "Ŗęşęŧ" - }, - "segment-async": { - "error": "Fäįľęđ ŧő ľőäđ őpŧįőʼnş", - "loading": "Ŀőäđįʼnģ őpŧįőʼnş...", - "no-options": "Ńő őpŧįőʼnş ƒőūʼnđ" - }, - "select": { - "default-create-label": "Ħįŧ ęʼnŧęř ŧő äđđ", - "no-options-label": "Ńő őpŧįőʼnş ƒőūʼnđ", - "placeholder": "Cĥőőşę" - }, - "series-color-picker-popover": { - "y-axis-usage": "Ůşę řįģĥŧ y-äχįş" - }, - "spinner": { - "aria-label": "Ŀőäđįʼnģ" - }, - "table": { - "copy": "Cőpy ŧő Cľįpþőäřđ", - "csv-counts": "Ŗőŵş:{{rows}}, Cőľūmʼnş:{{columns}} <5>", - "filter-popup-apply": "Øĸ", - "filter-popup-cancel": "Cäʼnčęľ", - "filter-popup-clear": "Cľęäř ƒįľŧęř", - "filter-popup-heading": "Fįľŧęř þy väľūęş:", - "no-values-label": "Ńő väľūęş", - "pagination-summary": "{{itemsRangeStart}} - {{displayedEnd}} őƒ {{numRows}} řőŵş" - }, - "tags-input": { - "add": "Åđđ" - }, - "user-icon": { - "active-text": "Åčŧįvę ľäşŧ 15m" - }, - "value-pill": { - "remove-button": "Ŗęmővę {{children}}" - }, - "viz-legend": { - "right-axis-indicator": "(řįģĥŧ y-äχįş)" - }, - "viz-tooltip": { - "actions-confirmation-input-placeholder": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő {{ actionTitle }}?", - "actions-confirmation-label": "Cőʼnƒįřmäŧįőʼn męşşäģę", - "actions-confirmation-message": "Přővįđę ä đęşčřįpŧįvę přőmpŧ ŧő čőʼnƒįřm őř čäʼnčęľ ŧĥę äčŧįőʼn.", - "footer-add-annotation": "Åđđ äʼnʼnőŧäŧįőʼn", - "footer-click-to-action": "Cľįčĸ ŧő {{actionTitle}}", - "footer-click-to-navigate": "Cľįčĸ ŧő őpęʼn {{linkTitle}}" - } - }, - "graph": { - "container": { - "content": "Ŗęʼnđęřįʼnģ ŧőő mäʼny şęřįęş įʼn ä şįʼnģľę päʼnęľ mäy įmpäčŧ pęřƒőřmäʼnčę äʼnđ mäĸę đäŧä ĥäřđęř ŧő řęäđ. Cőʼnşįđęř řęƒįʼnįʼnģ yőūř qūęřįęş.", - "show-all-series": "Ŝĥőŵ äľľ {{length}}", - "show-only-series": "Ŝĥőŵįʼnģ őʼnľy {{MAX_NUMBER_OF_TIME_SERIES}} şęřįęş", - "title": "Ğřäpĥ" - } - }, - "help-modal": { - "column-headers": { - "description": "Đęşčřįpŧįőʼn", - "keys": "Ķęyş" - }, - "shortcuts-category": { - "dashboard": "Đäşĥþőäřđ", - "focused-panel": "Főčūşęđ päʼnęľ", - "global": "Ğľőþäľ", - "time-range": "Ŧįmę řäʼnģę" - }, - "shortcuts-description": { - "change-theme": "Cĥäʼnģę ŧĥęmę", - "collapse-all-rows": "Cőľľäpşę äľľ řőŵş", - "copy-time-range": "Cőpy ŧįmę řäʼnģę", - "dashboard-settings": "Đäşĥþőäřđ şęŧŧįʼnģş", - "duplicate-panel": "Đūpľįčäŧę Päʼnęľ", - "exit-edit/setting-views": "Ēχįŧ ęđįŧ/şęŧŧįʼnģ vįęŵş", - "expand-all-rows": "Ēχpäʼnđ äľľ řőŵş", - "go-to-dashboards": "Ğő ŧő Đäşĥþőäřđş", - "go-to-explore": "Ğő ŧő Ēχpľőřę", - "go-to-home-dashboard": "Ğő ŧő Ħőmę Đäşĥþőäřđ", - "go-to-profile": "Ğő ŧő Přőƒįľę", - "make-time-range-permanent": "Mäĸę ŧįmę řäʼnģę äþşőľūŧę/pęřmäʼnęʼnŧ", - "move-time-range-back": "Mővę ŧįmę řäʼnģę þäčĸ", - "move-time-range-forward": "Mővę ŧįmę řäʼnģę ƒőřŵäřđ", - "open-search": "Øpęʼn şęäřčĥ", - "open-shared-modal": "Øpęʼn Päʼnęľ Ŝĥäřę Mőđäľ", - "paste-time-range": "Päşŧę ŧįmę řäʼnģę", - "refresh-all-panels": "Ŗęƒřęşĥ äľľ päʼnęľş", - "remove-panel": "Ŗęmővę Päʼnęľ", - "save-dashboard": "Ŝävę đäşĥþőäřđ", - "show-all-shortcuts": "Ŝĥőŵ äľľ ĸęyþőäřđ şĥőřŧčūŧş", - "toggle-active-mode": "Ŧőģģľę įʼn-äčŧįvę / vįęŵ mőđę", - "toggle-all-panel-legends": "Ŧőģģľę äľľ päʼnęľ ľęģęʼnđş", - "toggle-auto-fit": "Ŧőģģľę äūŧő ƒįŧ päʼnęľş (ęχpęřįmęʼnŧäľ ƒęäŧūřę)", - "toggle-exemplars": "Ŧőģģľę ęχęmpľäřş įʼn äľľ päʼnęľ", - "toggle-graph-crosshair": "Ŧőģģľę şĥäřęđ ģřäpĥ čřőşşĥäįř", - "toggle-kiosk": "Ŧőģģľę ĸįőşĸ mőđę (ĥįđęş ŧőp ʼnäv)", - "toggle-panel-edit": "Ŧőģģľę päʼnęľ ęđįŧ vįęŵ", - "toggle-panel-fullscreen": "Ŧőģģľę päʼnęľ ƒūľľşčřęęʼn vįęŵ", - "toggle-panel-legend": "Ŧőģģľę päʼnęľ ľęģęʼnđ", - "zoom-out-time-range": "Żőőm őūŧ ŧįmę řäʼnģę" - }, - "title": "Ŝĥőřŧčūŧş" - }, - "help-wizard": { - "download-snapshot": "Đőŵʼnľőäđ şʼnäpşĥőŧ", - "github-comment": "Cőpy Ğįŧĥūþ čőmmęʼnŧ", - "support-bundle": "Ÿőū čäʼn äľşő řęŧřįęvę ä şūppőřŧ þūʼnđľę čőʼnŧäįʼnįʼnģ įʼnƒőřmäŧįőʼn čőʼnčęřʼnįʼnģ yőūř Ğřäƒäʼnä įʼnşŧäʼnčę äʼnđ čőʼnƒįģūřęđ đäŧäşőūřčęş įʼn ŧĥę <1>şūppőřŧ þūʼnđľęş şęčŧįőʼn.", - "troubleshooting-help": "Ŧő řęqūęşŧ ŧřőūþľęşĥőőŧįʼnģ ĥęľp, şęʼnđ ä şʼnäpşĥőŧ őƒ ŧĥįş päʼnęľ ŧő Ğřäƒäʼnä Ŀäþş Ŧęčĥʼnįčäľ Ŝūppőřŧ. Ŧĥę şʼnäpşĥőŧ čőʼnŧäįʼnş qūęřy řęşpőʼnşę đäŧä äʼnđ päʼnęľ şęŧŧįʼnģş." - }, - "inspector": { - "query": { - "collapse-all": "Cőľľäpşę äľľ", - "copy-to-clipboard": "Cőpy ŧő čľįpþőäřđ", - "description": "Qūęřy įʼnşpęčŧőř äľľőŵş yőū ŧő vįęŵ řäŵ řęqūęşŧ äʼnđ řęşpőʼnşę. Ŧő čőľľęčŧ ŧĥįş đäŧä Ğřäƒäʼnä ʼnęęđş ŧő įşşūę ä ʼnęŵ qūęřy. Cľįčĸ řęƒřęşĥ þūŧŧőʼn þęľőŵ ŧő ŧřįģģęř ä ʼnęŵ qūęřy.", - "expand-all": "Ēχpäʼnđ äľľ", - "no-data": "Ńő řęqūęşŧ äʼnđ řęşpőʼnşę čőľľęčŧęđ yęŧ. Ħįŧ řęƒřęşĥ þūŧŧőʼn", - "refresh": "Ŗęƒřęşĥ" - } - }, - "ldap-drawer": { - "attributes-section": { - "description": "Ŝpęčįƒy ŧĥę ĿĐÅP äŧŧřįþūŧęş ŧĥäŧ mäp ŧő ŧĥę ūşęř'ş ģįvęʼn ʼnämę, şūřʼnämę, äʼnđ ęmäįľ äđđřęşş, ęʼnşūřįʼnģ ŧĥę äppľįčäŧįőʼn čőřřęčŧľy řęŧřįęvęş äʼnđ đįşpľäyş ūşęř įʼnƒőřmäŧįőʼn.", - "email-label": "Ēmäįľ", - "label": "Åŧŧřįþūŧęş", - "member-of-label": "Męmþęř ؃", - "name-label": "Ńämę", - "surname-label": "Ŝūřʼnämę", - "username-label": "Ůşęřʼnämę" - }, - "extra-security-section": { - "client-cert-label": "Cľįęʼnŧ čęřŧįƒįčäŧę päŧĥ", - "client-cert-placeholder": "/päŧĥ/ŧő/čľįęʼnŧ_čęřŧ.pęm", - "client-cert-value-label": "Cľįęʼnŧ čęřŧįƒįčäŧę čőʼnŧęʼnŧ", - "client-cert-value-placeholder": "Cľįęʼnŧ čęřŧįƒįčäŧę čőʼnŧęʼnŧ įʼn þäşę64", - "client-key-label": "Cľįęʼnŧ ĸęy päŧĥ", - "client-key-placeholder": "/päŧĥ/ŧő/čľįęʼnŧ_ĸęy.pęm", - "client-key-value-label": "Cľįęʼnŧ ĸęy čőʼnŧęʼnŧ", - "client-key-value-placeholder": "Cľįęʼnŧ ĸęy čőʼnŧęʼnŧ įʼn þäşę64", - "encryption-provider-base-64": "ßäşę64-ęʼnčőđęđ čőʼnŧęʼnŧ", - "encryption-provider-description": "X.509 čęřŧįƒįčäŧę přővįđęş ŧĥę pūþľįč päřŧ, ŵĥįľę ŧĥę přįväŧę ĸęy įşşūęđ įʼn ä PĶCŜ#8 ƒőřmäŧ přővįđęş ŧĥę přįväŧę päřŧ őƒ ŧĥę äşymmęŧřįč ęʼnčřypŧįőʼn.", - "encryption-provider-file-path": "Päŧĥ ŧő ƒįľęş", - "encryption-provider-label": "Ēʼnčřypŧįőʼn ĸęy äʼnđ čęřŧįƒįčäŧę přővįşįőʼn şpęčįƒįčäŧįőʼn.", - "label": "Ēχŧřä şęčūřįŧy męäşūřęş", - "min-tls-version-description": "Ŧĥįş įş ŧĥę mįʼnįmūm ŦĿŜ vęřşįőʼn äľľőŵęđ. Åččępŧęđ väľūęş äřę: ŦĿŜ1.2, ŦĿŜ1.3.", - "min-tls-version-label": "Mįʼn ŦĿŜ vęřşįőʼn", - "root-ca-cert-label": "Ŗőőŧ CÅ čęřŧįƒįčäŧę päŧĥ", - "root-ca-cert-placeholder": "/päŧĥ/ŧő/řőőŧ_čä_čęřŧ.pęm", - "root-ca-cert-value-label": "Ŗőőŧ CÅ čęřŧįƒįčäŧę čőʼnŧęʼnŧ", - "root-ca-cert-value-placeholder": "ęχämpľę: ĿŜ0ŧĿŜ1CŖŮđĴŦįßĐŖVĴŮŜŮŻĴQ0FŮŖŜ0ŧĿŜ0ŧ", - "start-tls-description": "Ĩƒ şęŧ ŧő ŧřūę, ūşę ĿĐÅP ŵįŧĥ ŜŦÅŖŦŦĿŜ įʼnşŧęäđ őƒ ĿĐÅPŜ", - "start-tls-label": "Ŝŧäřŧ ŦĿŜ", - "tls-ciphers-label": "ŦĿŜ čįpĥęřş", - "tls-ciphers-placeholder": "ęχämpľę: ŦĿŜ_ÅĒŜ_256_ĞCM_ŜĦÅ384", - "use-ssl-description": "Ŝęŧ ŧő ŧřūę įƒ ĿĐÅP şęřvęř şĥőūľđ ūşę ŦĿŜ čőʼnʼnęčŧįőʼn (ęįŧĥęř ŵįŧĥ ŜŦÅŖŦŦĿŜ őř ĿĐÅPŜ)", - "use-ssl-label": "Ůşę ŜŜĿ", - "use-ssl-tooltip": "Főř ä čőmpľęŧę ľįşŧ őƒ şūppőřŧęđ čįpĥęřş äʼnđ ŦĿŜ vęřşįőʼnş, řęƒęř ŧő:" - }, - "group-mapping": { - "grafana-admin": { - "description": "Ĩƒ ęʼnäþľęđ, äľľ ūşęřş ƒřőm ŧĥįş ģřőūp ŵįľľ þę Ğřäƒäʼnä Åđmįʼnş", - "label": "Ğřäƒäʼnä Åđmįʼn" - }, - "group-dn": { - "description": "Ŧĥę ʼnämę őƒ ŧĥę ĸęy ūşęđ ŧő ęχŧřäčŧ ŧĥę ĨĐ ŧőĸęʼn ƒřőm ŧĥę řęŧūřʼnęđ ØÅūŧĥ2 ŧőĸęʼn.", - "label": "Ğřőūp ĐŃ" - }, - "org-id": { - "description": "Ŧĥę Ğřäƒäʼnä őřģäʼnįžäŧįőʼn đäŧäþäşę įđ. Đęƒäūľŧ őřģ (ĨĐ 1) ŵįľľ þę ūşęđ įƒ ľęƒŧ őūŧ", - "label": "Øřģ ĨĐ" - }, - "org-role": { - "label": "Øřģ řőľę *" - }, - "remove": { - "button": "Ŗęmővę ģřőūp mäppįʼnģ" - } - }, - "group-mapping-section": { - "add": { - "button": "Åđđ ģřőūp mäppįʼnģ" - }, - "description": "Mäp ĿĐÅP ģřőūpş ŧő Ğřäƒäʼnä őřģ řőľęş", - "group-search-base-dns-label": "Ğřőūp şęäřčĥ þäşę ĐŃŜ", - "group-search-base-dns-placeholder": "ęχämpľę: őū=ģřőūpş,đč=ęχämpľę,đč=čőm", - "group-search-filter-description": "Ůşęđ ŧő ƒįľŧęř äʼnđ įđęʼnŧįƒy ģřőūp ęʼnŧřįęş ŵįŧĥįʼn ŧĥę đįřęčŧőřy", - "group-search-filter-label": "Ğřőūp şęäřčĥ ƒįľŧęř", - "group-search-filter-user-attribute-description": "Ĩđęʼnŧįƒįęş ūşęřş ŵįŧĥįʼn ģřőūp ęʼnŧřįęş ƒőř ƒįľŧęřįʼnģ pūřpőşęş", - "group-search-filter-user-attribute-label": "Ğřőūp ʼnämę äŧŧřįþūŧę", - "label": "Ğřőūp mäppįʼnģ", - "skip-org-role-sync-description": "Přęvęʼnŧ şyʼnčĥřőʼnįžįʼnģ ūşęřş’ őřģäʼnįžäŧįőʼn řőľęş ƒřőm yőūř ĨđP", - "skip-org-role-sync-label": "Ŝĸįp őřģäʼnįžäŧįőʼn řőľę şyʼnč" - }, - "misc-section": { - "allow-sign-up-descrition": "Ĩƒ ʼnőŧ ęʼnäþľęđ, őʼnľy ęχįşŧįʼnģ Ğřäƒäʼnä ūşęřş čäʼn ľőģ įʼn ūşįʼnģ ĿĐÅP", - "allow-sign-up-label": "Åľľőŵ şįģʼn-ūp", - "label": "Mįşč", - "port-description": "Đęƒäūľŧ pőřŧ įş 389 ŵįŧĥőūŧ ŜŜĿ őř 636 ŵįŧĥ ŜŜĿ", - "port-label": "Pőřŧ", - "timeout-description": "Ŧįmęőūŧ įʼn şęčőʼnđş ƒőř ŧĥę čőʼnʼnęčŧįőʼn ŧő ŧĥę ĿĐÅP şęřvęř", - "timeout-label": "Ŧįmęőūŧ" - }, - "title": "Åđväʼnčęđ şęŧŧįʼnģş" - }, - "ldap-settings-page": { - "advanced-settings-section": { - "edit-button": "Ēđįŧ", - "subtitle": "Mäppįʼnģş, ęχŧřä şęčūřįŧy męäşūřęş, äʼnđ mőřę.", - "title": "Åđväʼnčęđ Ŝęŧŧįʼnģş" - }, - "alert": { - "discard-success": "ĿĐÅP şęŧŧįʼnģş đįşčäřđęđ", - "error-fetching": "Ēřřőř ƒęŧčĥįʼnģ ĿĐÅP şęŧŧįʼnģş", - "error-saving": "Ēřřőř şävįʼnģ ĿĐÅP şęŧŧįʼnģş", - "error-validate-form": "Ēřřőř väľįđäŧįʼnģ ĿĐÅP şęŧŧįʼnģş", - "feature-flag-disabled": "Ŧĥįş päģę įş őʼnľy äččęşşįþľę þy ęʼnäþľįʼnģ ŧĥę <1>şşőŜęŧŧįʼnģşĿĐÅP ƒęäŧūřę ƒľäģ.", - "saved": "ĿĐÅP şęŧŧįʼnģş şävęđ" - }, - "bind-dn": { - "description": "Đįşŧįʼnģūįşĥęđ ʼnämę őƒ ŧĥę äččőūʼnŧ ūşęđ ŧő þįʼnđ äʼnđ äūŧĥęʼnŧįčäŧę ŧő ŧĥę ĿĐÅP şęřvęř.", - "label": "ßįʼnđ ĐŃ", - "placeholder": "ęχämpľę: čʼn=äđmįʼn,đč=ģřäƒäʼnä,đč=őřģ" - }, - "bind-password": { - "label": "ßįʼnđ päşşŵőřđ" - }, - "buttons-section": { - "disable-button": "Đįşäþľę", - "discard-button": "Đįşčäřđ", - "save-and-enable-button": "Ŝävę äʼnđ ęʼnäþľę", - "save-button": "Ŝävę" - }, - "documentation": "đőčūmęʼnŧäŧįőʼn", - "host": { - "description": "Ħőşŧʼnämę őř ĨP äđđřęşş őƒ ŧĥę ĿĐÅP şęřvęř yőū ŵįşĥ ŧő čőʼnʼnęčŧ ŧő.", - "error": "Ŝęřvęř ĥőşŧ įş ä řęqūįřęđ ƒįęľđ", - "label": "Ŝęřvęř ĥőşŧ", - "placeholder": "ęχämpľę: 127.0.0.1" - }, - "login-form-alert": { - "description": "Ÿőūř ĿĐÅP čőʼnƒįģūřäŧįőʼn įş ʼnőŧ ŵőřĸįʼnģ þęčäūşę ŧĥę þäşįč ľőģįʼn ƒőřm įş čūřřęʼnŧľy đįşäþľęđ. Pľęäşę ęʼnäþľę ŧĥę ľőģįʼn ƒőřm ŧő ūşę ĿĐÅP äūŧĥęʼnŧįčäŧįőʼn. Ÿőū čäʼn ęʼnäþľę įŧ őʼn ŧĥę Åūŧĥęʼnŧįčäŧįőʼn päģę ūʼnđęř “Åūŧĥ şęŧŧįʼnģş”.", - "title": "ßäşįč ľőģįʼn đįşäþľęđ" - }, - "search_filter": { - "description": "ĿĐÅP şęäřčĥ ƒįľŧęř ūşęđ ŧő ľőčäŧę şpęčįƒįč ęʼnŧřįęş ŵįŧĥįʼn ŧĥę đįřęčŧőřy.", - "error": "Ŝęäřčĥ ƒįľŧęř įş ä řęqūįřęđ ƒįęľđ", - "label": "Ŝęäřčĥ ƒįľŧęř", - "placeholder": "ęχämpľę: čʼn=%ş" - }, - "search-base-dns": { - "description": "Åʼn äřřäy őƒ þäşę đʼnş ŧő şęäřčĥ ŧĥřőūģĥ.", - "error": "Ŝęäřčĥ þäşę ĐŃŜ įş ä řęqūįřęđ ƒįęľđ", - "label": "Ŝęäřčĥ þäşę ĐŃŜ", - "placeholder": "ęχämpľę: đč=ģřäƒäʼnä,đč=őřģ" - }, - "subtitle": "Ŧĥę ĿĐÅP įʼnŧęģřäŧįőʼn įʼn Ğřäƒäʼnä äľľőŵş yőūř Ğřäƒäʼnä ūşęřş ŧő ľőģ įʼn ŵįŧĥ ŧĥęįř ĿĐÅP čřęđęʼnŧįäľş. Fįʼnđ őūŧ mőřę įʼn őūř <2><0>đőčūmęʼnŧäŧįőʼn.", - "title": "ßäşįč Ŝęŧŧįʼnģş" - }, - "library-panel": { - "add-modal": { - "cancel": "Cäʼnčęľ", - "create": "Cřęäŧę ľįþřäřy päʼnęľ", - "error": "Ŀįþřäřy päʼnęľ ŵįŧĥ ŧĥįş ʼnämę äľřęäđy ęχįşŧş", - "folder": "Ŝävę įʼn ƒőľđęř", - "folder-description": "Ŀįþřäřy päʼnęľ pęřmįşşįőʼnş äřę đęřįvęđ ƒřőm ŧĥę ƒőľđęř pęřmįşşįőʼnş", - "name": "Ŀįþřäřy päʼnęľ ʼnämę" - }, - "add-widget": { - "title": "Åđđ päʼnęľ ƒřőm päʼnęľ ľįþřäřy" - }, - "empty-state": { - "message": "Ÿőū ĥävęʼn'ŧ čřęäŧęđ äʼny ľįþřäřy päʼnęľş yęŧ", - "more-info": "Cřęäŧę ä ľįþřäřy päʼnęľ ƒřőm äʼny ęχįşŧįʼnģ đäşĥþőäřđ päʼnęľ ŧĥřőūģĥ ŧĥę päʼnęľ čőʼnŧęχŧ męʼnū. <2>Ŀęäřʼn mőřę" - } - }, - "library-panels": { - "empty-state": { - "message": "Ńő ľįþřäřy päʼnęľş ƒőūʼnđ" - }, - "loading-panel-text": "Ŀőäđįʼnģ ľįþřäřy päʼnęľ", - "modal": { - "body_one": "Ŧĥįş päʼnęľ įş þęįʼnģ ūşęđ įʼn {{count}} đäşĥþőäřđ. Pľęäşę čĥőőşę ŵĥįčĥ đäşĥþőäřđ ŧő vįęŵ ŧĥę päʼnęľ įʼn:", - "body_other": "Ŧĥįş päʼnęľ įş þęįʼnģ ūşęđ įʼn {{count}} đäşĥþőäřđ. Pľęäşę čĥőőşę ŵĥįčĥ đäşĥþőäřđ ŧő vįęŵ ŧĥę päʼnęľ įʼn:", - "button-cancel": "Cäʼnčęľ", - "button-view-panel1": "Vįęŵ päʼnęľ įʼn {{label}}...", - "button-view-panel2": "Vįęŵ päʼnęľ įʼn đäşĥþőäřđ...", - "panel-not-linked": "Päʼnęľ įş ʼnőŧ ľįʼnĸęđ ŧő ä đäşĥþőäřđ. Åđđ ŧĥę päʼnęľ ŧő ä đäşĥþőäřđ äʼnđ řęŧřy.", - "select-no-options-message": "Ńő đäşĥþőäřđş ƒőūʼnđ", - "select-placeholder": "Ŝŧäřŧ ŧypįʼnģ ŧő şęäřčĥ ƒőř đäşĥþőäřđ", - "title": "Vįęŵ päʼnęľ įʼn đäşĥþőäřđ" - }, - "save": { - "error": "Ēřřőř şävįʼnģ ľįþřäřy päʼnęľ: \"{{errorMsg}}\"", - "success": "Ŀįþřäřy päʼnęľ şävęđ" - } - }, - "link": { - "share": { - "config-alert-description": "Ůpđäŧįʼnģ yőūř şęŧŧįʼnģş ŵįľľ mőđįƒy ŧĥę đęƒäūľŧ čőpy ľįʼnĸ ŧő įʼnčľūđę ŧĥęşę čĥäʼnģęş. Pľęäşę ʼnőŧę ŧĥäŧ ŧĥęşę şęŧŧįʼnģş äřę şävęđ ŵįŧĥįʼn yőūř čūřřęʼnŧ þřőŵşęř şčőpę.", - "config-alert-title": "Ŀįʼnĸ şęŧŧįʼnģş", - "config-description": "Cřęäŧę ä pęřşőʼnäľįžęđ, đįřęčŧ ľįʼnĸ ŧő şĥäřę yőūř đäşĥþőäřđ ŵįŧĥįʼn yőūř őřģäʼnįžäŧįőʼn, ŵįŧĥ ŧĥę ƒőľľőŵįʼnģ čūşŧőmįžäŧįőʼn şęŧŧįʼnģş:", - "copy-link-button": "Cőpy ľįʼnĸ", - "copy-to-clipboard": "Ŀįʼnĸ čőpįęđ ŧő čľįpþőäřđ", - "short-url-label": "Ŝĥőřŧęʼn ľįʼnĸ", - "time-range-description": "Cĥäʼnģę ŧĥę čūřřęʼnŧ řęľäŧįvę ŧįmę řäʼnģę ŧő äʼn äþşőľūŧę ŧįmę řäʼnģę", - "time-range-label": "Ŀőčĸ ŧįmę řäʼnģę" - }, - "share-panel": { - "config-description": "Cřęäŧę ä pęřşőʼnäľįžęđ, đįřęčŧ ľįʼnĸ ŧő şĥäřę yőūř päʼnęľ ŵįŧĥįʼn yőūř őřģäʼnįžäŧįőʼn, ŵįŧĥ ŧĥę ƒőľľőŵįʼnģ čūşŧőmįžäŧįőʼn şęŧŧįʼnģş:", - "download-image": "Đőŵʼnľőäđ įmäģę", - "render-image": "Ğęʼnęřäŧę įmäģę", - "render-image-error": "Fäįľęđ ŧő řęʼnđęř päʼnęľ įmäģę", - "render-image-error-description": "Åʼn ęřřőř őččūřřęđ ŵĥęʼn ģęʼnęřäŧįʼnģ ŧĥę įmäģę" - } - }, - "lock-icon": "ľőčĸ įčőʼn", - "login": { - "divider": { - "connecting-text": "őř" - }, - "error": { - "blocked": "Ÿőū ĥävę ęχčęęđęđ ŧĥę ʼnūmþęř őƒ ľőģįʼn äŧŧęmpŧş ƒőř ŧĥįş ūşęř. Pľęäşę ŧřy äģäįʼn ľäŧęř.", - "invalid-user-or-password": "Ĩʼnväľįđ ūşęřʼnämę őř päşşŵőřđ", - "title": "Ŀőģįʼn ƒäįľęđ", - "unknown": "Ůʼnĸʼnőŵʼn ęřřőř őččūřřęđ" - }, - "forgot-password": "Főřģőŧ yőūř päşşŵőřđ?", - "form": { - "confirmation-code": "Cőʼnƒįřmäŧįőʼn čőđę įş řęqūįřęđ", - "confirmation-code-label": "Cőʼnƒįřmäŧįőʼn čőđę", - "confirmation-code-placeholder": "čőʼnƒįřmäŧįőʼn čőđę", - "email-label": "Ēmäįľ", - "email-placeholder": "ęmäįľ", - "email-required": "Ēmäįľ įş řęqūįřęđ", - "name-label": "Ńämę", - "name-placeholder": "ʼnämę", - "password-label": "Päşşŵőřđ", - "password-placeholder": "päşşŵőřđ", - "password-required": "Päşşŵőřđ įş řęqūįřęđ", - "submit-label": "Ŀőģ įʼn", - "submit-loading-label": "Ŀőģģįʼnģ įʼn...", - "username-label": "Ēmäįľ őř ūşęřʼnämę", - "username-placeholder": "ęmäįľ őř ūşęřʼnämę", - "username-required": "Ēmäįľ őř ūşęřʼnämę įş řęqūįřęđ", - "verify-email-label": "Ŝęʼnđ ä vęřįƒįčäŧįőʼn ęmäįľ", - "verify-email-loading-label": "Ŝęʼnđįʼnģ ęmäįľ..." - }, - "layout": { - "update-password": "Ůpđäŧę yőūř päşşŵőřđ" - }, - "services": { - "sing-in-with-prefix": "Ŝįģʼn įʼn ŵįŧĥ {{serviceName}}" - }, - "signup": { - "button-label": "Ŝįģʼn ūp", - "new-to-question": "Ńęŵ ŧő Ğřäƒäʼnä?" - } - }, - "logs": { - "infinite-scroll": { - "end-of-range": "Ēʼnđ őƒ ŧĥę şęľęčŧęđ ŧįmę řäʼnģę.", - "load-more": "Ŝčřőľľ ŧő ľőäđ mőřę", - "load-newer": "Ŀőäđįʼnģ ʼnęŵęř ľőģş...", - "load-older": "Ŀőäđįʼnģ őľđęř ľőģş...", - "older-logs": "Øľđęř ľőģş" - }, - "log-details": { - "fields": "Fįęľđş", - "links": "Ŀįʼnĸş", - "log-line": "Ŀőģ ľįʼnę", - "no-details": "Ńő đęŧäįľş äväįľäþľę" - }, - "log-line-menu": { - "copy-link": "Cőpy ľįʼnĸ ŧő ľőģ ľįʼnę", - "copy-log": "Cőpy ľőģ ľįʼnę", - "icon-label": "Ŀőģ męʼnū", - "pin-to-outline": "Pįʼn ľőģ", - "show-context": "Ŝĥőŵ čőʼnŧęχŧ", - "unpin-from-outline": "Ůʼnpįʼn ľőģ" - }, - "log-row-message": { - "ellipsis": "… ", - "more": "mőřę", - "see-details": "Ŝęę ľőģ đęŧäįľş" - }, - "log-rows": { - "disable-popover": { - "confirm": "Cőʼnƒįřm", - "message": "Ÿőū äřę äþőūŧ ŧő đįşäþľę ŧĥę ľőģş ƒįľŧęř męʼnū. Ŧő řę-ęʼnäþľę įŧ, şęľęčŧ ŧęχŧ įʼn ä ľőģ ľįʼnę ŵĥįľę ĥőľđįʼnģ ŧĥę äľŧ ĸęy.", - "title": "Đįşäþľę męʼnū" - }, - "disable-popover-message": { - "shortcut": "äľŧ+şęľęčŧ ŧő ęʼnäþľę äģäįʼn" - } - }, - "logs-navigation": { - "newer-logs": "Ńęŵęř ľőģş", - "older-logs": "Øľđęř ľőģş", - "scroll-bottom": "Ŝčřőľľ ŧő þőŧŧőm", - "scroll-top": "Ŝčřőľľ ŧő ŧőp", - "start-of-range": "Ŝŧäřŧ őƒ řäʼnģę" - }, - "popover-menu": { - "copy": "Cőpy şęľęčŧįőʼn", - "disable-menu": "Đįşäþľę męʼnū", - "line-contains": "Åđđ äş ľįʼnę čőʼnŧäįʼnş ƒįľŧęř", - "line-contains-not": "Åđđ äş ľįʼnę đőęş ʼnőŧ čőʼnŧäįʼn ƒįľŧęř" - } - }, - "migrate-to-cloud": { - "build-snapshot": { - "description": "Ŧĥįş ŧőőľ čäʼn mįģřäŧę şőmę řęşőūřčęş ƒřőm ŧĥįş įʼnşŧäľľäŧįőʼn ŧő yőūř čľőūđ şŧäčĸ. Ŧő ģęŧ şŧäřŧęđ, yőū'ľľ ʼnęęđ ŧő čřęäŧę ä şʼnäpşĥőŧ őƒ ŧĥįş įʼnşŧäľľäŧįőʼn. Cřęäŧįʼnģ ä şʼnäpşĥőŧ ŧypįčäľľy ŧäĸęş ľęşş ŧĥäʼn ŧŵő mįʼnūŧęş. Ŧĥę şʼnäpşĥőŧ įş şŧőřęđ äľőʼnģşįđę ŧĥįş Ğřäƒäʼnä įʼnşŧäľľäŧįőʼn.", - "title": "Ńő şʼnäpşĥőŧ ęχįşŧş", - "when-complete": "Øʼnčę ŧĥę şʼnäpşĥőŧ įş čőmpľęŧę, yőū ŵįľľ þę äþľę ŧő ūpľőäđ įŧ ŧő yőūř čľőūđ şŧäčĸ." - }, - "building-snapshot": { - "description": "Ŵę'řę čřęäŧįʼnģ ä pőįʼnŧ-įʼn-ŧįmę şʼnäpşĥőŧ őƒ ŧĥę čūřřęʼnŧ şŧäŧę őƒ ŧĥįş įʼnşŧäľľäŧįőʼn. Øʼnčę ŧĥę şʼnäpşĥőŧ įş čőmpľęŧę. yőū'ľľ þę äþľę ŧő ūpľőäđ įŧ ŧő Ğřäƒäʼnä Cľőūđ.", - "description-eta": "Cřęäŧįʼnģ ä şʼnäpşĥőŧ ŧypįčäľľy ŧäĸęş ľęşş ŧĥäʼn ŧŵő mįʼnūŧęş.", - "title": "ßūįľđįʼnģ įʼnşŧäľľäŧįőʼn şʼnäpşĥőŧ" - }, - "can-i-move": { - "body": "Øʼnčę yőū čőʼnʼnęčŧ ŧĥįş įʼnşŧäľľäŧįőʼn ŧő ä čľőūđ şŧäčĸ, yőū'ľľ þę äþľę ŧő ūpľőäđ đäŧä şőūřčęş äʼnđ đäşĥþőäřđş.", - "link-title": "Ŀęäřʼn äþőūŧ mįģřäŧįʼnģ őŧĥęř şęŧŧįʼnģş", - "title": "Cäʼn Ĩ mővę ŧĥįş įʼnşŧäľľäŧįőʼn ŧő Ğřäƒäʼnä Cľőūđ?" - }, - "connect-modal": { - "body-cloud-stack": "Ÿőū'ľľ äľşő ʼnęęđ ä čľőūđ şŧäčĸ. Ĩƒ yőū ĵūşŧ şįģʼnęđ ūp, ŵę'ľľ äūŧőmäŧįčäľľy čřęäŧę yőūř ƒįřşŧ şŧäčĸ. Ĩƒ yőū ĥävę äʼn äččőūʼnŧ, yőū'ľľ ʼnęęđ ŧő şęľęčŧ őř čřęäŧę ä şŧäčĸ.", - "body-get-started": "Ŧő ģęŧ şŧäřŧęđ, yőū'ľľ ʼnęęđ ä Ğřäƒäʼnä.čőm äččőūʼnŧ.", - "body-sign-up": "Ŝįģʼn ūp ƒőř ä Ğřäƒäʼnä.čőm äččőūʼnŧ", - "body-token": "Ÿőūř şęľƒ-mäʼnäģęđ Ğřäƒäʼnä įʼnşŧäľľäŧįőʼn ʼnęęđş şpęčįäľ äččęşş ŧő şęčūřęľy mįģřäŧę čőʼnŧęʼnŧ. Ÿőū'ľľ ʼnęęđ ŧő čřęäŧę ä mįģřäŧįőʼn ŧőĸęʼn őʼn yőūř čĥőşęʼn čľőūđ şŧäčĸ.", - "body-token-field": "Mįģřäŧįőʼn ŧőĸęʼn", - "body-token-field-placeholder": "Päşŧę ŧőĸęʼn ĥęřę", - "body-token-instructions": "Ŀőģ įʼnŧő yőūř čľőūđ şŧäčĸ äʼnđ ʼnävįģäŧę ŧő Åđmįʼnįşŧřäŧįőʼn, Ğęʼnęřäľ, Mįģřäŧę ŧő Ğřäƒäʼnä Cľőūđ. Cřęäŧę ä mįģřäŧįőʼn ŧőĸęʼn őʼn ŧĥäŧ şčřęęʼn äʼnđ päşŧę ŧĥę ŧőĸęʼn ĥęřę.", - "body-view-stacks": "Vįęŵ my čľőūđ şŧäčĸş", - "cancel": "Cäʼnčęľ", - "connect": "Cőʼnʼnęčŧ ŧő ŧĥįş şŧäčĸ", - "connecting": "Cőʼnʼnęčŧįʼnģ ŧő ŧĥįş şŧäčĸ...", - "title": "Cőʼnʼnęčŧ ŧő ä čľőūđ şŧäčĸ", - "token-error-title": "Ēřřőř şävįʼnģ ŧőĸęʼn", - "token-errors": { - "instance-request-error": "Åʼn ęřřőř őččūřřęđ ŵĥįľę äŧŧęmpŧįʼnģ ŧő vęřįƒy ŧĥę čľőūđ įʼnşŧäʼnčę'ş čőʼnʼnęčŧįvįŧy. Pľęäşę čĥęčĸ ŧĥę ʼnęŧŵőřĸ şęŧŧįʼnģş őř čľőūđ įʼnşŧäʼnčę şŧäŧūş.", - "instance-unreachable": "Ŧĥę čľőūđ įʼnşŧäʼnčę čäʼnʼnőŧ þę řęäčĥęđ. Mäĸę şūřę ŧĥę įʼnşŧäʼnčę įş řūʼnʼnįʼnģ äʼnđ ŧřy äģäįʼn.", - "migration-disabled": "Cľőūđ mįģřäŧįőʼnş äřę đįşäþľęđ őʼn ŧĥįş įʼnşŧäʼnčę.", - "session-creation-failure": "Ŧĥęřę ŵäş äʼn ęřřőř čřęäŧįʼnģ ŧĥę mįģřäŧįőʼn. Pľęäşę ŧřy äģäįʼn.", - "token-invalid": "Ŧőĸęʼn įş ʼnőŧ väľįđ. Ğęʼnęřäŧę ä ʼnęŵ ŧőĸęʼn őʼn yőūř čľőūđ įʼnşŧäʼnčę äʼnđ ŧřy äģäįʼn.", - "token-not-saved": "Ŧĥęřę ŵäş äʼn ęřřőř şävįʼnģ ŧĥę ŧőĸęʼn. Ŝęę ŧĥę Ğřäƒäʼnä şęřvęř ľőģş ƒőř mőřę đęŧäįľş.", - "token-request-error": "Åʼn ęřřőř őččūřřęđ ŵĥįľę väľįđäŧįʼnģ ŧĥę ŧőĸęʼn. Pľęäşę čĥęčĸ ŧĥę Ğřäƒäʼnä įʼnşŧäʼnčę ľőģş.", - "token-validation-failure": "Ŧőĸęʼn įş ʼnőŧ väľįđ. Pľęäşę ęʼnşūřę ŧĥę ŧőĸęʼn mäŧčĥęş ŧĥę mįģřäŧįőʼn ŧőĸęʼn őʼn yőūř čľőūđ įʼnşŧäʼnčę." - }, - "token-required-error": "Mįģřäŧįőʼn ŧőĸęʼn įş řęqūįřęđ" - }, - "cta": { - "button": "Mįģřäŧę ŧĥįş įʼnşŧäʼnčę ŧő Cľőūđ", - "header": "Ŀęŧ ūş mäʼnäģę yőūř Ğřäƒäʼnä şŧäčĸ" - }, - "delete-migration-token-confirm": { - "body": "Ĩƒ yőū'vę äľřęäđy ūşęđ ŧĥįş ŧőĸęʼn ŵįŧĥ ä şęľƒ-mäʼnäģęđ įʼnşŧäľľäŧįőʼn, ŧĥäŧ įʼnşŧäľľäŧįőʼn ŵįľľ ʼnő ľőʼnģęř þę äþľę ŧő ūpľőäđ čőʼnŧęʼnŧ.", - "confirm-button": "Đęľęŧę ŧőĸęʼn", - "error-title": "Ēřřőř đęľęŧįʼnģ ŧőĸęʼn", - "title": "Đęľęŧę mįģřäŧįőʼn ŧőĸęʼn" - }, - "disconnect-modal": { - "body": "Ŧĥįş ŵįľľ řęmővę ŧĥę mįģřäŧįőʼn ŧőĸęʼn ƒřőm ŧĥįş įʼnşŧäľľäŧįőʼn. Ĩƒ yőū ŵįşĥ ŧő ūpľőäđ mőřę řęşőūřčęş įʼn ŧĥę ƒūŧūřę, yőū ŵįľľ ʼnęęđ ŧő ęʼnŧęř ä ʼnęŵ mįģřäŧįőʼn ŧőĸęʼn.", - "cancel": "Cäʼnčęľ", - "disconnect": "Đįşčőʼnʼnęčŧ", - "disconnecting": "Đįşčőʼnʼnęčŧįʼnģ...", - "error": "Ŧĥęřę ŵäş äʼn ęřřőř đįşčőʼnʼnęčŧįʼnģ", - "title": "Đįşčőʼnʼnęčŧ ƒřőm čľőūđ şŧäčĸ" - }, - "get-started": { - "body": "Ŧĥę mįģřäŧįőʼn přőčęşş mūşŧ þę şŧäřŧęđ ƒřőm yőūř şęľƒ-mäʼnäģęđ Ğřäƒäʼnä įʼnşŧäʼnčę.", - "configure-pdc-link": "Cőʼnƒįģūřę PĐC ƒőř ŧĥįş şŧäčĸ", - "link-title": "Ŀęäřʼn mőřę äþőūŧ Přįväŧę Đäŧä Ŝőūřčę Cőʼnʼnęčŧ", - "step-1": "Ŀőģ įʼn ŧő yőūř şęľƒ-mäʼnäģęđ įʼnşŧäʼnčę äʼnđ ʼnävįģäŧę ŧő Åđmįʼnįşŧřäŧįőʼn, Ğęʼnęřäľ, Mįģřäŧę ŧő Ğřäƒäʼnä Cľőūđ.", - "step-2": "Ŝęľęčŧ \"Mįģřäŧę ŧĥįş įʼnşŧäʼnčę ŧő Cľőūđ\".", - "step-3": "Ÿőū'ľľ þę přőmpŧęđ ƒőř ä mįģřäŧįőʼn ŧőĸęʼn. Ğęʼnęřäŧę őʼnę ƒřőm ŧĥįş şčřęęʼn.", - "step-4": "Ĩʼn yőūř şęľƒ-mäʼnäģęđ įʼnşŧäʼnčę, şęľęčŧ \"Ůpľőäđ ęvęřyŧĥįʼnģ\" ŧő ūpľőäđ đäŧä şőūřčęş äʼnđ đäşĥþőäřđş ŧő ŧĥįş čľőūđ şŧäčĸ.", - "step-5": "Ĩƒ şőmę őƒ yőūř đäŧä şőūřčęş ŵįľľ ʼnőŧ ŵőřĸ ővęř ŧĥę pūþľįč įʼnŧęřʼnęŧ, yőū’ľľ ʼnęęđ ŧő įʼnşŧäľľ Přįväŧę Đäŧä Ŝőūřčę Cőʼnʼnęčŧ įʼn yőūř şęľƒ-mäʼnäģęđ ęʼnvįřőʼnmęʼnŧ.", - "title": "Pęřƒőřmįʼnģ ä mįģřäŧįőʼn" - }, - "is-it-secure": { - "body": "Ğřäƒäʼnä Ŀäþş įş čőmmįŧŧęđ ŧő mäįʼnŧäįʼnįʼnģ ŧĥę ĥįģĥęşŧ şŧäʼnđäřđş őƒ đäŧä přįväčy äʼnđ şęčūřįŧy. ßy įmpľęmęʼnŧįʼnģ įʼnđūşŧřy-şŧäʼnđäřđ şęčūřįŧy ŧęčĥʼnőľőģįęş äʼnđ přőčęđūřęş, ŵę ĥęľp přőŧęčŧ őūř čūşŧőmęřş' đäŧä ƒřőm ūʼnäūŧĥőřįžęđ äččęşş, ūşę, őř đįşčľőşūřę.", - "link-title": "Ğřäƒäʼnä Ŀäþş Ŧřūşŧ Cęʼnŧęř", - "title": "Ĩş įŧ şęčūřę?" - }, - "migrate-to-this-stack": { - "body": "Ÿőū čäʼn mįģřäŧę şőmę řęşőūřčęş ƒřőm yőūř şęľƒ-mäʼnäģęđ Ğřäƒäʼnä įʼnşŧäľľäŧįőʼn ŧő ŧĥįş čľőūđ şŧäčĸ. Ŧő đő ŧĥįş şęčūřęľy, yőū'ľľ ʼnęęđ ŧő ģęʼnęřäŧę ä mįģřäŧįőʼn ŧőĸęʼn. Ÿőūř şęľƒ-mäʼnäģęđ įʼnşŧäʼnčę ŵįľľ ūşę ŧĥę ŧőĸęʼn ŧő äūŧĥęʼnŧįčäŧę ŵįŧĥ ŧĥįş čľőūđ şŧäčĸ.", - "link-title": "Vįęŵ ŧĥę ƒūľľ mįģřäŧįőʼn ģūįđę", - "title": "Ŀęŧ ūş ĥęľp yőū mįģřäŧę ŧő ŧĥįş şŧäčĸ" - }, - "migrated-counts": { - "alert_rule_groups": "äľęřŧ řūľę ģřőūpş", - "alert_rules": "äľęřŧ řūľęş", - "contact_points": "čőʼnŧäčŧ pőįʼnŧş", - "dashboards": "đäşĥþőäřđş", - "datasources": "đäŧä şőūřčęş", - "folders": "ƒőľđęřş", - "library_elements": "ľįþřäřy ęľęmęʼnŧş", - "mute_timings": "mūŧę ŧįmįʼnģş", - "notification_policies": "ʼnőŧįƒįčäŧįőʼn pőľįčįęş", - "notification_templates": "ʼnőŧįƒįčäŧįőʼn ŧęmpľäŧęş", - "plugins": "pľūģįʼnş" - }, - "migration-token": { - "delete-button": "Đęľęŧę ŧőĸęʼn", - "delete-modal-body": "Ĩƒ yőū'vę äľřęäđy ūşęđ ŧĥįş ŧőĸęʼn ŵįŧĥ ä şęľƒ-mäʼnäģęđ įʼnşŧäľľäŧįőʼn, ŧĥäŧ įʼnşŧäľľäŧįőʼn ŵįľľ ʼnő ľőʼnģęř þę äþľę ŧő ūpľőäđ čőʼnŧęʼnŧ.", - "delete-modal-cancel": "Cäʼnčęľ", - "delete-modal-confirm": "Đęľęŧę", - "delete-modal-deleting": "Đęľęŧįʼnģ...", - "delete-modal-title": "Đęľęŧę mįģřäŧįőʼn ŧőĸęʼn", - "error-body": "Ůʼnäþľę ŧő ģęʼnęřäŧę ä mįģřäŧįőʼn ŧőĸęʼn. Pľęäşę ŧřy äģäįʼn ľäŧęř.", - "error-title": "Ŝőmęŧĥįʼnģ ŵęʼnŧ ŵřőʼnģ", - "generate-button": "Ğęʼnęřäŧę ä mįģřäŧįőʼn ŧőĸęʼn", - "generate-button-loading": "Ğęʼnęřäŧįʼnģ ä mįģřäŧįőʼn ŧőĸęʼn...", - "modal-close": "Cľőşę", - "modal-copy-and-close": "Cőpy ŧő čľįpþőäřđ äʼnđ čľőşę", - "modal-copy-button": "Cőpy ŧő čľįpþőäřđ", - "modal-field-description": "Cőpy ŧĥę ŧőĸęʼn ʼnőŵ äş yőū ŵįľľ ʼnőŧ þę äþľę ŧő şęę įŧ äģäįʼn. Ŀőşįʼnģ ä ŧőĸęʼn řęqūįřęş čřęäŧįʼnģ ä ʼnęŵ őʼnę.", - "modal-field-label": "Ŧőĸęʼn", - "modal-title": "Mįģřäŧįőʼn ŧőĸęʼn čřęäŧęđ", - "status": "Cūřřęʼnŧ şŧäŧūş: <2>" - }, - "onprem": { - "cancel-snapshot-error-title": "Ēřřőř čäʼnčęľľįʼnģ čřęäŧįʼnģ şʼnäpşĥőŧ", - "create-snapshot-error-title": "Ēřřőř čřęäŧįʼnģ şʼnäpşĥőŧ", - "disconnect-error-title": "Ēřřőř đįşčőʼnʼnęčŧįʼnģ", - "error-see-server-logs": "Ŝęę ŧĥę Ğřäƒäʼnä şęřvęř ľőģş ƒőř mőřę đęŧäįľş", - "get-session-error-title": "Ēřřőř ľőäđįʼnģ mįģřäŧįőʼn čőʼnƒįģūřäŧįőʼn", - "get-snapshot-error-title": "Ēřřőř ľőäđįʼnģ şʼnäpşĥőŧ", - "migration-finished-with-caveat-title": "Ŗęşőūřčę mįģřäŧįőʼn čőmpľęŧę", - "migration-finished-with-errors-body": "Ŧĥę mįģřäŧįőʼn ĥäş čőmpľęŧęđ, þūŧ şőmę įŧęmş čőūľđ ʼnőŧ þę mįģřäŧęđ ŧő ŧĥę čľőūđ şŧäčĸ. Cĥęčĸ ŧĥę ƒäįľęđ řęşőūřčęş ƒőř mőřę đęŧäįľş", - "migration-finished-with-warnings-body": "Ŧĥę mįģřäŧįőʼn ĥäş čőmpľęŧęđ ŵįŧĥ şőmę ŵäřʼnįʼnģş. Cĥęčĸ įʼnđįvįđūäľ řęşőūřčęş ƒőř mőřę đęŧäįľş", - "snapshot-error-status-body": "Ŧĥęřę ŵäş äʼn ęřřőř čřęäŧįʼnģ ŧĥę şʼnäpşĥőŧ őř şŧäřŧįʼnģ ŧĥę mįģřäŧįőʼn přőčęşş. Ŝęę ŧĥę Ğřäƒäʼnä şęřvęř ľőģş ƒőř mőřę đęŧäįľş", - "snapshot-error-status-title": "Ēřřőř mįģřäŧįʼnģ řęşőūřčęş", - "success-message": "Ŝūččęşşƒūľľy mįģřäŧęđ {{successCount}} {{types, list}} ŧő yőūř Ğřäƒäʼnä Cľőūđ įʼnşŧäʼnčę.", - "success-message-generic": "Ŝūččęşşƒūľľy mįģřäŧęđ {{successCount}} řęşőūřčęş ŧő yőūř Ğřäƒäʼnä Cľőūđ įʼnşŧäʼnčę.", - "success-title": "Mįģřäŧįőʼn čőmpľęŧęđ!", - "upload-snapshot-error-title": "Ēřřőř ūpľőäđįʼnģ şʼnäpşĥőŧ" - }, - "pdc": { - "body": "Ēχpőşįʼnģ yőūř đäŧä şőūřčęş ŧő ŧĥę įʼnŧęřʼnęŧ čäʼn řäįşę şęčūřįŧy čőʼnčęřʼnş. Přįväŧę đäŧä şőūřčę čőʼnʼnęčŧ (PĐC) äľľőŵş Ğřäƒäʼnä Cľőūđ ŧő äččęşş yőūř ęχįşŧįʼnģ đäŧä şőūřčęş ővęř ä şęčūřę ʼnęŧŵőřĸ ŧūʼnʼnęľ.", - "link-title": "Ŀęäřʼn äþőūŧ PĐC", - "title": "Ńőŧ äľľ my đäŧä şőūřčęş äřę őʼn ŧĥę pūþľįč įʼnŧęřʼnęŧ" - }, - "pricing": { - "body": "Ğřäƒäʼnä Cľőūđ ĥäş ä ģęʼnęřőūş ƒřęę pľäʼn äʼnđ ä 14 đäy ūʼnľįmįŧęđ ūşäģę ŧřįäľ. Ńŧęř yőūř ŧřįäľ ęχpįřęş, yőū'ľľ þę þįľľęđ þäşęđ őʼn ūşäģę ővęř ŧĥę ƒřęę pľäʼn ľįmįŧş.", - "link-title": "Ğřäƒäʼnä Cľőūđ přįčįʼnģ", - "title": "Ħőŵ mūčĥ đőęş įŧ čőşŧ?" - }, - "public-preview": { - "button-text": "Ğįvę ƒęęđþäčĸ", - "message": "<0>Vįşįŧ őūř đőčş ŧő ľęäřʼn mőřę äþőūŧ ŧĥįş ƒęäŧūřę!", - "message-cloud": "Ÿőūř şęľƒ-mäʼnäģęđ įʼnşŧäʼnčę őƒ Ğřäƒäʼnä řęqūįřęş vęřşįőʼn 11.5+, őř 11.2+ ŵįŧĥ ŧĥę őʼnPřęmŦőCľőūđMįģřäŧįőʼnş ƒęäŧūřę ƒľäģ ęʼnäþľęđ.", - "title": "Mįģřäŧę ŧő Ğřäƒäʼnä Cľőūđ įş įʼn pūþľįč přęvįęŵ" - }, - "resource-details": { - "dismiss-button": "ØĶ", - "error-messages": { - "dashboard-already-managed": "Đäşĥþőäřđ įş äľřęäđy přővįşįőʼnęđ äʼnđ mäʼnäģęđ þy Ğřäƒäʼnä įʼn ŧĥę čľőūđ įʼnşŧäʼnčę. Ŵę řęčőmmęʼnđ ūşįʼnģ ŧĥę přővįşįőʼnęđ đäşĥþőäřđ ģőįʼnģ ƒőřŵäřđ. Ĩƒ yőū şŧįľľ ŵįşĥ ŧő čőpy ŧĥę đäşĥþőäřđ ŧő ŧĥę čľőūđ įʼnşŧäʼnčę, ŧĥęʼn čĥäʼnģę ŧĥę đäşĥþőäřđ ĨĐ įʼn ŧĥę đäşĥþőäřđ ĴŜØŃ, şävę ä ʼnęŵ şʼnäpşĥőŧ äʼnđ ūpľőäđ äģäįʼn.", - "datasource-already-managed": "Đäŧä şőūřčę įş äľřęäđy přővįşįőʼnęđ äʼnđ mäʼnäģęđ þy Ğřäƒäʼnä įʼn ŧĥę čľőūđ įʼnşŧäʼnčę. Ĩƒ ŧĥįş įş ä đįƒƒęřęʼnŧ řęşőūřčę, şęŧ äʼnőŧĥęř ŮĨĐ äʼnđ ŧřy äģäįʼn.", - "datasource-invalid-url": "Ŧĥęřę įş ä đäŧä şőūřčę ŵĥįčĥ ĥäş äʼn įʼnväľįđ ŮŖĿ. Přővįđę ä väľįđ ŮŖĿ äʼnđ ŧřy äģäįʼn.", - "datasource-name-conflict": "Ŧĥęřę įş ä đäŧä şőūřčę ŵįŧĥ ŧĥę şämę ʼnämę įʼn ŧĥę ŧäřģęŧ įʼnşŧäʼnčę. Ŗęʼnämę őʼnę őƒ ŧĥęm äʼnđ ŧřy äģäįʼn.", - "folder-name-conflict": "Ŧĥęřę įş ä ƒőľđęř ŵįŧĥ ŧĥę şämę ʼnämę įʼn ŧĥę ŧäřģęŧ įʼnşŧäʼnčę. Ŗęʼnämę őʼnę őƒ ŧĥęm äʼnđ ŧřy äģäįʼn.", - "generic-error": "Ŧĥęřę ĥäş þęęʼn äʼn ęřřőř ŵĥįľę mįģřäŧįʼnģ. Pľęäşę čĥęčĸ ŧĥę čľőūđ mįģřäŧįőʼn ľőģş ƒőř mőřę įʼnƒőřmäŧįőʼn.", - "internal-service-error": "Ŧĥęřę ĥäş þęęʼn äʼn ęřřőř ŵĥįľę mįģřäŧįʼnģ. Pľęäşę čĥęčĸ ŧĥę Ğřäƒäʼnä şęřvęř ľőģş ƒőř mőřę đęŧäįľş.", - "library-element-name-conflict": "Ŧĥęřę įş ä ľįþřäřy ęľęmęʼnŧ ŵįŧĥ ŧĥę şämę ʼnämę įʼn ŧĥę ŧäřģęŧ įʼnşŧäʼnčę. Ŗęʼnämę őʼnę őƒ ŧĥęm äʼnđ ŧřy äģäįʼn.", - "resource-conflict": "Ŧĥęřę įş ä řęşőūřčę čőʼnƒľįčŧ ŵįŧĥ ŧĥę ŧäřģęŧ įʼnşŧäʼnčę. Pľęäşę čĥęčĸ ŧĥę Ğřäƒäʼnä şęřvęř ľőģş ƒőř mőřę đęŧäįľş.", - "unexpected-error": "Ŧĥęřę ĥäş þęęʼn äʼn ęřřőř ŵĥįľę mįģřäŧįʼnģ. Pľęäşę čĥęčĸ ŧĥę Ğřäƒäʼnä şęřvęř ľőģş ƒőř mőřę đęŧäįľş.", - "unsupported-data-type": "Mįģřäŧįőʼn őƒ ŧĥįş đäŧä ŧypę įş ʼnőŧ čūřřęʼnŧľy şūppőřŧęđ." - }, - "error-title": "Ůʼnäþľę ŧő mįģřäŧę ŧĥįş řęşőūřčę:", - "generic-title": "Ŗęşőūřčę mįģřäŧįőʼn đęŧäįľş:", - "missing-message": "Ńő męşşäģę přővįđęđ.", - "resource-summary": "{{refId}} ({{typeName}})", - "title": "Mįģřäŧįőʼn řęşőūřčę đęŧäįľş", - "warning-title": "Ŗęşőūřčę mįģřäŧęđ ŵįŧĥ ä ŵäřʼnįʼnģ:" - }, - "resource-status": { - "error-details-button": "Đęŧäįľş", - "failed": "Ēřřőř", - "migrated": "Ůpľőäđęđ ŧő čľőūđ", - "migrating": "Ůpľőäđįʼnģ...", - "not-migrated": "Ńőŧ yęŧ ūpľőäđęđ", - "unknown": "Ůʼnĸʼnőŵʼn", - "warning": "Ůpľőäđęđ ŵįŧĥ ŵäřʼnįʼnģ", - "warning-details-button": "Đęŧäįľş" - }, - "resource-table": { - "dashboard-load-error": "Ůʼnäþľę ŧő ľőäđ đäşĥþőäřđ", - "error-library-element-sub": "Ŀįþřäřy Ēľęmęʼnŧ {ūįđ}", - "error-library-element-title": "Ůʼnäþľę ŧő ľőäđ ľįþřäřy ęľęmęʼnŧ", - "unknown-datasource-title": "Đäŧä şőūřčę {{datasourceUID}}", - "unknown-datasource-type": "Ůʼnĸʼnőŵʼn đäŧä şőūřčę" - }, - "resource-type": { - "alert_rule": "Åľęřŧ Ŗūľę", - "alert_rule_group": "Åľęřŧ Ŗūľę Ğřőūp", - "contact_point": "Cőʼnŧäčŧ Pőįʼnŧ", - "dashboard": "Đäşĥþőäřđ", - "datasource": "Đäŧä şőūřčę", - "folder": "Főľđęř", - "library_element": "Ŀįþřäřy Ēľęmęʼnŧ", - "mute_timing": "Mūŧę Ŧįmįʼnģ", - "notification_policy": "Ńőŧįƒįčäŧįőʼn Pőľįčy", - "notification_template": "Ńőŧįƒįčäŧįőʼn Ŧęmpľäŧę", - "plugin": "Pľūģįʼn", - "unknown": "Ůʼnĸʼnőŵʼn" - }, - "summary": { - "cancel-snapshot": "Cäʼnčęľ şʼnäpşĥőŧ", - "disconnect": "Đįşčőʼnʼnęčŧ", - "errored-resource-count": "Ēřřőřş", - "page-loading": "Ŀőäđįʼnģ...", - "rebuild-snapshot": "Ŗęþūįľđ şʼnäpşĥőŧ", - "snapshot-date": "Ŝʼnäpşĥőŧ ŧįmęşŧämp", - "snapshot-not-created": "Ńőŧ yęŧ čřęäŧęđ", - "start-migration": "ßūįľđ şʼnäpşĥőŧ", - "successful-resource-count": "Ŝūččęşşƒūľľy mįģřäŧęđ", - "target-stack-title": "Ůpľőäđįʼnģ ŧő", - "total-resource-count": "Ŧőŧäľ řęşőūřčęş", - "upload-migration": "Ůpľőäđ şʼnäpşĥőŧ" - }, - "support-types-disclosure": { - "text": "Đäşĥþőäřđş, Főľđęřş, äʼnđ þūįľŧ-įʼn čőřę đäŧä şőūřčęş äřę mįģřäŧęđ ŧő yőūř Ğřäƒäʼnä Cľőūđ şŧäčĸ. <2>Ŀęäřʼn äþőūŧ mįģřäŧįʼnģ őŧĥęř şęŧŧįʼnģş." - }, - "token-status": { - "active": "Ŧőĸęʼn čřęäŧęđ äʼnđ äčŧįvę", - "no-active": "Ńő äčŧįvę ŧőĸęʼn", - "unknown": "Ůʼnĸʼnőŵʼn", - "unknown-error": "Ēřřőř řęŧřįęvįʼnģ ŧőĸęʼn" - }, - "what-is-cloud": { - "body": "Ğřäƒäʼnä čľőūđ įş ä ƒūľľy mäʼnäģęđ čľőūđ-ĥőşŧęđ őþşęřväþįľįŧy pľäŧƒőřm įđęäľ ƒőř čľőūđ ʼnäŧįvę ęʼnvįřőʼnmęʼnŧş. Ĩŧ'ş ęvęřyŧĥįʼnģ yőū ľővę äþőūŧ Ğřäƒäʼnä ŵįŧĥőūŧ ŧĥę ővęřĥęäđ őƒ mäįʼnŧäįʼnįʼnģ, ūpģřäđįʼnģ, äʼnđ şūppőřŧįʼnģ äʼn įʼnşŧäľľäŧįőʼn.", - "link-title": "Ŀęäřʼn äþőūŧ čľőūđ ƒęäŧūřęş", - "title": "Ŵĥäŧ įş Ğřäƒäʼnä Cľőūđ?" - }, - "why-host": { - "body": "Ĩʼn äđđįŧįőʼn ŧő ŧĥę čőʼnvęʼnįęʼnčę őƒ mäʼnäģęđ ĥőşŧįʼnģ, Ğřäƒäʼnä Cľőūđ įʼnčľūđęş mäʼny čľőūđ-ęχčľūşįvę ƒęäŧūřęş ľįĸę ŜĿØş, įʼnčįđęʼnŧ mäʼnäģęmęʼnŧ, mäčĥįʼnę ľęäřʼnįʼnģ, äʼnđ pőŵęřƒūľ őþşęřväþįľįŧy įʼnŧęģřäŧįőʼnş.", - "link-title": "Mőřę qūęşŧįőʼnş? Ŧäľĸ ŧő äʼn ęχpęřŧ", - "title": "Ŵĥy ĥőşŧ ŵįŧĥ Ğřäƒäʼnä?" - } - }, - "multicombobox": { - "all": { - "title": "Åľľ", - "title-filtered": "Åľľ (ƒįľŧęřęđ)" - }, - "clear": { - "title": "Cľęäř äľľ" - } - }, - "nav": { - "add-new-connections": { - "title": "Åđđ ʼnęŵ čőʼnʼnęčŧįőʼn" - }, - "admin": { - "subtitle": "Mäʼnäģę şęřvęř-ŵįđę şęŧŧįʼnģş äʼnđ äččęşş ŧő řęşőūřčęş şūčĥ äş őřģäʼnįžäŧįőʼnş, ūşęřş, äʼnđ ľįčęʼnşęş", - "title": "Ŝęřvęř äđmįʼn" - }, - "alert-list-legacy": { - "title": "Åľęřŧ řūľęş" - }, - "alerting": { - "subtitle": "Ŀęäřʼn äþőūŧ přőþľęmş įʼn yőūř şyşŧęmş mőmęʼnŧş äƒŧęř ŧĥęy őččūř", - "title": "Åľęřŧįʼnģ" - }, - "alerting-admin": { - "subtitle": "Mäʼnäģę Åľęřŧmäʼnäģęř čőʼnƒįģūřäŧįőʼnş äʼnđ ęʼnäþľę řęčęįvįʼnģ Ğřäƒäʼnä-mäʼnäģęđ äľęřŧş", - "title": "Ŝęŧŧįʼnģş" - }, - "alerting-am-routes": { - "subtitle": "Đęŧęřmįʼnę ĥőŵ äľęřŧş äřę řőūŧęđ ŧő čőʼnŧäčŧ pőįʼnŧş", - "title": "Ńőŧįƒįčäŧįőʼn pőľįčįęş" - }, - "alerting-channels": { - "title": "Ńőŧįƒįčäŧįőʼn čĥäʼnʼnęľş" - }, - "alerting-groups": { - "subtitle": "Ŝęę ģřőūpęđ äľęřŧş ŵįŧĥ äčŧįvę ʼnőŧįƒįčäŧįőʼnş", - "title": "Åčŧįvę ʼnőŧįƒįčäŧįőʼnş" - }, - "alerting-home": { - "title": "Ħőmę" - }, - "alerting-legacy": { - "title": "Åľęřŧįʼnģ (ľęģäčy)" - }, - "alerting-list": { - "subtitle": "Ŗūľęş ŧĥäŧ đęŧęřmįʼnę ŵĥęŧĥęř äʼn äľęřŧ ŵįľľ ƒįřę", - "title": "Åľęřŧ řūľęş" - }, - "alerting-receivers": { - "subtitle": "Cĥőőşę ĥőŵ ŧő ʼnőŧįƒy yőūř čőʼnŧäčŧ pőįʼnŧş ŵĥęʼn äʼn äľęřŧ įʼnşŧäʼnčę ƒįřęş", - "title": "Cőʼnŧäčŧ pőįʼnŧş" - }, - "alerting-silences": { - "subtitle": "Ŝŧőp ʼnőŧįƒįčäŧįőʼnş ƒřőm őʼnę őř mőřę äľęřŧįʼnģ řūľęş", - "title": "Ŝįľęʼnčęş" - }, - "alerting-upgrade": { - "subtitle": "Ůpģřäđę yőūř ęχįşŧįʼnģ ľęģäčy äľęřŧş äʼnđ ʼnőŧįƒįčäŧįőʼn čĥäʼnʼnęľş ŧő ŧĥę ʼnęŵ Ğřäƒäʼnä Åľęřŧįʼnģ", - "title": "Åľęřŧįʼnģ ūpģřäđę" - }, - "alerts-and-incidents": { - "subtitle": "Åľęřŧįʼnģ äʼnđ įʼnčįđęʼnŧ mäʼnäģęmęʼnŧ äppş", - "title": "Åľęřŧş & ĨŖM" - }, - "api-keys": { - "subtitle": "Mäʼnäģę äʼnđ čřęäŧę ÅPĨ ĸęyş ŧĥäŧ äřę ūşęđ ŧő įʼnŧęřäčŧ ŵįŧĥ Ğřäƒäʼnä ĦŦŦP ÅPĨş", - "title": "ÅPĨ ĸęyş" - }, - "application": { - "title": "Åppľįčäŧįőʼn" - }, - "apps": { - "subtitle": "Åpp pľūģįʼnş ŧĥäŧ ęχŧęʼnđ ŧĥę Ğřäƒäʼnä ęχpęřįęʼnčę", - "title": "Mőřę äppş" - }, - "authentication": { - "title": "Åūŧĥęʼnŧįčäŧįőʼn" - }, - "bookmarks": { - "title": "ßőőĸmäřĸş" - }, - "bookmarks-empty": { - "title": "ßőőĸmäřĸ päģęş ƒőř ŧĥęm ŧő äppęäř ĥęřę" - }, - "collector": { - "title": "Cőľľęčŧőř" - }, - "config": { - "title": "Åđmįʼnįşŧřäŧįőʼn" - }, - "config-access": { - "subtitle": "Cőʼnƒįģūřę äččęşş ƒőř įʼnđįvįđūäľ ūşęřş, ŧęämş, äʼnđ şęřvįčę äččőūʼnŧş", - "title": "Ůşęřş äʼnđ äččęşş" - }, - "config-general": { - "subtitle": "Mäʼnäģę đęƒäūľŧ přęƒęřęʼnčęş äʼnđ şęŧŧįʼnģş äčřőşş Ğřäƒäʼnä", - "title": "Ğęʼnęřäľ" - }, - "config-plugins": { - "subtitle": "Ĩʼnşŧäľľ pľūģįʼnş äʼnđ đęƒįʼnę ŧĥę řęľäŧįőʼnşĥįpş þęŧŵęęʼn đäŧä", - "title": "Pľūģįʼnş äʼnđ đäŧä" - }, - "connect-data": { - "title": "Cőʼnʼnęčŧ đäŧä" - }, - "connections": { - "subtitle": "ßřőŵşę äʼnđ čřęäŧę ʼnęŵ čőʼnʼnęčŧįőʼnş", - "title": "Cőʼnʼnęčŧįőʼnş" - }, - "correlations": { - "subtitle": "Åđđ äʼnđ čőʼnƒįģūřę čőřřęľäŧįőʼnş", - "title": "Cőřřęľäŧįőʼnş" - }, - "create": { - "title": "Cřęäŧę" - }, - "create-alert": { - "title": "Ńęŵ äľęřŧ řūľę" - }, - "create-dashboard": { - "title": "Đäşĥþőäřđ" - }, - "create-folder": { - "title": "Főľđęř" - }, - "create-import": { - "title": "Ĩmpőřŧ đäşĥþőäřđ" - }, - "dashboards": { - "subtitle": "Cřęäŧę äʼnđ mäʼnäģę đäşĥþőäřđş ŧő vįşūäľįžę yőūř đäŧä", - "title": "Đäşĥþőäřđş" - }, - "data-sources": { - "subtitle": "Vįęŵ äʼnđ mäʼnäģę yőūř čőʼnʼnęčŧęđ đäŧä şőūřčę čőʼnʼnęčŧįőʼnş", - "title": "Đäŧä şőūřčęş" - }, - "databases": { - "title": "Đäŧäþäşęş" - }, - "datasources": { - "subtitle": "Åđđ äʼnđ čőʼnƒįģūřę đäŧä şőūřčęş", - "title": "Đäŧä şőūřčęş" - }, - "detect": { - "title": "Đęŧęčŧ" - }, - "drilldown": { - "title": "Đřįľľđőŵʼn" - }, - "explore": { - "title": "Ēχpľőřę" - }, - "frontend": { - "subtitle": "Ğäįʼn řęäľ ūşęř mőʼnįŧőřįʼnģ įʼnşįģĥŧş", - "title": "Fřőʼnŧęʼnđ" - }, - "frontend-app": { - "title": "Fřőʼnŧęʼnđ" - }, - "global-orgs": { - "subtitle": "Ĩşőľäŧęđ įʼnşŧäʼnčęş őƒ Ğřäƒäʼnä řūʼnʼnįʼnģ őʼn ŧĥę şämę şęřvęř", - "title": "Øřģäʼnįžäŧįőʼnş" - }, - "global-users": { - "subtitle": "Mäʼnäģę ūşęřş įʼn Ğřäƒäʼnä", - "title": "Ůşęřş" - }, - "grafana-quaderno": { - "title": "Ğřäƒäʼnä Qūäđęřʼnő" - }, - "groupsync": { - "subtitle": "Mäʼnäģę mäppįʼnģş őƒ Ĩđęʼnŧįŧy Přővįđęř ģřőūpş ŧő Ğřäƒäʼnä Ŗőľęş" - }, - "help": { - "title": "Ħęľp" - }, - "help/community": "Cőmmūʼnįŧy", - "help/documentation": "Đőčūmęʼnŧäŧįőʼn", - "help/keyboard-shortcuts": "Ķęyþőäřđ şĥőřŧčūŧş", - "help/support": "Ŝūppőřŧ", - "history-container": { - "drawer-tittle": "Ħįşŧőřy" - }, - "history-wrapper": { - "collapse": "Cőľľäpşę", - "expand": "Ēχpäʼnđ", - "icon-selected": "Ŝęľęčŧęđ Ēʼnŧřy", - "icon-unselected": "Ńőřmäľ Ēʼnŧřy", - "show-more": "Ŝĥőŵ mőřę", - "today": "Ŧőđäy", - "yesterday": "Ÿęşŧęřđäy" - }, - "home": { - "title": "Ħőmę" - }, - "incidents": { - "title": "Ĩʼnčįđęʼnŧ" - }, - "infrastructure": { - "subtitle": "Ůʼnđęřşŧäʼnđ yőūř įʼnƒřäşŧřūčŧūřę'ş ĥęäľŧĥ", - "title": "Ĩʼnƒřäşŧřūčŧūřę" - }, - "integrations": { - "title": "Ĩʼnŧęģřäŧįőʼnş" - }, - "k6": { - "title": "Pęřƒőřmäʼnčę" - }, - "kubernetes": { - "title": "Ķūþęřʼnęŧęş" - }, - "library-panels": { - "subtitle": "Ŗęūşäþľę päʼnęľş ŧĥäŧ čäʼn þę äđđęđ ŧő mūľŧįpľę đäşĥþőäřđş", - "title": "Ŀįþřäřy päʼnęľş" - }, - "machine-learning": { - "title": "Mäčĥįʼnę ľęäřʼnįʼnģ" - }, - "manage-folder": { - "subtitle": "Mäʼnäģę ƒőľđęř đäşĥþőäřđş äʼnđ pęřmįşşįőʼnş" - }, - "migrate-to-cloud": { - "subtitle": "Cőpy čőʼnƒįģūřäŧįőʼn ƒřőm yőūř şęľƒ-mäʼnäģęđ įʼnşŧäľľäŧįőʼn ŧő ä čľőūđ şŧäčĸ", - "title": "Mįģřäŧę ŧő Ğřäƒäʼnä Cľőūđ" - }, - "monitoring": { - "subtitle": "Øūŧ-őƒ-ŧĥę-þőχ őþşęřväþįľįŧy şőľūŧįőʼnş", - "title": "Øþşęřväþįľįŧy" - }, - "new": { - "title": "Ńęŵ" - }, - "new-dashboard": { - "title": "Ńęŵ đäşĥþőäřđ" - }, - "new-folder": { - "title": "Ńęŵ ƒőľđęř" - }, - "oncall": { - "title": "ØʼnCäľľ" - }, - "org-settings": { - "subtitle": "Mäʼnäģę přęƒęřęʼnčęş äčřőşş äʼn őřģäʼnįžäŧįőʼn", - "title": "Đęƒäūľŧ přęƒęřęʼnčęş" - }, - "playlists": { - "subtitle": "Ğřőūpş őƒ đäşĥþőäřđş ŧĥäŧ äřę đįşpľäyęđ įʼn ä şęqūęʼnčę", - "title": "Pľäyľįşŧş" - }, - "plugins": { - "subtitle": "Ēχŧęʼnđ ŧĥę Ğřäƒäʼnä ęχpęřįęʼnčę ŵįŧĥ pľūģįʼnş", - "title": "Pľūģįʼnş" - }, - "private-data-source-connections": { - "subtitle": "Qūęřy đäŧä ŧĥäŧ ľįvęş ŵįŧĥįʼn ä şęčūřęđ ʼnęŧŵőřĸ ŵįŧĥőūŧ őpęʼnįʼnģ ŧĥę ʼnęŧŵőřĸ ŧő įʼnþőūʼnđ ŧř䃃įč ƒřőm Ğřäƒäʼnä Cľőūđ. Ŀęäřʼn mőřę įʼn őūř đőčş.", - "title": "Přįväŧę đäŧä şőūřčę čőʼnʼnęčŧ" - }, - "profile/notifications": { - "title": "Ńőŧįƒįčäŧįőʼn ĥįşŧőřy" - }, - "profile/password": { - "title": "Cĥäʼnģę päşşŵőřđ" - }, - "profile/settings": { - "title": "Přőƒįľę" - }, - "profiles": { - "title": "Přőƒįľęş" - }, - "public": { - "title": "Pūþľįč đäşĥþőäřđş" - }, - "recently-deleted": { - "subtitle": "Åʼny įŧęmş ľįşŧęđ ĥęřę ƒőř mőřę ŧĥäʼn 30 đäyş ŵįľľ þę äūŧőmäŧįčäľľy đęľęŧęđ.", - "title": "Ŗęčęʼnŧľy đęľęŧęđ" - }, - "recorded-queries": { - "title": "Ŗęčőřđęđ qūęřįęş" - }, - "reporting": { - "title": "Ŗępőřŧįʼnģ" - }, - "scenes": { - "title": "Ŝčęʼnęş" - }, - "search": { - "placeholderCommandPalette": "Ŝęäřčĥ őř ĵūmp ŧő..." - }, - "search-dashboards": { - "title": "Ŝęäřčĥ đäşĥþőäřđş" - }, - "server-settings": { - "subtitle": "Vįęŵ ŧĥę şęŧŧįʼnģş đęƒįʼnęđ įʼn yőūř Ğřäƒäʼnä čőʼnƒįģ", - "title": "Ŝęŧŧįʼnģş" - }, - "service-accounts": { - "subtitle": "Ůşę şęřvįčę äččőūʼnŧş ŧő řūʼn äūŧőmäŧęđ ŵőřĸľőäđş įʼn Ğřäƒäʼnä", - "title": "Ŝęřvįčę äččőūʼnŧş" - }, - "setup-guide": { - "title": "Ŝęŧūp ģūįđę" - }, - "shared-dashboard": { - "subtitle": "Mäʼnäģę yőūř őřģäʼnįžäŧįőʼn'ş ęχŧęřʼnäľľy şĥäřęđ đäşĥþőäřđş", - "title": "Ŝĥäřęđ đäşĥþőäřđş" - }, - "sign-out": { - "title": "Ŝįģʼn őūŧ" - }, - "slo": { - "title": "ŜĿØ" - }, - "snapshots": { - "subtitle": "Ĩʼnŧęřäčŧįvę, pūþľįčäľľy äväįľäþľę, pőįʼnŧ-įʼn-ŧįmę řępřęşęʼnŧäŧįőʼnş őƒ đäşĥþőäřđş äʼnđ päʼnęľş", - "title": "Ŝʼnäpşĥőŧş" - }, - "starred": { - "title": "Ŝŧäřřęđ" - }, - "starred-empty": { - "title": "Ÿőūř şŧäřřęđ đäşĥþőäřđş ŵįľľ äppęäř ĥęřę" - }, - "statistics-and-licensing": { - "title": "Ŝŧäŧįşŧįčş äʼnđ ľįčęʼnşįʼnģ" - }, - "storage": { - "subtitle": "Mäʼnäģę ƒįľę şŧőřäģę", - "title": "Ŝŧőřäģę" - }, - "support-bundles": { - "subtitle": "Đőŵʼnľőäđ şūppőřŧ þūʼnđľęş", - "title": "Ŝūppőřŧ þūʼnđľęş" - }, - "synthetics": { - "title": "Ŝyʼnŧĥęŧįčş" - }, - "teams": { - "subtitle": "Ğřőūpş őƒ ūşęřş ŧĥäŧ ĥävę čőmmőʼn đäşĥþőäřđ äʼnđ pęřmįşşįőʼn ʼnęęđş", - "title": "Ŧęämş" - }, - "testing-and-synthetics": { - "subtitle": "Øpŧįmįžę pęřƒőřmäʼnčę ŵįŧĥ ĸ6 äʼnđ Ŝyʼnŧĥęŧįč Mőʼnįŧőřįʼnģ įʼnşįģĥŧş", - "title": "Ŧęşŧįʼnģ & şyʼnŧĥęŧįčş" - }, - "upgrading": { - "title": "Ŝŧäŧş äʼnđ ľįčęʼnşę" - }, - "users": { - "subtitle": "Ĩʼnvįŧę äʼnđ äşşįģʼn řőľęş ŧő ūşęřş", - "title": "Ůşęřş" - } - }, - "navigation": { - "invite-user": { - "invite-button": "Ĩʼnvįŧę", - "invite-tooltip": "Ĩʼnvįŧę ʼnęŵ męmþęř" - }, - "item": { - "add-bookmark": "Åđđ ŧő ßőőĸmäřĸş", - "remove-bookmark": "Ŗęmővę ƒřőm ßőőĸmäřĸş" - }, - "kiosk": { - "tv-alert": "Přęşş ĒŜC ŧő ęχįŧ ĸįőşĸ mőđę" - }, - "megamenu": { - "close": "Cľőşę męʼnū", - "dock": "Đőčĸ męʼnū", - "list-label": "Ńävįģäŧįőʼn", - "open": "Øpęʼn męʼnū", - "undock": "Ůʼnđőčĸ męʼnū" - }, - "rss-button": "Ŀäŧęşŧ ƒřőm ŧĥę þľőģ" - }, - "news": { - "drawer": { - "close": "Cľőşę Đřäŵęř" - }, - "title": "Ŀäŧęşŧ ƒřőm ŧĥę þľőģ" - }, - "notifications": { - "empty-state": { - "description": "Ńőŧįƒįčäŧįőʼnş yőū ĥävę řęčęįvęđ ŵįľľ äppęäř ĥęřę", - "title": "Ÿőū'řę äľľ čäūģĥŧ ūp!" - }, - "starred-dashboard": "Đäşĥþőäřđ şŧäřřęđ", - "unstarred-dashboard": "Đäşĥþőäřđ ūʼnşŧäřřęđ" - }, - "oauth": { - "form": { - "server-discovery-action-button": "Ēʼnŧęř ØpęʼnĨĐ Cőʼnʼnęčŧ Đįşčővęřy ŮŖĿ", - "server-discovery-modal-close": "Cľőşę", - "server-discovery-modal-loading": "Ŀőäđįʼnģ...", - "server-discovery-modal-submit": "Ŝūþmįŧ" - }, - "login": { - "error": "Ŀőģįʼn přővįđęř đęʼnįęđ ľőģįʼn řęqūęşŧ" - } - }, - "panel": { - "header-menu": { - "copy": "Cőpy", - "create-library-panel": "Cřęäŧę ľįþřäřy päʼnęľ", - "duplicate": "Đūpľįčäŧę", - "edit": "Ēđįŧ", - "explore": "Ēχpľőřę", - "get-help": "Ğęŧ ĥęľp", - "hide-legend": "Ħįđę ľęģęʼnđ", - "inspect": "Ĩʼnşpęčŧ", - "inspect-data": "Đäŧä", - "inspect-json": "Päʼnęľ ĴŜØŃ", - "more": "Mőřę...", - "new-alert-rule": "Ńęŵ äľęřŧ řūľę", - "query": "Qūęřy", - "remove": "Ŗęmővę", - "replace-library-panel": "Ŗępľäčę ľįþřäřy päʼnęľ", - "share": "Ŝĥäřę", - "show-legend": "Ŝĥőŵ ľęģęʼnđ", - "unlink-library-panel": "Ůʼnľįʼnĸ ľįþřäřy päʼnęľ", - "view": "Vįęŵ" - } - }, - "panel-search": { - "no-matches": "Ńő mäŧčĥęş ƒőūʼnđ", - "unsupported-layout": "Ůʼnşūppőřŧęđ ľäyőūŧ" - }, - "panel-type-filter": { - "clear-button": "Cľęäř ŧypęş" - }, - "playlist-edit": { - "error-prefix": "Ēřřőř ľőäđįʼnģ pľäyľįşŧ:", - "form": { - "add-tag-label": "Åđđ þy ŧäģ", - "add-tag-placeholder": "Ŝęľęčŧ ä ŧäģ", - "add-title-label": "Åđđ þy ŧįŧľę", - "cancel": "Cäʼnčęľ", - "heading": "Åđđ đäşĥþőäřđş", - "interval-label": "Ĩʼnŧęřväľ", - "interval-placeholder": "5m", - "interval-required": "Ĩʼnŧęřväľ įş řęqūįřęđ", - "name-label": "Ńämę", - "name-placeholder": "Ńämę", - "name-required": "Ńämę įş řęqūįřęđ", - "save": "Ŝävę", - "table-delete": "Đęľęŧę pľäyľįşŧ įŧęm", - "table-drag": "Đřäģ äʼnđ đřőp ŧő řęőřđęř", - "table-empty": "Pľäyľįşŧ įş ęmpŧy. Åđđ đäşĥþőäřđş þęľőŵ.", - "table-heading": "Đäşĥþőäřđş" - }, - "sub-title": "Å pľäyľįşŧ řőŧäŧęş ŧĥřőūģĥ ä přę-şęľęčŧęđ ľįşŧ őƒ đäşĥþőäřđş. Å pľäyľįşŧ čäʼn þę ä ģřęäŧ ŵäy ŧő þūįľđ şįŧūäŧįőʼnäľ äŵäřęʼnęşş, őř ĵūşŧ şĥőŵ őƒƒ yőūř męŧřįčş ŧő yőūř ŧęäm őř vįşįŧőřş.", - "title": "Ēđįŧ pľäyľįşŧ" - }, - "playlist-page": { - "card": { - "delete": "Đęľęŧę pľäyľįşŧ", - "edit": "Ēđįŧ pľäyľįşŧ", - "start": "Ŝŧäřŧ pľäyľįşŧ", - "tooltip": "Ŝĥäřę pľäyľįşŧ" - }, - "create-button": { - "title": "Ńęŵ pľäyľįşŧ" - }, - "delete-modal": { - "body": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő đęľęŧę {{name}} pľäyľįşŧ?", - "confirm-text": "Đęľęŧę" - }, - "empty": { - "button": "Cřęäŧę pľäyľįşŧ", - "pro-tip": "Ÿőū čäʼn ūşę pľäyľįşŧş ŧő čyčľę đäşĥþőäřđş őʼn ŦVş ŵįŧĥőūŧ ūşęř čőʼnŧřőľ. <2>Ŀęäřʼn mőřę", - "title": "Ŧĥęřę äřę ʼnő pľäyľįşŧş čřęäŧęđ yęŧ" - } - }, - "playlists": { - "empty-state": { - "message": "Ńő pľäyľįşŧş ƒőūʼnđ" - } - }, - "plugins": { - "catalog": { - "no-updates-available": "Ńő ūpđäŧęş äväįľäþľę", - "update-all": { - "all-plugins-updated": "Åľľ pľūģįʼnş ūpđäŧęđ!", - "available-header": "Åväįľäþľę", - "button": "Ůpđäŧę äľľ ({{length}})", - "cloud-update-message": "* Ĩŧ mäy ŧäĸę ä ƒęŵ mįʼnūŧęş ƒőř ŧĥę pľūģįʼnş ŧő þę äväįľäþľę ƒőř ūşäģę.", - "error": "Ēřřőř ūpđäŧįʼnģ pľūģįʼn:", - "error-status-text": "ƒäįľęđ - şęę ęřřőř męşşäģęş", - "header": "Ŧĥę ƒőľľőŵįʼnģ pľūģįʼnş ĥävę ūpđäŧę äväįľäþľę", - "installed-header": "Ĩʼnşŧäľľęđ", - "modal-confirmation": "Ůpđäŧę", - "modal-dismiss": "Cľőşę", - "modal-in-progress": "Ůpđäŧįʼnģ...", - "modal-title": "Ůpđäŧę Pľūģįʼnş", - "name-header": "Ńämę", - "update-header": "Ůpđäŧę", - "update-status-text": "pľūģįʼnş ūpđäŧęđ" - }, - "versions": { - "confirmation-text-1": "Åřę yőū řęäľľy şūřę yőū ŵäʼnŧ ŧő đőŵʼnģřäđę ŧő vęřşįőʼn", - "confirmation-text-2": "Ÿőū şĥőūľđ ʼnőřmäľľy ʼnőŧ þę đőįʼnģ ŧĥįş", - "downgrade-confirm": "Đőŵʼnģřäđę", - "downgrade-title": "Đőŵʼnģřäđę pľūģįʼn vęřşįőʼn" - } - }, - "details": { - "connections-tab": { - "description": "Ÿőū čūřřęʼnŧľy ĥävę ŧĥę ƒőľľőŵįʼnģ đäŧä şőūřčęş čőʼnƒįģūřęđ ƒőř {{pluginName}}, čľįčĸ ä ŧįľę ŧő vįęŵ ŧĥę čőʼnƒįģūřäŧįőʼn đęŧäįľş. Ÿőū čäʼn ƒįʼnđ äľľ őƒ yőūř đäŧä şőūřčę čőʼnʼnęčŧįőʼnş įʼn <4><0>Cőʼnʼnęčŧįőʼnş - <3>Đäŧä şőūřčęş." - }, - "labels": { - "contactGrafanaLabs": "Cőʼnŧäčŧ Ğřäƒäʼnä Ŀäþş", - "customLinks": "Cūşŧőm ľįʼnĸş ", - "customLinksTooltip": "Ŧĥęşę ľįʼnĸş äřę přővįđęđ þy ŧĥę pľūģįʼn đęvęľőpęř ŧő őƒƒęř äđđįŧįőʼnäľ, đęvęľőpęř-şpęčįƒįč řęşőūřčęş äʼnđ įʼnƒőřmäŧįőʼn", - "dependencies": "Đępęʼnđęʼnčįęş", - "documentation": "Đőčūmęʼnŧäŧįőʼn", - "downloads": "Đőŵʼnľőäđş", - "from": "Fřőm", - "installedVersion": "Ĩʼnşŧäľľęđ Vęřşįőʼn", - "lastCommitDate": "Ŀäşŧ čőmmįŧ đäŧę:", - "latestVersion": "Ŀäŧęşŧ Vęřşįőʼn", - "license": "Ŀįčęʼnşę", - "raiseAnIssue": "Ŗäįşę äʼn įşşūę", - "reportAbuse": "Ŗępőřŧ ä čőʼnčęřʼn ", - "reportAbuseTooltip": "Ŗępőřŧ įşşūęş řęľäŧęđ ŧő mäľįčįőūş őř ĥäřmƒūľ pľūģįʼnş đįřęčŧľy ŧő Ğřäƒäʼnä Ŀäþş.", - "repository": "Ŗępőşįŧőřy", - "signature": "Ŝįģʼnäŧūřę", - "status": "Ŝŧäŧūş", - "updatedAt": "Ŀäşŧ ūpđäŧęđ:" - }, - "modal": { - "cancel": "Cäʼnčęľ", - "copyEmail": "Cőpy ęmäįľ äđđřęşş", - "description": "Ŧĥįş ƒęäŧūřę įş ƒőř řępőřŧįʼnģ mäľįčįőūş őř ĥäřmƒūľ þęĥävįőūř ŵįŧĥįʼn pľūģįʼnş. Főř pľūģįʼn čőʼnčęřʼnş, ęmäįľ ūş äŧ: ", - "node": "Ńőŧę: Főř ģęʼnęřäľ pľūģįʼn įşşūęş ľįĸę þūģş őř ƒęäŧūřę řęqūęşŧş, pľęäşę čőʼnŧäčŧ ŧĥę pľūģįʼn äūŧĥőř ūşįʼnģ ŧĥę přővįđęđ ľįʼnĸş. ", - "title": "Ŗępőřŧ ä pľūģįʼn čőʼnčęřʼn" - } - }, - "empty-state": { - "message": "Ńő pľūģįʼnş ƒőūʼnđ" - }, - "filter": { - "disabled": "Ŧĥįş ƒįľŧęř ĥäş þęęʼn đįşäþľęđ þęčäūşę ŧĥę Ğřäƒäʼnä şęřvęř čäʼnʼnőŧ äččęşş ģřäƒäʼnä.čőm", - "sort": "Ŝőřŧ", - "sort-list": "Ŝőřŧ Pľūģįʼnş Ŀįşŧ", - "state": "Ŝŧäŧę" - }, - "plugin-help": { - "error": "Åʼn ęřřőř őččūřřęđ ŵĥęʼn ľőäđįʼnģ ĥęľp.", - "not-found": "Ńő qūęřy ĥęľp čőūľđ þę ƒőūʼnđ." - } - }, - "profile": { - "change-password": { - "cancel-button": "Cäʼnčęľ", - "cannot-change-password-message": "Päşşŵőřđ čäʼnʼnőŧ þę čĥäʼnģęđ ĥęřę.", - "change-password-button": "Cĥäʼnģę Päşşŵőřđ", - "confirm-password-label": "Cőʼnƒįřm päşşŵőřđ", - "confirm-password-required": "Ńęŵ päşşŵőřđ čőʼnƒįřmäŧįőʼn įş řęqūįřęđ", - "ldap-auth-proxy-message": "Ÿőū čäʼnʼnőŧ čĥäʼnģę päşşŵőřđ ŵĥęʼn şįģʼnęđ įʼn ŵįŧĥ ĿĐÅP őř äūŧĥ přőχy.", - "new-password-label": "Ńęŵ päşşŵőřđ", - "new-password-required": "Ńęŵ päşşŵőřđ įş řęqūįřęđ", - "new-password-same-as-old": "Ńęŵ päşşŵőřđ čäʼn'ŧ þę ŧĥę şämę äş ŧĥę őľđ őʼnę.", - "old-password-label": "Øľđ päşşŵőřđ", - "old-password-required": "Øľđ päşşŵőřđ įş řęqūįřęđ", - "passwords-must-match": "Päşşŵőřđş mūşŧ mäŧčĥ", - "strong-password-validation-register": "Päşşŵőřđ đőęş ʼnőŧ čőmpľy ŵįŧĥ ŧĥę şŧřőʼnģ päşşŵőřđ pőľįčy" - } - }, - "public-dashboard": { - "acknowledgment-checkboxes": { - "ack-title": "ßęƒőřę yőū mäĸę ŧĥę đäşĥþőäřđ pūþľįč, äčĸʼnőŵľęđģę ŧĥę ƒőľľőŵįʼnģ:", - "data-src-ack-desc": "Pūþľįşĥįʼnģ čūřřęʼnŧľy őʼnľy ŵőřĸş ŵįŧĥ ä şūþşęŧ őƒ đäŧä şőūřčęş*", - "data-src-ack-tooltip": "Ŀęäřʼn mőřę äþőūŧ pūþľįč đäŧäşőūřčęş", - "public-ack-desc": "Ÿőūř ęʼnŧįřę đäşĥþőäřđ ŵįľľ þę pūþľįč*", - "public-ack-tooltip": "Ŀęäřʼn mőřę äþőūŧ pūþľįč đäşĥþőäřđş", - "usage-ack-desc": "Mäĸįʼnģ ä đäşĥþőäřđ pūþľįč ŵįľľ čäūşę qūęřįęş ŧő řūʼn ęäčĥ ŧįmę įŧ įş vįęŵęđ, ŵĥįčĥ mäy įʼnčřęäşę čőşŧş*", - "usage-ack-desc-tooltip": "Ŀęäřʼn mőřę äþőūŧ qūęřy čäčĥįʼnģ" - }, - "config": { - "can-view-dashboard-radio-button-label": "Cäʼn vįęŵ đäşĥþőäřđ", - "copy-button": "Cőpy", - "dashboard-url-field-label": "Đäşĥþőäřđ ŮŖĿ", - "email-share-type-option-label": "Øʼnľy şpęčįƒįęđ pęőpľę", - "pause-sharing-dashboard-label": "Päūşę şĥäřįʼnģ đäşĥþőäřđ", - "public-share-type-option-label": "Åʼnyőʼnę ŵįŧĥ ä ľįʼnĸ", - "revoke-public-URL-button": "Ŗęvőĸę pūþľįč ŮŖĿ", - "revoke-public-URL-button-title": "Ŗęvőĸę pūþľįč ŮŖĿ", - "settings-title": "Ŝęŧŧįʼnģş" - }, - "configuration": { - "display-annotations-description": "Přęşęʼnŧ äʼnʼnőŧäŧįőʼnş őʼn ŧĥįş đäşĥþőäřđ", - "display-annotations-label": "Đįşpľäy äʼnʼnőŧäŧįőʼnş", - "enable-time-range-description": "Åľľőŵ pęőpľę ŧő čĥäʼnģę ŧįmę řäʼnģę", - "enable-time-range-label": "Ēʼnäþľę ŧįmę řäʼnģę", - "settings-label": "Ŝęŧŧįʼnģş", - "success-pause": "Ÿőūř đäşĥþőäřđ äččęşş ĥäş þęęʼn päūşęđ", - "success-resume": "Ÿőūř đäşĥþőäřđ äččęşş ĥäş þęęʼn řęşūmęđ", - "success-update": "Ŝęŧŧįʼnģş ĥävę þęęʼn şūččęşşƒūľľy ūpđäŧęđ", - "success-update-old": "Pūþľįč đäşĥþőäřđ ūpđäŧęđ!", - "time-range-label": "Ŧįmę řäʼnģę", - "time-range-tooltip": "Ŧĥę şĥäřęđ đäşĥþőäřđ ūşęş ŧĥę đęƒäūľŧ ŧįmę řäʼnģę şęŧŧįʼnģş őƒ ŧĥę đäşĥþőäřđ" - }, - "create-page": { - "generate-public-url-button": "Ğęʼnęřäŧę pūþľįč ŮŖĿ", - "unsupported-features-desc": "Cūřřęʼnŧľy, ŵę đőʼn’ŧ şūppőřŧ ŧęmpľäŧę väřįäþľęş őř ƒřőʼnŧęʼnđ đäŧä şőūřčęş", - "welcome-title": "Ŵęľčőmę ŧő pūþľįč đäşĥþőäřđş!" - }, - "delete-modal": { - "revoke-body-text": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő řęvőĸę ŧĥįş ŮŖĿ? Ŧĥę đäşĥþőäřđ ŵįľľ ʼnő ľőʼnģęř þę pūþľįč.", - "revoke-title": "Ŗęvőĸę pūþľįč ŮŖĿ" - }, - "email-sharing": { - "accept-button": "Åččępŧ", - "alert-text": "Ŝĥäřįʼnģ đäşĥþőäřđş þy ęmäįľ įş þįľľęđ pęř ūşęř ƒőř ŧĥę đūřäŧįőʼn őƒ ŧĥę 30-đäy ŧőĸęʼn, řęģäřđľęşş őƒ ĥőŵ mäʼny đäşĥþőäřđş äřę şĥäřęđ. ßįľľįʼnģ şŧőpş äƒŧęř 30 đäyş ūʼnľęşş yőū řęʼnęŵ ŧĥę ŧőĸęʼn.", - "bill-ack": "Ĩ ūʼnđęřşŧäʼnđ ŧĥäŧ äđđįʼnģ ūşęřş řęqūįřęş päymęʼnŧ.*", - "cancel-button": "Cäʼnčęľ", - "input-invalid-email-text": "Ĩʼnväľįđ ęmäįľ", - "input-required-email-text": "Ēmäįľ įş řęqūįřęđ", - "invite-button": "Ĩʼnvįŧę", - "invite-field-desc": "Ĩʼnvįŧę pęőpľę þy ęmäįľ", - "invite-field-label": "Ĩʼnvįŧę", - "learn-more-button": "Ŀęäřʼn mőřę", - "recipient-email-placeholder": "Ēmäįľ", - "recipient-invalid-email-text": "Ĩʼnväľįđ ęmäįľ", - "recipient-invitation-button": "Ĩʼnvįŧę", - "recipient-invitation-description": "Ĩʼnvįŧę şőmęőʼnę þy ęmäįľ", - "recipient-invitation-tooltip": "Ŧĥįş đäşĥþőäřđ čőʼnŧäįʼnş şęʼnşįŧįvę đäŧä. ßy ūşįʼnģ ŧĥįş ƒęäŧūřę yőū ŵįľľ þę şĥäřįʼnģ ŵįŧĥ ęχŧęřʼnäľ pęőpľę.", - "recipient-list-description": "Øʼnľy pęőpľę yőū'vę đįřęčŧľy įʼnvįŧęđ čäʼn äččęşş ŧĥįş đäşĥþőäřđ", - "recipient-list-title": "Pęőpľę ŵįŧĥ äččęşş", - "recipient-required-email-text": "Ēmäįľ įş řęqūįřęđ", - "resend-button": "Ŗęşęʼnđ", - "resend-button-title": "Ŗęşęʼnđ", - "resend-invite-label": "Ŗęşęʼnđ įʼnvįŧę", - "revoke-access-label": "Ŗęvőĸę äččęşş", - "revoke-button": "Ŗęvőĸę", - "revoke-button-title": "Ŗęvőĸę", - "success-creation": "Ÿőūř đäşĥþőäřđ įş řęäđy ƒőř ęχŧęřʼnäľ şĥäřįʼnģ", - "success-share-type-change": "Đäşĥþőäřđ äččęşş ūpđäŧęđ: Øʼnľy şpęčįƒįč pęőpľę čäʼn ʼnőŵ äččęşş ŵįŧĥ ŧĥę ľįʼnĸ" - }, - "modal-alerts": { - "no-upsert-perm-alert-desc": "Cőʼnŧäčŧ yőūř äđmįʼn ŧő ģęŧ pęřmįşşįőʼn ŧő {{mode}} pūþľįč đäşĥþőäřđş", - "no-upsert-perm-alert-title": "Ÿőū đőʼn’ŧ ĥävę pęřmįşşįőʼn ŧő {{ mode }} ä pūþľįč đäşĥþőäřđ", - "save-dashboard-changes-alert-title": "Pľęäşę şävę yőūř đäşĥþőäřđ čĥäʼnģęş þęƒőřę ūpđäŧįʼnģ ŧĥę pūþľįč čőʼnƒįģūřäŧįőʼn", - "unsupport-data-source-alert-readmore-link": "Ŗęäđ mőřę äþőūŧ şūppőřŧęđ đäŧä şőūřčęş", - "unsupported-data-source-alert-desc": "Ŧĥęřę äřę đäŧä şőūřčęş įʼn ŧĥįş đäşĥþőäřđ ŧĥäŧ äřę ūʼnşūppőřŧęđ ƒőř pūþľįč đäşĥþőäřđş. Päʼnęľş ŧĥäŧ ūşę ŧĥęşę đäŧä şőūřčęş mäy ʼnőŧ ƒūʼnčŧįőʼn přőpęřľy: {{unsupportedDataSources}}.", - "unsupported-data-source-alert-title": "Ůʼnşūppőřŧęđ đäŧä şőūřčęş", - "unsupported-template-variable-alert-desc": "Ŧĥįş pūþľįč đäşĥþőäřđ mäy ʼnőŧ ŵőřĸ şįʼnčę įŧ ūşęş ŧęmpľäŧę väřįäþľęş", - "unsupported-template-variable-alert-title": "Ŧęmpľäŧę väřįäþľęş äřę ʼnőŧ şūppőřŧęđ" - }, - "public-sharing": { - "accept-button": "Åččępŧ", - "alert-text": "Ŝĥäřįʼnģ ŧĥįş đäşĥþőäřđ ęχŧęřʼnäľľy mäĸęş įŧ ęʼnŧįřęľy äččęşşįþľę ŧő äʼnyőʼnę ŵįŧĥ ŧĥę ľįʼnĸ.", - "cancel-button": "Cäʼnčęľ", - "learn-more-button": "Ŀęäřʼn mőřę", - "public-ack": "Ĩ ūʼnđęřşŧäʼnđ ŧĥäŧ ŧĥįş ęʼnŧįřę đäşĥþőäřđ ŵįľľ þę pūþľįč.*", - "success-creation": "Ÿőūř đäşĥþőäřđ įş ʼnőŵ pūþľįčľy äččęşşįþľę", - "success-share-type-change": "Đäşĥþőäřđ äččęşş ūpđäŧęđ: Åʼnyőʼnę ŵįŧĥ ŧĥę ľįʼnĸ čäʼn ʼnőŵ äččęşş" - }, - "settings-bar-header": { - "collapse-settings-tooltip": "Cőľľäpşę şęŧŧįʼnģş", - "expand-settings-tooltip": "Ēχpäʼnđ şęŧŧįʼnģş" - }, - "settings-configuration": { - "default-time-range-label": "Đęƒäūľŧ ŧįmę řäʼnģę", - "default-time-range-label-desc": "Ŧĥę pūþľįč đäşĥþőäřđ ūşęş ŧĥę đęƒäūľŧ ŧįmę řäʼnģę şęŧŧįʼnģş őƒ ŧĥę đäşĥþőäřđ", - "show-annotations-label": "Ŝĥőŵ äʼnʼnőŧäŧįőʼnş", - "show-annotations-label-desc": "Ŝĥőŵ äʼnʼnőŧäŧįőʼnş őʼn pūþľįč đäşĥþőäřđ", - "time-range-picker-label": "Ŧįmę řäʼnģę pįčĸęř ęʼnäþľęđ", - "time-range-picker-label-desc": "Åľľőŵ vįęŵęřş ŧő čĥäʼnģę ŧįmę řäʼnģę" - }, - "settings-summary": { - "annotations-hide-text": "Åʼnʼnőŧäŧįőʼnş = ĥįđę", - "annotations-show-text": "Åʼnʼnőŧäŧįőʼnş = şĥőŵ", - "time-range-picker-disabled-text": "Ŧįmę řäʼnģę pįčĸęř = đįşäþľęđ", - "time-range-picker-enabled-text": "Ŧįmę řäʼnģę pįčĸęř = ęʼnäþľęđ", - "time-range-text": "Ŧįmę řäʼnģę = " - }, - "share": { - "success-delete": "Ÿőūř đäşĥþőäřđ įş ʼnő ľőʼnģęř şĥäřęäþľę", - "success-delete-old": "Pūþľįč đäşĥþőäřđ đęľęŧęđ!" - }, - "share-configuration": { - "share-type-label": "Ŀįʼnĸ äččęşş" - }, - "share-externally": { - "copy-link-button": "Cőpy ęχŧęřʼnäľ ľįʼnĸ", - "email-share-type-option-description": "Øʼnľy pęőpľę ŵįŧĥ ŧĥę ľįʼnĸ čäʼn äččęşş đäşĥþőäřđ", - "email-share-type-option-label": "Øʼnľy şpęčįƒįč pęőpľę", - "no-upsert-perm-alert-desc": "Cőʼnŧäčŧ yőūř äđmįʼn ŧő ģęŧ pęřmįşşįőʼn ŧő {{mode}} şĥäřęđ đäşĥþőäřđş", - "no-upsert-perm-alert-title": "Ÿőū đőʼn’ŧ ĥävę pęřmįşşįőʼn ŧő {{ mode }} ä şĥäřęđ đäşĥþőäřđ", - "pause-access-button": "Päūşę äččęşş", - "pause-access-tooltip": "Päūşįʼnģ ŵįľľ ŧęmpőřäřįľy đįşäþľę äččęşş ŧő ŧĥįş đäşĥþőäřđ ƒőř äľľ ūşęřş", - "public-share-type-option-description": "Åʼnyőʼnę ŵįŧĥ ŧĥę ľįʼnĸ čäʼn äččęşş đäşĥþőäřđ", - "public-share-type-option-label": "Åʼnyőʼnę ŵįŧĥ ŧĥę ľįʼnĸ", - "resume-access-button": "Ŗęşūmę äččęşş", - "revoke-access-button": "Ŗęvőĸę äččęşş", - "revoke-access-description": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő řęvőĸę ŧĥįş äččęşş? Ŧĥę đäşĥþőäřđ čäʼn ʼnő ľőʼnģęř þę şĥäřęđ.", - "unsupported-data-source-alert-desc": "Ŧĥęřę äřę đäŧä şőūřčęş įʼn ŧĥįş đäşĥþőäřđ ŧĥäŧ äřę ūʼnşūppőřŧęđ ƒőř şĥäřęđ đäşĥþőäřđş. Päʼnęľş ŧĥäŧ ūşę ŧĥęşę đäŧä şőūřčęş mäy ʼnőŧ ƒūʼnčŧįőʼn přőpęřľy: {{unsupportedDataSources}}." - }, - "sharing": { - "success-creation": "Đäşĥþőäřđ įş pūþľįč!" - } - }, - "public-dashboard-list": { - "button": { - "config-button-tooltip": "Cőʼnƒįģūřę pūþľįč đäşĥþőäřđ", - "revoke-button-text": "Ŗęvőĸę pūþľįč ŮŖĿ", - "revoke-button-tooltip": "Ŗęvőĸę pūþľįč đäşĥþőäřđ ŮŖĿ", - "view-button-tooltip": "Vįęŵ pūþľįč đäşĥþőäřđ" - }, - "empty-state": { - "message": "Ÿőū ĥävęʼn'ŧ čřęäŧęđ äʼny pūþľįč đäşĥþőäřđş yęŧ", - "more-info": "Cřęäŧę ä pūþľįč đäşĥþőäřđ ƒřőm äʼny ęχįşŧįʼnģ đäşĥþőäřđ ŧĥřőūģĥ ŧĥę <1>Ŝĥäřę mőđäľ. <4>Ŀęäřʼn mőřę" - }, - "toggle": { - "pause-sharing-toggle-text": "Päūşę şĥäřįʼnģ" - } - }, - "public-dashboard-users-access-list": { - "dashboard-modal": { - "external-link": "Ēχŧęřʼnäľ ľįʼnĸ", - "loading-text": "Ŀőäđįʼnģ...", - "open-dashboard-list-text": "Øpęʼn đäşĥþőäřđş ľįşŧ", - "public-dashboard-link": "Pūþľįč đäşĥþőäřđ ŮŖĿ", - "public-dashboard-setting": "Pūþľįč đäşĥþőäřđ şęŧŧįʼnģş", - "sharing-setting": "Ŝĥäřįʼnģ şęŧŧįʼnģş" - }, - "delete-user-modal": { - "delete-user-button-text": "Đęľęŧę ūşęř", - "delete-user-cancel-button": "Cäʼnčęľ", - "delete-user-revoke-access-button": "Ŗęvőĸę äččęşş", - "revoke-access-title": "Ŗęvőĸę äččęşş", - "revoke-user-access-modal-desc-line1": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő řęvőĸę äččęşş ƒőř {{email}}?", - "revoke-user-access-modal-desc-line2": "Ŧĥįş äčŧįőʼn ŵįľľ įmmęđįäŧęľy řęvőĸę {{email}}&äpőş;ş äččęşş ŧő äľľ pūþľįč đäşĥþőäřđş." - }, - "delete-user-shared-dashboards-modal": { - "revoke-user-access-modal-desc-line2": "Ŧĥįş äčŧįőʼn ŵįľľ įmmęđįäŧęľy řęvőĸę {{email}}&äpőş;ş äččęşş ŧő äľľ şĥäřęđ đäşĥþőäřđş." - }, - "modal": { - "dashboard-modal-title": "Pūþľįč đäşĥþőäřđş", - "shared-dashboard-modal-title": "Ŝĥäřęđ đäşĥþőäřđş" - }, - "table-body": { - "dashboard-count_one": "{{count}} đäşĥþőäřđş", - "dashboard-count_other": "{{count}} đäşĥþőäřđş" - }, - "table-header": { - "activated-label": "Åčŧįväŧęđ", - "activated-tooltip": "Ēäřľįęşŧ ŧįmę ūşęř ĥäş þęęʼn äʼn äčŧįvę ūşęř ŧő ä đäşĥþőäřđ", - "email-label": "Ēmäįľ", - "last-active-label": "Ŀäşŧ äčŧįvę", - "origin-label": "Øřįģįʼn", - "role-label": "Ŗőľę" - } - }, - "query-operation": { - "header": { - "collapse-row": "Cőľľäpşę qūęřy řőŵ", - "datasource-help": "Ŝĥőŵ đäŧä şőūřčę ĥęľp", - "drag-and-drop": "Đřäģ äʼnđ đřőp ŧő řęőřđęř", - "duplicate-query": "Đūpľįčäŧę qūęřy", - "expand-row": "Ēχpäʼnđ qūęřy řőŵ", - "hide-response": "Ħįđę řęşpőʼnşę", - "remove-query": "Ŗęmővę qūęřy", - "show-response": "Ŝĥőŵ řęşpőʼnşę", - "toggle-edit-mode": "Ŧőģģľę ŧęχŧ ęđįŧ mőđę" - }, - "query-editor-not-exported": "Đäŧä şőūřčę pľūģįʼn đőęş ʼnőŧ ęχpőřŧ äʼny Qūęřy Ēđįŧőř čőmpőʼnęʼnŧ" - }, - "recently-deleted": { - "buttons": { - "delete": "Đęľęŧę pęřmäʼnęʼnŧľy", - "restore": "Ŗęşŧőřę" - }, - "page": { - "no-deleted-dashboards": "Ÿőū ĥävęʼn'ŧ đęľęŧęđ äʼny đäşĥþőäřđş řęčęʼnŧľy.", - "no-deleted-dashboards-text": "Ŵĥęʼn yőū đęľęŧę ä đäşĥþőäřđ, įŧ ŵįľľ äppęäř ĥęřę ƒőř 30 đäyş þęƒőřę þęįʼnģ pęřmäʼnęʼnŧľy đęľęŧęđ. Ÿőūř őřģäʼnįžäŧįőʼn äđmįʼnįşŧřäŧőř čäʼn řęşŧőřę řęčęʼnŧľy-đęľęŧęđ đäşĥþőäřđş.", - "no-search-result": "Ńő řęşūľŧş ƒőūʼnđ ƒőř yőūř qūęřy" - }, - "permanently-delete-modal": { - "confirm-text": "Đęľęŧę", - "delete-button": "Đęľęŧę", - "delete-loading": "Đęľęŧįʼnģ...", - "text_one": "Ŧĥįş äčŧįőʼn ŵįľľ đęľęŧę {{numberOfDashboards}} đäşĥþőäřđş.", - "text_other": "Ŧĥįş äčŧįőʼn ŵįľľ đęľęŧę {{numberOfDashboards}} đäşĥþőäřđş.", - "title": "Pęřmäʼnęʼnŧľy Đęľęŧę Đäşĥþőäřđş" - }, - "restore-modal": { - "folder-picker-text_one": "Pľęäşę čĥőőşę ä ƒőľđęř ŵĥęřę yőūř đäşĥþőäřđş ŵįľľ þę řęşŧőřęđ.", - "folder-picker-text_other": "Pľęäşę čĥőőşę ä ƒőľđęř ŵĥęřę yőūř đäşĥþőäřđş ŵįľľ þę řęşŧőřęđ.", - "restore-button": "Ŗęşŧőřę", - "restore-loading": "Ŗęşŧőřįʼnģ...", - "text_one": "Ŧĥįş äčŧįőʼn ŵįľľ řęşŧőřę {{numberOfDashboards}} đäşĥþőäřđş.", - "text_other": "Ŧĥįş äčŧįőʼn ŵįľľ řęşŧőřę {{numberOfDashboards}} đäşĥþőäřđş.", - "title": "Ŗęşŧőřę Đäşĥþőäřđş" - } - }, - "recentlyDeleted": { - "filter": { - "placeholder": "Ŝęäřčĥ ƒőř đäşĥþőäřđş" - } - }, - "reduce": { - "strictMode": { - "description": "Ŵĥęʼn <1>Ŗęđūčę Ŝŧřįčŧ mőđę įş ūşęđ, ŧĥę <3>ƒįľľ(ʼnūľľ) ƒūʼnčŧįőʼn (ĨʼnƒľūχQĿ) ŵįľľ řęşūľŧ įʼn <6>ŃäŃ. <9>Ŝęę ŧĥę đőčūmęʼnŧäŧįőʼn ƒőř mőřę đęŧäįľş.", - "title": "Ŝŧřįčŧ Mőđę ßęĥävįőūř" - } - }, - "refresh-picker": { - "aria-label": { - "choose-interval": "Åūŧő řęƒřęşĥ ŧūřʼnęđ őƒƒ. Cĥőőşę řęƒřęşĥ ŧįmę įʼnŧęřväľ", - "duration-selected": "Cĥőőşę řęƒřęşĥ ŧįmę įʼnŧęřväľ ŵįŧĥ čūřřęʼnŧ įʼnŧęřväľ {{durationAriaLabel}} şęľęčŧęđ" - }, - "auto-option": { - "aria-label": "", - "label": "" - }, - "live-option": { - "aria-label": "Ŧūřʼn őʼn ľįvę şŧřęämįʼnģ", - "label": "Ŀįvę" - }, - "off-option": { - "aria-label": "Ŧūřʼn őƒƒ äūŧő řęƒřęşĥ", - "label": "؃ƒ" - }, - "tooltip": { - "interval-selected": "Ŝęŧ äūŧő řęƒřęşĥ įʼnŧęřväľ", - "turned-off": "Åūŧő řęƒřęşĥ őƒƒ" - } - }, - "return-to-previous": { - "button": { - "label": "ßäčĸ ŧő {{title}}" - }, - "dismissable-button": "Cľőşę" - }, - "role-picker": { - "built-in": { - "basic-roles": "ßäşįč řőľęş" - }, - "input": { - "no-roles": "Ńő řőľęş äşşįģʼnęđ" - }, - "menu": { - "clear-button": "Cľęäř äľľ", - "tooltip": "Ÿőū čäʼn ʼnőŵ şęľęčŧ ŧĥę \"Ńő þäşįč řőľę\" őpŧįőʼn äʼnđ äđđ pęřmįşşįőʼnş ŧő yőūř čūşŧőm ʼnęęđş. Ÿőū čäʼn ƒįʼnđ mőřę įʼnƒőřmäŧįőʼn įʼn <1>őūř đőčūmęʼnŧäŧįőʼn." - }, - "sub-menu": { - "clear-button": "Cľęäř" - }, - "title": { - "description": "Åşşįģʼn řőľęş ŧő ūşęřş ŧő ęʼnşūřę ģřäʼnūľäř čőʼnŧřőľ ővęř äččęşş ŧő Ğřäƒäʼnä&ľşqūő;ş ƒęäŧūřęş äʼnđ řęşőūřčęş. Fįʼnđ őūŧ mőřę įʼn őūř <2>đőčūmęʼnŧäŧįőʼn." - } - }, - "role-picker-drawer": { - "basic-roles": { - "label": "ßäşįč Ŗőľęş" - } - }, - "route-error": { - "description": "Ğřäƒäʼnä ĥäş ľįĸęľy þęęʼn ūpđäŧęđ. Pľęäşę ŧřy řęľőäđįʼnģ ŧĥę päģę.", - "reload-button": "Ŗęľőäđ", - "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ę őř ƒőľđęř.", - "title": "Đäşĥþőäřđ ʼnämę äľřęäđy ęχįşŧş" - } - }, - "scopes": { - "dashboards": { - "collapse": "Cőľľäpşę", - "expand": "Ēχpäʼnđ", - "loading": "Ŀőäđįʼnģ đäşĥþőäřđş", - "noResultsForFilter": "Ńő řęşūľŧş ƒőūʼnđ ƒőř yőūř qūęřy", - "noResultsForFilterClear": "Cľęäř şęäřčĥ", - "noResultsForScopes": "Ńő đäşĥþőäřđş ƒőūʼnđ ƒőř ŧĥę şęľęčŧęđ şčőpęş", - "noResultsNoScopes": "Ńő şčőpęş şęľęčŧęđ", - "search": "Ŝęäřčĥ", - "toggle": { - "collapse": "Cőľľäpşę şūģģęşŧęđ đäşĥþőäřđş ľįşŧ", - "disabled": "Ŝūģģęşŧęđ đäşĥþőäřđş ľįşŧ įş đįşäþľęđ đūę ŧő řęäđ őʼnľy mőđę", - "expand": "Ēχpäʼnđ şūģģęşŧęđ đäşĥþőäřđş ľįşŧ" - } - }, - "selector": { - "apply": "Åppľy", - "cancel": "Cäʼnčęľ", - "input": { - "placeholder": "Ŝęľęčŧ şčőpęş...", - "removeAll": "Ŗęmővę äľľ şčőpęş" - }, - "title": "Ŝęľęčŧ şčőpęş" - }, - "tree": { - "collapse": "Cőľľäpşę", - "expand": "Ēχpäʼnđ", - "headline": { - "noResults": "Ńő řęşūľŧş ƒőūʼnđ ƒőř yőūř qūęřy", - "recommended": "Ŗęčőmmęʼnđęđ", - "results": "Ŗęşūľŧş" - }, - "search": "Ŝęäřčĥ" - } - }, - "search": { - "actions": { - "include-panels": "Ĩʼnčľūđę päʼnęľş", - "remove-datasource-filter": "Đäŧäşőūřčę: {{datasource}}", - "sort-placeholder": "Ŝőřŧ", - "starred": "Ŝŧäřřęđ", - "view-as-folders": "Vįęŵ þy ƒőľđęřş", - "view-as-list": "Vįęŵ äş ľįşŧ" - }, - "dashboard-actions": { - "import": "Ĩmpőřŧ", - "new": "Ńęŵ", - "new-dashboard": "Ńęŵ đäşĥþőäřđ", - "new-folder": "Ńęŵ ƒőľđęř" - }, - "results-table": { - "datasource-header": "Đäŧä şőūřčę", - "deleted-less-than-1-min": "< 1 mįʼn", - "deleted-remaining-header": "Ŧįmę řęmäįʼnįʼnģ", - "location-header": "Ŀőčäŧįőʼn", - "name-header": "Ńämę", - "tags-header": "Ŧäģş", - "type-dashboard": "Đäşĥþőäřđ", - "type-folder": "Főľđęř", - "type-header": "Ŧypę" - }, - "search-input": { - "include-panels-placeholder": "Ŝęäřčĥ ƒőř đäşĥþőäřđş, ƒőľđęřş, äʼnđ päʼnęľş", - "placeholder": "Ŝęäřčĥ ƒőř đäşĥþőäřđş äʼnđ ƒőľđęřş" - } - }, - "select": { - "select-menu": { - "selected-count": "Ŝęľęčŧęđ " - } - }, - "service-account-create-page": { - "create": { - "button": "Cřęäŧę" - }, - "name": { - "label": "Đįşpľäy ʼnämę", - "required-error": "Đįşpľäy ʼnämę įş řęqūįřęđ" - }, - "page-nav": { - "label": "Cřęäŧę şęřvįčę äččőūʼnŧ" - }, - "role": { - "label": "Ŗőľę" - } - }, - "service-accounts": { - "empty-state": { - "button-title": "Åđđ şęřvįčę äččőūʼnŧ", - "message": "Ńő şęřvįčęş äččőūʼnŧş ƒőūʼnđ", - "more-info": "Ŗęmęmþęř, yőū čäʼn přővįđę şpęčįƒįč pęřmįşşįőʼnş ƒőř ÅPĨ äččęşş ŧő őŧĥęř äppľįčäŧįőʼnş", - "title": "Ÿőū ĥävęʼn'ŧ čřęäŧęđ äʼny şęřvįčę äččőūʼnŧş yęŧ" - } - }, - "share-dashboard": { - "menu": { - "export-json-title": "Ēχpőřŧ äş ĴŜØŃ", - "share-externally-title": "Ŝĥäřę ęχŧęřʼnäľľy", - "share-internally-title": "Ŝĥäřę įʼnŧęřʼnäľľy", - "share-snapshot-title": "Ŝĥäřę şʼnäpşĥőŧ" - }, - "share-button": "Ŝĥäřę", - "share-button-tooltip": "Cőpy ľįʼnĸ" - }, - "share-drawer": { - "confirm-action": { - "back-arrow-button": "ßäčĸ þūŧŧőʼn", - "cancel-button": "Cäʼnčęľ" - } - }, - "share-modal": { - "dashboard": { - "title": "Ŝĥäřę" - }, - "embed": { - "copy": "Cőpy ŧő čľįpþőäřđ", - "html": "Ēmþęđ ĦŦMĿ", - "html-description": "Ŧĥę ĦŦMĿ čőđę þęľőŵ čäʼn þę päşŧęđ äʼnđ įʼnčľūđęđ įʼn äʼnőŧĥęř ŵęþ päģę. Ůʼnľęşş äʼnőʼnymőūş äččęşş įş ęʼnäþľęđ, ŧĥę ūşęřş vįęŵįʼnģ ŧĥäŧ päģę ʼnęęđ ŧő þę şįģʼnęđ įʼnŧő Ğřäƒäʼnä ƒőř ŧĥę ģřäpĥ ŧő ľőäđ.", - "info": "Ğęʼnęřäŧę ĦŦMĿ ƒőř ęmþęđđįʼnģ äʼn įƒřämę ŵįŧĥ ŧĥįş päʼnęľ", - "time-range": "Ŀőčĸ ŧįmę řäʼnģę" - }, - "export": { - "back-button": "ßäčĸ ŧő ęχpőřŧ čőʼnƒįģ", - "cancel-button": "Cäʼnčęľ", - "info-text": "Ēχpőřŧ ŧĥįş đäşĥþőäřđ.", - "loading": "Ŀőäđįʼnģ...", - "save-button": "Ŝävę ŧő ƒįľę", - "share-externally-label": "Ēχpőřŧ ƒőř şĥäřįʼnģ ęχŧęřʼnäľľy", - "view-button": "Vįęŵ ĴŜØŃ" - }, - "library": { - "info": "Cřęäŧę ľįþřäřy päʼnęľ." - }, - "link": { - "copy-link-button": "Cőpy", - "info-text": "Cřęäŧę ä đįřęčŧ ľįʼnĸ ŧő ŧĥįş đäşĥþőäřđ őř päʼnęľ, čūşŧőmįžęđ ŵįŧĥ ŧĥę őpŧįőʼnş þęľőŵ.", - "link-url": "Ŀįʼnĸ ŮŖĿ", - "render-alert": "Ĩmäģę řęʼnđęřęř pľūģįʼn ʼnőŧ įʼnşŧäľľęđ", - "render-instructions": "Ŧő řęʼnđęř ä päʼnęľ įmäģę, yőū mūşŧ įʼnşŧäľľ ŧĥę <2>Ğřäƒäʼnä įmäģę řęʼnđęřęř pľūģįʼn. Pľęäşę čőʼnŧäčŧ yőūř Ğřäƒäʼnä äđmįʼnįşŧřäŧőř ŧő įʼnşŧäľľ ŧĥę pľūģįʼn.", - "rendered-image": "Đįřęčŧ ľįʼnĸ řęʼnđęřęđ įmäģę", - "save-alert": "Đäşĥþőäřđ įş ʼnőŧ şävęđ", - "save-dashboard": "Ŧő řęʼnđęř ä päʼnęľ įmäģę, yőū mūşŧ şävę ŧĥę đäşĥþőäřđ ƒįřşŧ.", - "shorten-url": "Ŝĥőřŧęʼn ŮŖĿ", - "time-range-description": "Ŧřäʼnşƒőřmş ŧĥę čūřřęʼnŧ řęľäŧįvę ŧįmę řäʼnģę ŧő äʼn äþşőľūŧę ŧįmę řäʼnģę", - "time-range-label": "Ŀőčĸ ŧįmę řäʼnģę" - }, - "panel": { - "title": "Ŝĥäřę Päʼnęľ" - }, - "snapshot": { - "cancel-button": "Cäʼnčęľ", - "copy-link-button": "Cőpy", - "delete-button": "Đęľęŧę şʼnäpşĥőŧ.", - "deleted-message": "Ŧĥę şʼnäpşĥőŧ ĥäş þęęʼn đęľęŧęđ. Ĩƒ yőū ĥävę äľřęäđy äččęşşęđ įŧ őʼnčę, ŧĥęʼn įŧ mįģĥŧ ŧäĸę ūp ŧő äʼn ĥőūř þęƒőřę þęƒőřę įŧ įş řęmővęđ ƒřőm þřőŵşęř čäčĥęş őř CĐŃ čäčĥęş.", - "expire": "Ēχpįřę", - "expire-day": "1 Đäy", - "expire-hour": "1 Ħőūř", - "expire-never": "Ńęvęř", - "expire-week": "1 Ŵęęĸ", - "info-text-1": "Å şʼnäpşĥőŧ įş äʼn įʼnşŧäʼnŧ ŵäy ŧő şĥäřę äʼn įʼnŧęřäčŧįvę đäşĥþőäřđ pūþľįčľy. Ŵĥęʼn čřęäŧęđ, ŵę şŧřįp şęʼnşįŧįvę đäŧä ľįĸę qūęřįęş (męŧřįč, ŧęmpľäŧę, äʼnđ äʼnʼnőŧäŧįőʼn) äʼnđ päʼnęľ ľįʼnĸş, ľęävįʼnģ őʼnľy ŧĥę vįşįþľę męŧřįč đäŧä äʼnđ şęřįęş ʼnämęş ęmþęđđęđ įʼn yőūř đäşĥþőäřđ.", - "info-text-2": "Ķęęp įʼn mįʼnđ, yőūř şʼnäpşĥőŧ <1>čäʼn þę vįęŵęđ þy äʼnyőʼnę ŧĥäŧ ĥäş ŧĥę ľįʼnĸ äʼnđ čäʼn äččęşş ŧĥę ŮŖĿ. Ŝĥäřę ŵįşęľy.", - "local-button": "Pūþľįşĥ Ŝʼnäpşĥőŧ", - "mistake-message": "Đįđ yőū mäĸę ä mįşŧäĸę? ", - "name": "Ŝʼnäpşĥőŧ ʼnämę", - "timeout": "Ŧįmęőūŧ (şęčőʼnđş)", - "timeout-description": "Ÿőū mįģĥŧ ʼnęęđ ŧő čőʼnƒįģūřę ŧĥę ŧįmęőūŧ väľūę įƒ įŧ ŧäĸęş ä ľőʼnģ ŧįmę ŧő čőľľęčŧ yőūř đäşĥþőäřđ męŧřįčş.", - "url-label": "Ŝʼnäpşĥőŧ ŮŖĿ" - }, - "tab-title": { - "embed": "Ēmþęđ", - "export": "Ēχpőřŧ", - "library-panel": "Ŀįþřäřy päʼnęľ", - "link": "Ŀįʼnĸ", - "panel-embed": "Ēmþęđ", - "public-dashboard": "Pūþľįč Đäşĥþőäřđ", - "public-dashboard-title": "Pūþľįč đäşĥþőäřđ", - "snapshot": "Ŝʼnäpşĥőŧ" - }, - "theme-picker": { - "current": "Cūřřęʼnŧ", - "dark": "Đäřĸ", - "field-name": "Ŧĥęmę", - "light": "Ŀįģĥŧ" - }, - "view-json": { - "copy-button": "Cőpy ŧő Cľįpþőäřđ" - } - }, - "share-panel": { - "drawer": { - "new-library-panel-title": "Ńęŵ ľįþřäřy päʼnęľ", - "share-embed-title": "Ŝĥäřę ęmþęđ", - "share-link-title": "Ŀįʼnĸ şęŧŧįʼnģş" - }, - "menu": { - "new-library-panel-title": "Ńęŵ ľįþřäřy päʼnęľ", - "share-embed-title": "Ŝĥäřę ęmþęđ", - "share-link-title": "Ŝĥäřę ľįʼnĸ", - "share-snapshot-title": "Ŝĥäřę şʼnäpşĥőŧ" - }, - "new-library-panel": { - "cancel-button": "Cäʼnčęľ", - "create-button": "Cřęäŧę ľįþřäřy päʼnęľ" - } - }, - "share-panel-image": { - "preview": { - "title": "Päʼnęľ přęvįęŵ" - }, - "settings": { - "height-label": "Ħęįģĥŧ", - "height-min": "Ħęįģĥŧ mūşŧ þę ęqūäľ őř ģřęäŧęř ŧĥäʼn 1", - "height-placeholder": "500", - "height-required": "Ħęįģĥŧ įş řęqūįřęđ", - "max-warning": "Ŝęŧŧįʼnģ mäχįmūmş äřę ľįmįŧęđ þy ŧĥę įmäģę řęʼnđęřęř şęřvįčę", - "scale-factor-label": "Ŝčäľę ƒäčŧőř", - "scale-factor-min": "Ŝčäľę ƒäčŧőř mūşŧ þę ęqūäľ őř ģřęäŧęř ŧĥäʼn 1", - "scale-factor-placeholder": "1", - "scale-factor-required": "Ŝčäľę ƒäčŧőř įş řęqūįřęđ", - "title": "Ĩmäģę şęŧŧįʼnģş", - "width-label": "Ŵįđŧĥ", - "width-min": "Ŵįđŧĥ mūşŧ þę ęqūäľ őř ģřęäŧęř ŧĥäʼn 1", - "width-placeholder": "1000", - "width-required": "Ŵįđŧĥ įş řęqūįřęđ" - } - }, - "share-playlist": { - "checkbox-description": "Päʼnęľ ĥęįģĥŧş ŵįľľ þę äđĵūşŧęđ ŧő ƒįŧ şčřęęʼn şįžę", - "checkbox-label": "Åūŧőƒįŧ", - "copy-link-button": "Cőpy", - "link-url-label": "Ŀįʼnĸ ŮŖĿ", - "mode": "Mőđę", - "mode-kiosk": "Ķįőşĸ", - "mode-normal": "Ńőřmäľ", - "title": "Ŝĥäřę pľäyľįşŧ" - }, - "shared": { - "preferences": { - "theme": { - "dark-label": "Đäřĸ", - "light-label": "Ŀįģĥŧ", - "system-label": "Ŝyşŧęm přęƒęřęʼnčę" - } - } - }, - "shared-dashboard": { - "delete-modal": { - "revoke-body-text": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő řęvőĸę ŧĥįş äččęşş? Ŧĥę đäşĥþőäřđ čäʼn ʼnő ľőʼnģęř þę şĥäřęđ.", - "revoke-title": "Ŗęvőĸę äččęşş" - }, - "fields": { - "timezone-label": "Ŧįmęžőʼnę" - } - }, - "shared-dashboard-list": { - "button": { - "config-button-tooltip": "Cőʼnƒįģūřę şĥäřęđ đäşĥþőäřđ", - "revoke-button-text": "Ŗęvőĸę äččęşş", - "revoke-button-tooltip": "Ŗęvőĸę äččęşş", - "view-button-tooltip": "Vįęŵ şĥäřęđ đäşĥþőäřđ" - }, - "empty-state": { - "message": "Ÿőū ĥävęʼn'ŧ čřęäŧęđ äʼny şĥäřęđ đäşĥþőäřđş yęŧ", - "more-info": "Cřęäŧę ä şĥäřęđ đäşĥþőäřđ ƒřőm äʼny ęχįşŧįʼnģ đäşĥþőäřđ ŧĥřőūģĥ ŧĥę <1>Ŝĥäřę mőđäľ. <4>Ŀęäřʼn mőřę" - }, - "toggle": { - "pause-sharing-toggle-text": "Päūşę äččęşş" - } - }, - "shared-preferences": { - "fields": { - "home-dashboard-label": "Ħőmę Đäşĥþőäřđ", - "home-dashboard-placeholder": "Đęƒäūľŧ đäşĥþőäřđ", - "locale-label": "Ŀäʼnģūäģę", - "locale-placeholder": "Cĥőőşę ľäʼnģūäģę", - "theme-description": "Ēʼnĵőyįʼnģ ŧĥę ľįmįŧęđ ęđįŧįőʼn ŧĥęmęş? Ŧęľľ ūş ŵĥäŧ yőū'đ ľįĸę ŧő şęę <2>ĥęřę.", - "theme-label": "Ĩʼnŧęřƒäčę ŧĥęmę", - "week-start-label": "Ŵęęĸ şŧäřŧ" - }, - "theme": { - "default-label": "Đęƒäūľŧ" - }, - "title": "Přęƒęřęʼnčęş" - }, - "sign-up": { - "back-button": "ßäčĸ ŧő ľőģįʼn", - "submit-button": "Ŝūþmįŧ", - "verify": { - "back-button": "ßäčĸ ŧő ľőģįʼn", - "complete-button": "Cőmpľęŧę şįģʼnūp", - "header": "Vęřįƒy ęmäįľ", - "info": "Åʼn ęmäįľ ŵįŧĥ ä vęřįƒįčäŧįőʼn ľįʼnĸ ĥäş þęęʼn şęʼnŧ ŧő ŧĥę ęmäįľ äđđřęşş. Ÿőū şĥőūľđ řęčęįvę įŧ şĥőřŧľy.", - "send-button": "Ŝęʼnđ vęřįƒįčäŧįőʼn ęmäįľ" - } - }, - "silences": { - "empty-state": { - "button-title": "Cřęäŧę şįľęʼnčę", - "title": "Ÿőū ĥävęʼn'ŧ čřęäŧęđ äʼny şįľęʼnčęş yęŧ" - }, - "table": { - "add-silence-button": "Åđđ Ŝįľęʼnčę", - "edit-button": "Ēđįŧ", - "expired-silences": "Ēχpįřęđ şįľęʼnčęş äřę äūŧőmäŧįčäľľy đęľęŧęđ äƒŧęř 5 đäyş.", - "no-matching-silences": "Ńő mäŧčĥįʼnģ şįľęʼnčęş ƒőūʼnđ;", - "noConfig": "Cřęäŧę ä ʼnęŵ čőʼnŧäčŧ pőįʼnŧ ŧő čřęäŧę ä čőʼnƒįģūřäŧįőʼn ūşįʼnģ ŧĥę đęƒäūľŧ väľūęş őř čőʼnŧäčŧ yőūř äđmįʼnįşŧřäŧőř ŧő şęŧ ūp ŧĥę Åľęřŧmäʼnäģęř.", - "recreate-button": "Ŗęčřęäŧę", - "unsilence-button": "Ůʼnşįľęʼnčę" - } - }, - "silences-table": { - "header": { - "alert-name": "Åľęřŧ ʼnämę", - "state": "Ŝŧäŧę" - } - }, - "snapshot": { - "empty-state": { - "message": "Ÿőū ĥävęʼn'ŧ čřęäŧęđ äʼny şʼnäpşĥőŧş yęŧ", - "more-info": "Ÿőū čäʼn čřęäŧę ä şʼnäpşĥőŧ őƒ äʼny đäşĥþőäřđ ŧĥřőūģĥ ŧĥę <1>Ŝĥäřę mőđäľ. <4>Ŀęäřʼn mőřę" - }, - "external-badge": "Ēχŧęřʼnäľ", - "name-column-header": "Ńämę", - "share": { - "cancel-button": "Cäʼnčęľ", - "copy-link-button": "Cőpy ľįʼnĸ", - "delete-button": "Đęľęŧę şʼnäpşĥőŧ", - "delete-description": "Åřę yőū şūřę yőū ŵäʼnŧ ŧő đęľęŧę ŧĥįş şʼnäpşĥőŧ?", - "delete-permission-tooltip": "Ÿőū đőʼn'ŧ ĥävę pęřmįşşįőʼn ŧő đęľęŧę şʼnäpşĥőŧş", - "delete-title": "Đęľęŧę şʼnäpşĥőŧ", - "deleted-alert": "Ŝʼnäpşĥőŧ đęľęŧęđ. Ĩŧ čőūľđ ŧäĸę äʼn ĥőūř ŧő þę čľęäřęđ ƒřőm CĐŃ čäčĥęş.", - "expiration-label": "Ēχpįřęş įʼn", - "info-alert": "Å Ğřäƒäʼnä đäşĥþőäřđ şʼnäpşĥőŧ pūþľįčľy şĥäřęş ä đäşĥþőäřđ ŵĥįľę řęmővįʼnģ şęʼnşįŧįvę đäŧä şūčĥ äş qūęřįęş äʼnđ päʼnęľ ľįʼnĸş, ľęävįʼnģ őʼnľy vįşįþľę męŧřįčş äʼnđ şęřįęş ʼnämęş. Åʼnyőʼnę ŵįŧĥ ŧĥę ľįʼnĸ čäʼn äččęşş ŧĥę şʼnäpşĥőŧ.", - "learn-more-button": "Ŀęäřʼn mőřę", - "local-button": "Pūþľįşĥ şʼnäpşĥőŧ", - "name-label": "Ŝʼnäpşĥőŧ ʼnämę", - "new-snapshot-button": "Ńęŵ şʼnäpşĥőŧ", - "success-creation": "Ÿőūř şʼnäpşĥőŧ ĥäş þęęʼn čřęäŧęđ", - "success-delete": "Ÿőūř şʼnäpşĥőŧ ĥäş þęęʼn đęľęŧęđ", - "view-all-button": "Vįęŵ äľľ şʼnäpşĥőŧş" - }, - "share-panel": { - "info-alert": "Å Ğřäƒäʼnä päʼnęľ şʼnäpşĥőŧ pūþľįčľy şĥäřęş ä päʼnęľ ŵĥįľę řęmővįʼnģ şęʼnşįŧįvę đäŧä şūčĥ äş qūęřįęş äʼnđ päʼnęľ ľįʼnĸş, ľęävįʼnģ őʼnľy vįşįþľę męŧřįčş äʼnđ şęřįęş ʼnämęş. Åʼnyőʼnę ŵįŧĥ ŧĥę ľįʼnĸ čäʼn äččęşş ŧĥę şʼnäpşĥőŧ." - }, - "url-column-header": "Ŝʼnäpşĥőŧ ūřľ", - "view-button": "Vįęŵ" - }, - "table": { - "container": { - "content": "Ŝĥőŵįʼnģ ŧőő mäʼny čőľūmʼnş įʼn ä şįʼnģľę ŧäþľę mäy įmpäčŧ pęřƒőřmäʼnčę äʼnđ mäĸę đäŧä ĥäřđęř ŧő řęäđ. Cőʼnşįđęř řęƒįʼnįʼnģ yőūř qūęřįęş.", - "show-all-series": "Ŝĥőŵ äľľ čőľūmʼnş", - "show-only-series": "Ŝĥőŵįʼnģ őʼnľy {{MAX_NUMBER_OF_COLUMNS}} čőľūmʼnş" - } - }, - "tag-filter": { - "clear-button": "Cľęäř ŧäģş", - "loading": "Ŀőäđįʼnģ...", - "no-tags": "Ńő ŧäģş ƒőūʼnđ", - "placeholder": "Fįľŧęř þy ŧäģ" - }, - "teams": { - "empty-state": { - "button-title": "Ńęŵ ŧęäm", - "message": "Ńő ŧęämş ƒőūʼnđ", - "pro-tip": "Åşşįģʼn ƒőľđęř äʼnđ đäşĥþőäřđ pęřmįşşįőʼnş ŧő ŧęämş įʼnşŧęäđ őƒ ūşęřş ŧő ęäşę äđmįʼnįşŧřäŧįőʼn. <2>Ŀęäřʼn mőřę", - "title": "Ÿőū ĥävęʼn'ŧ čřęäŧęđ äʼny ŧęämş yęŧ" - } - }, - "theme-preview": { - "breadcrumbs": { - "dashboards": "Đäşĥþőäřđş", - "home": "Ħőmę" - }, - "panel": { - "form-label": "Főřm ľäþęľ", - "title": "Päʼnęľ" - } - }, - "time-picker": { - "absolute": { - "recent-title": "Ŗęčęʼnŧľy ūşęđ äþşőľūŧę řäʼnģęş", - "title": "Åþşőľūŧę ŧįmę řäʼnģę" - }, - "calendar": { - "apply-button": "Åppľy ŧįmę řäʼnģę", - "cancel-button": "Cäʼnčęľ", - "close": "Cľőşę čäľęʼnđäř", - "next-month": "Ńęχŧ mőʼnŧĥ", - "previous-month": "Přęvįőūş mőʼnŧĥ", - "select-time": "Ŝęľęčŧ ä ŧįmę řäʼnģę" - }, - "content": { - "empty-recent-list-docs": "<0><0>Ŗęäđ ŧĥę đőčūmęʼnŧäŧįőʼn<1> ŧő ƒįʼnđ őūŧ mőřę äþőūŧ ĥőŵ ŧő ęʼnŧęř čūşŧőm ŧįmę řäʼnģęş.", - "empty-recent-list-info": "Ĩŧ ľőőĸş ľįĸę yőū ĥävęʼn'ŧ ūşęđ ŧĥįş ŧįmę pįčĸęř þęƒőřę. Åş şőőʼn äş yőū ęʼnŧęř şőmę ŧįmę įʼnŧęřväľş, řęčęʼnŧľy ūşęđ įʼnŧęřväľş ŵįľľ äppęäř ĥęřę.", - "filter-placeholder": "Ŝęäřčĥ qūįčĸ řäʼnģęş" - }, - "copy-paste": { - "copy-success-message": "Ŧįmę řäʼnģę čőpįęđ ŧő čľįpþőäřđ", - "default-error-message": "{{error}} įş ʼnőŧ ä väľįđ ŧįmę řäʼnģę", - "default-error-title": "Ĩʼnväľįđ ŧįmę řäʼnģę", - "tooltip-copy": "Cőpy ŧįmę řäʼnģę ŧő čľįpþőäřđ", - "tooltip-paste": "Päşŧę ŧįmę řäʼnģę" - }, - "footer": { - "change-settings-button": "Cĥäʼnģę ŧįmę şęŧŧįʼnģş", - "fiscal-year-option": "Fįşčäľ yęäř", - "fiscal-year-start": "Fįşčäľ yęäř şŧäřŧ mőʼnŧĥ", - "time-zone-option": "Ŧįmę žőʼnę", - "time-zone-selection": "Ŧįmę žőʼnę şęľęčŧįőʼn" - }, - "range-content": { - "apply-button": "Åppľy ŧįmę řäʼnģę", - "default-error": "Pľęäşę ęʼnŧęř ä päşŧ đäŧę őř \"ʼnőŵ\"", - "fiscal-year": "Fįşčäľ yęäř", - "from-input": "Fřőm", - "open-input-calendar": "Øpęʼn čäľęʼnđäř", - "range-error": "\"Fřőm\" čäʼn'ŧ þę äƒŧęř \"Ŧő\"", - "to-input": "Ŧő" - }, - "range-picker": { - "backwards-time-aria-label": "Mővę ŧįmę řäʼnģę þäčĸŵäřđş", - "current-time-selected": "Ŧįmę řäʼnģę şęľęčŧęđ: {{currentTimeRange}}", - "forwards-time-aria-label": "Mővę ŧįmę řäʼnģę ƒőřŵäřđş", - "to": "ŧő", - "zoom-out-button": "Żőőm őūŧ ŧįmę řäʼnģę", - "zoom-out-tooltip": "Ŧįmę řäʼnģę žőőm őūŧ <1> CŦŖĿ+Ż" - }, - "time-range": { - "apply": "Åppľy ŧįmę řäʼnģę", - "aria-role": "Ŧįmę řäʼnģę şęľęčŧįőʼn", - "default-title": "Ŧįmę řäʼnģęş", - "example": "Ēχämpľę: ŧő şęľęčŧ ä ŧįmę řäʼnģę ƒřőm 10 mįʼnūŧęş äģő ŧő ʼnőŵ", - "example-details": "Fřőm: ʼnőŵ-10m Ŧő: ʼnőŵ", - "example-title": "Ēχämpľę ŧįmę řäʼnģęş", - "from-label": "Fřőm", - "from-to": "{{timeOptionFrom}} ŧő {{timeOptionTo}}", - "more-info": "Főř mőřę įʼnƒőřmäŧįőʼn şęę <2>đőčş <1>.", - "specify": "Ŝpęčįƒy ŧįmę řäʼnģę <1>", - "submit-button-label": "ŦįmęPįčĸęř şūþmįŧ þūŧŧőʼn", - "supported-formats": "Ŝūppőřŧęđ ƒőřmäŧş: <1>ʼnőŵ-[đįģįŧ]ş/m/ĥ/đ/ŵ", - "to-label": "Ŧő" - }, - "zone": { - "select-aria-label": "Ŧįmę žőʼnę pįčĸęř", - "select-search-input": "Ŧypę ŧő şęäřčĥ (čőūʼnŧřy, čįŧy, äþþřęvįäŧįőʼn)" - } - }, - "trails": { - "bookmarks": { - "or-view-bookmarks": "Øř vįęŵ þőőĸmäřĸş" - }, - "card": { - "date-created": "Đäŧę čřęäŧęđ: " - }, - "home": { - "learn-more": "Ŀęäřʼn mőřę", - "lets-start": "Ŀęŧ'ş şŧäřŧ!", - "start-your-metrics-exploration": "Ŝŧäřŧ yőūř męŧřįčş ęχpľőřäŧįőʼn!", - "subtitle": "Ēχpľőřę yőūř Přőmęŧĥęūş-čőmpäŧįþľę męŧřįčş ŵįŧĥőūŧ ŵřįŧįʼnģ ä qūęřy." - }, - "metric-select": { - "filter-by": "Fįľŧęř þy", - "native-histogram": "Ńäŧįvę Ħįşŧőģřäm", - "new-badge": "Ńęŵ", - "otel-switch": "Ŧĥįş şŵįŧčĥ ęʼnäþľęş ƒįľŧęřįʼnģ þy ØŦęľ řęşőūřčęş ƒőř ØŦęľ ʼnäŧįvę đäŧä şőūřčęş." - }, - "native-histogram-banner": { - "ch-heatmap": "Cľäşşįč Ħįşŧőģřäm đįşpľäyęđ äş ĥęäŧmäp:", - "ch-histogram": "Cľäşşįč Ħįşŧőģřäm đįşpľäyęđ äş ĥįşŧőģřäm:", - "click-histogram": "Cľįčĸ äʼny őƒ ŧĥę ʼnäŧįvę ĥįşŧőģřämş þęľőŵ ŧő ęχpľőřę ŧĥęm:", - "hide-examples": "Ħįđę ęχämpľęş", - "learn-more": "Ŀęäřʼn mőřę", - "metric-examples": "", - "nh-heatmap": "Ńäŧįvę Ħįşŧőģřäm đįşpľäyęđ äş ĥęäŧmäp:", - "nh-histogram": "Ńäŧįvę Ħįşŧőģřäm đįşpľäyęđ äş ĥįşŧőģřäm:", - "now": "Ńőŵ:", - "previously": "Přęvįőūşľy:", - "see-examples": "> Ŝęę ęχämpľęş", - "sentence": "Přőmęŧĥęūş ʼnäŧįvę ĥįşŧőģřämş őƒƒęř ĥįģĥ řęşőľūŧįőʼn, ĥįģĥ přęčįşįőʼn, şįmpľę ūşäģę įʼn įʼnşŧřūmęʼnŧäŧįőʼn äʼnđ ä ŵäy ŧő čőmþįʼnę äʼnđ mäʼnįpūľäŧę ĥįşŧőģřämş įʼn qūęřįęş äʼnđ įʼn Ğřäƒäʼnä." - }, - "recent-metrics": { - "or-view-a-recent-exploration": "Øř vįęŵ ä řęčęʼnŧ ęχpľőřäŧįőʼn" - }, - "settings": { - "always-keep-selected-metric-graph-in-view": "Åľŵäyş ĸęęp şęľęčŧęđ męŧřįč ģřäpĥ įʼn-vįęŵ", - "show-previews-of-metric-graphs": "Ŝĥőŵ přęvįęŵş őƒ męŧřįč ģřäpĥş" - } - }, - "transformations": { - "empty": { - "add-transformation-body": "Ŧřäʼnşƒőřmäŧįőʼnş äľľőŵ đäŧä ŧő þę čĥäʼnģęđ įʼn väřįőūş ŵäyş þęƒőřę yőūř vįşūäľįžäŧįőʼn įş şĥőŵʼn.<1>Ŧĥįş įʼnčľūđęş ĵőįʼnįʼnģ đäŧä ŧőģęŧĥęř, řęʼnämįʼnģ ƒįęľđş, mäĸįʼnģ čäľčūľäŧįőʼnş, ƒőřmäŧŧįʼnģ đäŧä ƒőř đįşpľäy, äʼnđ mőřę.", - "add-transformation-header": "Ŝŧäřŧ ŧřäʼnşƒőřmįʼnģ đäŧä" - } - }, - "upgrade-box": { - "discovery-text": "Ÿőū’vę đįşčővęřęđ ä Přő ƒęäŧūřę!", - "discovery-text-continued": "Ğęŧ ŧĥę Ğřäƒäʼnä Přő pľäʼn ŧő äččęşş {{featureName}}.", - "get-started": "Ğęŧ şŧäřŧęđ ŵįŧĥ {{featureName}}", - "learn-more": "Ŀęäřʼn mőřę", - "upgrade-button": "Ůpģřäđę" - }, - "user-orgs": { - "current-org-button": "Cūřřęʼnŧ", - "name-column": "Ńämę", - "role-column": "Ŗőľę", - "select-org-button": "Ŝęľęčŧ őřģäʼnįşäŧįőʼn", - "title": "Øřģäʼnįžäŧįőʼnş" - }, - "user-profile": { - "fields": { - "email-error": "Ēmäįľ įş řęqūįřęđ", - "email-label": "Ēmäįľ", - "name-error": "Ńämę įş řęqūįřęđ", - "name-label": "Ńämę", - "username-label": "Ůşęřʼnämę" - }, - "tabs": { - "general": "Ğęʼnęřäľ" - } - }, - "user-session": { - "auth-module-column": "Ĩđęʼnŧįŧy Přővįđęř", - "browser-column": "ßřőŵşęř & ØŜ", - "created-at-column": "Ŀőģģęđ őʼn", - "identity-provider-column": "Ĩđęʼnŧįŧy Přővįđęř", - "ip-column": "ĨP äđđřęşş", - "revoke": "Ŗęvőĸę ūşęř şęşşįőʼn", - "seen-at-column": "Ŀäşŧ şęęʼn" - }, - "user-sessions": { - "loading": "Ŀőäđįʼnģ şęşşįőʼnş..." - }, - "users": { - "empty-state": { - "message": "Ńő ūşęřş ƒőūʼnđ" - } - }, - "users-access-list": { - "tabs": { - "public-dashboard-users-tab-title": "Pūþľįč đäşĥþőäřđ ūşęřş", - "shared-dashboard-users-tab-title": "Ŝĥäřęđ đäşĥþőäřđ ūşęřş" - } - }, - "variable": { - "adhoc": { - "placeholder": "Ŝęľęčŧ väľūę" - }, - "dropdown": { - "placeholder": "Ēʼnŧęř väřįäþľę väľūę" - }, - "picker": { - "link-all": "Åľľ", - "option-all": "Åľľ", - "option-selected-values": "Ŝęľęčŧęđ", - "option-tooltip": "Cľęäř şęľęčŧįőʼnş" - }, - "textbox": { - "placeholder": "Ēʼnŧęř väřįäþľę väľūę" - } - }, - "variables": { - "empty-state": { - "button-title": "Åđđ väřįäþľę", - "info-box-content": "Väřįäþľęş ęʼnäþľę mőřę įʼnŧęřäčŧįvę äʼnđ đyʼnämįč đäşĥþőäřđş. Ĩʼnşŧęäđ őƒ ĥäřđ-čőđįʼnģ ŧĥįʼnģş ľįĸę şęřvęř őř şęʼnşőř ʼnämęş įʼn yőūř męŧřįč qūęřįęş yőū čäʼn ūşę väřįäþľęş įʼn ŧĥęįř pľäčę. Väřįäþľęş äřę şĥőŵʼn äş ľįşŧ þőχęş äŧ ŧĥę ŧőp őƒ ŧĥę đäşĥþőäřđ. Ŧĥęşę đřőp-đőŵʼn ľįşŧş mäĸę įŧ ęäşy ŧő čĥäʼnģę ŧĥę đäŧä þęįʼnģ đįşpľäyęđ įʼn yőūř đäşĥþőäřđ.", - "info-box-content-2": "Cĥęčĸ őūŧ ŧĥę <2>Ŧęmpľäŧęş äʼnđ väřįäþľęş đőčūmęʼnŧäŧįőʼn ƒőř mőřę įʼnƒőřmäŧįőʼn.", - "title": "Ŧĥęřę äřę ʼnő väřįäþľęş äđđęđ yęŧ" - }, - "unknown-table": { - "loading": "Ŀőäđįʼnģ...", - "no-unknowns": "Ńő řęʼnämęđ őř mįşşįʼnģ väřįäþľęş ƒőūʼnđ.", - "renamed-or-missing-variables": "Ŗęʼnämęđ őř mįşşįʼnģ väřįäþľęş", - "variable": "Väřįäþľę" - } - } -} diff --git a/public/locales/pseudo.mjs b/public/locales/pseudo.mjs deleted file mode 100644 index 05f3f89626d..00000000000 --- a/public/locales/pseudo.mjs +++ /dev/null @@ -1,63 +0,0 @@ -// @ts-check -import { readFile, writeFile } from 'fs/promises'; -import { format } from 'prettier'; -import { pseudoize } from 'pseudoizer'; -import { hideBin } from 'yargs/helpers'; -import yargs from 'yargs/yargs'; - -const argv = await yargs(hideBin(process.argv)) - .option('mode', { - demandOption: true, - describe: 'Path to a template to use for each issue. See source bettererIssueTemplate.md for an example', - type: 'string', - choices: ['oss', 'enterprise', 'both'], - }) - .version(false).argv; - -const extractOSS = ['oss', 'both'].includes(argv.mode); -const extractEnterprise = ['enterprise', 'both'].includes(argv.mode); - -/** - * @param {string} key - * @param {unknown} value - */ -function pseudoizeJsonReplacer(key, value) { - if (typeof value === 'string') { - // Split string on brace-enclosed segments. Odd indices will be {{variables}} - const phraseParts = value.split(/(\{\{[^}]+}\})/g); - const translatedParts = phraseParts.map((str, index) => (index % 2 ? str : pseudoize(str))); - return translatedParts.join(''); - } - - return value; -} -/** - * @param {string} inputPath - * @param {string} outputPath - */ -async function pseudoizeJson(inputPath, outputPath) { - const baseJson = await readFile(inputPath, 'utf-8'); - const enMessages = JSON.parse(baseJson); - const pseudoJson = JSON.stringify(enMessages, pseudoizeJsonReplacer, 2); - const prettyPseudoJson = await format(pseudoJson, { - parser: 'json', - }); - - await writeFile(outputPath, prettyPseudoJson); - console.log('Wrote', outputPath); -} - -// -// OSS translations -if (extractOSS) { - await pseudoizeJson('./public/locales/en-US/grafana.json', './public/locales/pseudo-LOCALE/grafana.json'); -} - -// -// Enterprise translations -if (extractEnterprise) { - await pseudoizeJson( - './public/app/extensions/locales/en-US/grafana-enterprise.json', - './public/app/extensions/locales/pseudo-LOCALE/grafana-enterprise.json' - ); -} diff --git a/yarn.lock b/yarn.lock index 369c4f29a57..a9474b2c206 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18246,6 +18246,7 @@ __metadata: i18next: "npm:^24.0.0" i18next-browser-languagedetector: "npm:^8.0.0" i18next-parser: "npm:9.3.0" + i18next-pseudo: "npm:^2.2.1" immer: "npm:10.1.1" immutable: "npm:5.0.3" ini: "npm:^5.0.0" @@ -18301,7 +18302,6 @@ __metadata: postcss-scss: "npm:4.0.9" prettier: "npm:3.4.2" prismjs: "npm:1.29.0" - pseudoizer: "npm:^0.1.0" rc-slider: "npm:11.1.8" rc-tree: "npm:5.13.0" re-resizable: "npm:6.10.3" @@ -19118,6 +19118,24 @@ __metadata: languageName: node linkType: hard +"i18next-pseudo@npm:^2.2.1": + version: 2.2.1 + resolution: "i18next-pseudo@npm:2.2.1" + dependencies: + i18next: "npm:^19.1.0" + checksum: 10/4eeec03540c6e9bb823b804cffcb2b95555b0a1d185e0287c74d2deaf7e6bfa206b0223d69db4fbe7b90c66faba451737b06151c85708afd2c5e9502adf817b2 + languageName: node + linkType: hard + +"i18next@npm:^19.1.0": + version: 19.9.2 + resolution: "i18next@npm:19.9.2" + dependencies: + "@babel/runtime": "npm:^7.12.0" + checksum: 10/a3b8da898edf74257984821b8eaf11929db4cab2c123dadad05c641af98bfcf94ddddee951d091e45f6f7510db47294f4d67134906b1dd82f144f01534153710 + languageName: node + linkType: hard + "i18next@npm:^23.0.0, i18next@npm:^23.11.5": version: 23.16.8 resolution: "i18next@npm:23.16.8" @@ -25369,13 +25387,6 @@ __metadata: languageName: node linkType: hard -"pseudoizer@npm:^0.1.0": - version: 0.1.0 - resolution: "pseudoizer@npm:0.1.0" - checksum: 10/fd3fa95ea4f330f268cad2388f3829e4c29249e7ffea970467b9123f1ef2a81334e92425c5cad0c72ab04c320203501b65ae86aa8d88320b63e0e75e944c6e76 - languageName: node - linkType: hard - "psl@npm:^1.1.33": version: 1.9.0 resolution: "psl@npm:1.9.0" From 98e4d57bcd1344b9392a6d9e68653c0a1177c95b Mon Sep 17 00:00:00 2001 From: Ed Poole Date: Mon, 10 Mar 2025 12:09:48 +0000 Subject: [PATCH 03/63] GrafanaUI: Add external border radius mixin (#100266) * Add external border radius mixin * Add getInternalRadius mixin for inverse use case * Update border radius fns with clearler types and JSDoc annotations * tidy up interface, apply correctly in radio buttons, add internal story * connect padding/offset in radiobuttongroup/radiobutton * split out offset into its own param --------- Co-authored-by: Ashley Harrison --- .../Forms/RadioButtonGroup/RadioButton.tsx | 5 +- .../RadioButtonGroup/RadioButtonGroup.tsx | 5 +- .../BorderRadius.internal.story.tsx | 46 ++++++++++ .../components/ThemeDemos/BorderRadius.tsx | 87 +++++++++++++++++++ packages/grafana-ui/src/themes/mixins.ts | 52 +++++++++++ 5 files changed, 190 insertions(+), 5 deletions(-) create mode 100644 packages/grafana-ui/src/components/ThemeDemos/BorderRadius.internal.story.tsx create mode 100644 packages/grafana-ui/src/components/ThemeDemos/BorderRadius.tsx diff --git a/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButton.tsx b/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButton.tsx index 898247dff7d..92f1c0d494e 100644 --- a/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButton.tsx +++ b/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButton.tsx @@ -5,10 +5,11 @@ import { GrafanaTheme2 } from '@grafana/data'; import { StringSelector, selectors } from '@grafana/e2e-selectors'; import { useStyles2 } from '../../../themes'; -import { getFocusStyles, getMouseFocusStyles } from '../../../themes/mixins'; +import { getFocusStyles, getInternalRadius, getMouseFocusStyles } from '../../../themes/mixins'; import { Tooltip } from '../../Tooltip/Tooltip'; import { getPropertiesForButtonSize } from '../commonStyles'; +export const RADIO_GROUP_PADDING = 2; export type RadioButtonSize = 'sm' | 'md'; export interface RadioButtonProps { @@ -130,7 +131,7 @@ const getRadioButtonStyles = (theme: GrafanaTheme2, size: RadioButtonSize, fullW lineHeight: `${labelHeight}px`, color: textColor, padding: theme.spacing(0, padding), - borderRadius: theme.shape.radius.default, + borderRadius: getInternalRadius(theme, RADIO_GROUP_PADDING), background: theme.colors.background.primary, cursor: 'pointer', userSelect: 'none', diff --git a/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.tsx b/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.tsx index 2cd47626db9..d615ca4d696 100644 --- a/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.tsx +++ b/packages/grafana-ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup.tsx @@ -7,8 +7,7 @@ import { GrafanaTheme2, SelectableValue, toIconName } from '@grafana/data'; import { useStyles2 } from '../../../themes'; import { Icon } from '../../Icon/Icon'; -import { RadioButtonSize, RadioButton } from './RadioButton'; - +import { RadioButtonSize, RadioButton, RADIO_GROUP_PADDING } from './RadioButton'; export interface RadioButtonGroupProps { value?: T; id?: string; @@ -119,7 +118,7 @@ const getStyles = (theme: GrafanaTheme2) => { flexWrap: 'nowrap', border: `1px solid ${theme.components.input.borderColor}`, borderRadius: theme.shape.radius.default, - padding: '2px', + padding: RADIO_GROUP_PADDING, '&:hover': { borderColor: theme.components.input.borderHover, }, diff --git a/packages/grafana-ui/src/components/ThemeDemos/BorderRadius.internal.story.tsx b/packages/grafana-ui/src/components/ThemeDemos/BorderRadius.internal.story.tsx new file mode 100644 index 00000000000..c938199176c --- /dev/null +++ b/packages/grafana-ui/src/components/ThemeDemos/BorderRadius.internal.story.tsx @@ -0,0 +1,46 @@ +import { Meta, StoryFn } from '@storybook/react'; + +import { BorderRadiusContainer } from './BorderRadius'; + +const meta: Meta = { + title: 'Docs Overview/Theme', + component: BorderRadiusContainer, + decorators: [], + parameters: { + layout: 'centered', + }, + args: { + referenceBorderRadius: 20, + referenceBorderWidth: 10, + offset: 0, + borderWidth: 2, + }, + argTypes: { + offset: { + control: { + min: 0, + }, + }, + referenceBorderRadius: { + control: { + min: 0, + }, + }, + referenceBorderWidth: { + control: { + min: 0, + }, + }, + borderWidth: { + control: { + min: 0, + }, + }, + }, +}; + +export const OffsetBorderRadius: StoryFn = (args) => { + return ; +}; + +export default meta; diff --git a/packages/grafana-ui/src/components/ThemeDemos/BorderRadius.tsx b/packages/grafana-ui/src/components/ThemeDemos/BorderRadius.tsx new file mode 100644 index 00000000000..7419ae28fe6 --- /dev/null +++ b/packages/grafana-ui/src/components/ThemeDemos/BorderRadius.tsx @@ -0,0 +1,87 @@ +import { css } from '@emotion/css'; + +import { GrafanaTheme2 } from '@grafana/data'; + +import { useStyles2 } from '../../themes'; +import { getInternalRadius, getExternalRadius } from '../../themes/mixins'; +import { Stack } from '../Layout/Stack/Stack'; +import { Text } from '../Text/Text'; + +interface DemoBoxProps { + referenceBorderRadius: number; + referenceBorderWidth: number; + offset: number; + borderWidth: number; +} + +export const BorderRadiusContainer = ({ + referenceBorderRadius, + referenceBorderWidth, + offset, + borderWidth, +}: DemoBoxProps) => { + const styles = useStyles2(getStyles, referenceBorderRadius, referenceBorderWidth, offset, borderWidth); + return ( + + + {/* eslint-disable-next-line @grafana/no-untranslated-strings */} + getInternalRadius +
+
+
+ + + {/* eslint-disable-next-line @grafana/no-untranslated-strings */} + getExternalRadius +
+
+
+ + + ); +}; + +const getStyles = ( + theme: GrafanaTheme2, + referenceBorderRadius: number, + referenceBorderWidth: number, + offset: number, + borderWidth: number +) => ({ + baseForInternal: css({ + backgroundColor: theme.colors.action.disabledBackground, + border: `${referenceBorderWidth}px dashed ${theme.colors.action.disabledText}`, + borderRadius: referenceBorderRadius, + display: 'flex', + height: '80px', + padding: offset, + width: '300px', + }), + baseForExternal: css({ + backgroundColor: theme.colors.action.disabledBackground, + border: `${referenceBorderWidth}px dashed ${theme.colors.action.disabledText}`, + borderRadius: referenceBorderRadius, + height: '80px', + flex: 1, + width: '300px', + }), + internalContainer: css({ + backgroundColor: theme.colors.background.primary, + border: `${borderWidth}px solid ${theme.colors.primary.main}`, + borderRadius: getInternalRadius(theme, offset, { + parentBorderRadius: referenceBorderRadius, + parentBorderWidth: referenceBorderWidth, + }), + flex: 1, + }), + externalContainer: css({ + border: `${borderWidth}px solid ${theme.colors.primary.main}`, + borderRadius: getExternalRadius(theme, offset, { + childBorderRadius: referenceBorderRadius, + selfBorderWidth: borderWidth, + }), + display: 'flex', + flex: 1, + padding: offset, + }), +}); diff --git a/packages/grafana-ui/src/themes/mixins.ts b/packages/grafana-ui/src/themes/mixins.ts index 7e9e42179b0..5127047ada0 100644 --- a/packages/grafana-ui/src/themes/mixins.ts +++ b/packages/grafana-ui/src/themes/mixins.ts @@ -82,3 +82,55 @@ export const getTooltipContainerStyles = (theme: GrafanaTheme2) => ({ borderRadius: theme.shape.radius.default, zIndex: theme.zIndex.tooltip, }); + +interface ExternalRadiusAdditionalOptions { + selfBorderWidth?: number; + childBorderRadius?: number; +} +/** + * Calculates a border radius for an element, based on border radius of its child. + * + * @param theme + * @param offset - The distance to offset from the child element, should be >= 0. + * @param additionalOptions + * @param additionalOptions.selfBorderWidth - The border width of the element itself (default: 1) + * @param additionalOptions.childBorderRadius - The border radius of the child element (default: theme default radius) + * @returns A CSS calc() expression that returns the relative external radius value + */ +export const getExternalRadius = ( + theme: GrafanaTheme2, + offset: number, + additionalOptions: ExternalRadiusAdditionalOptions = {} +) => { + const { selfBorderWidth = 1, childBorderRadius } = additionalOptions; + + const childBorderRadiusPx = childBorderRadius !== undefined ? `${childBorderRadius}px` : theme.shape.radius.default; + return `calc(max(0px, ${childBorderRadiusPx} + ${offset}px + ${selfBorderWidth}px))`; +}; + +interface InternalRadiusAdditionalOptions { + parentBorderWidth?: number; + parentBorderRadius?: number; +} + +/** + * Calculates a border radius for an element, based on border radius of its parent. + * + * @param theme + * @param offset - The distance to offset from the parent element, should be >= 0. + * @param additionalOptions + * @param additionalOptions.parentBorderWidth - The border width of the parent element (default: 1) + * @param additionalOptions.parentBorderRadius - The border radius of the parent element (default: theme default radius) + * @returns A CSS calc() expression that returns the relative internal radius value + */ +export const getInternalRadius = ( + theme: GrafanaTheme2, + offset: number, + additionalOptions: InternalRadiusAdditionalOptions = {} +) => { + const { parentBorderWidth = 1, parentBorderRadius } = additionalOptions; + + const parentBorderRadiusPx = + parentBorderRadius !== undefined ? `${parentBorderRadius}px` : theme.shape.radius.default; + return `calc(max(0px, ${parentBorderRadiusPx} - ${offset}px - ${parentBorderWidth}px))`; +}; From f020aae783d2b3b23b8507a514c05d8017a6a53f Mon Sep 17 00:00:00 2001 From: Will Assis <35489495+gassiss@users.noreply.github.com> Date: Mon, 10 Mar 2025 09:11:02 -0300 Subject: [PATCH 04/63] fix(unified-storage): use explicit nil where applicable in dualwrite package (#101783) use explicit nil where applicable in dualwrite package --- pkg/storage/legacysql/dualwrite/dualwriter.go | 34 ++++++++++--------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/pkg/storage/legacysql/dualwrite/dualwriter.go b/pkg/storage/legacysql/dualwrite/dualwriter.go index 7523d549e59..b2389d3d8b6 100644 --- a/pkg/storage/legacysql/dualwrite/dualwriter.go +++ b/pkg/storage/legacysql/dualwrite/dualwriter.go @@ -82,13 +82,13 @@ func (d *dualWriter) Create(ctx context.Context, in runtime.Object, createValida createdFromLegacy, err := d.legacy.Create(ctx, in, createValidation, options) if err != nil { log.Error("unable to create object in legacy storage", "err", err) - return createdFromLegacy, err + return nil, err } createdCopy := createdFromLegacy.DeepCopyObject() accCreated, err := meta.Accessor(createdCopy) if err != nil { - return createdFromLegacy, err + return nil, err } accCreated.SetResourceVersion("") accCreated.SetUID("") @@ -105,13 +105,13 @@ func (d *dualWriter) Create(ctx context.Context, in runtime.Object, createValida if err != nil { log.Error("unable to cleanup object in legacy storage", "err", err) } - return storageObj, errObjectSt + return nil, errObjectSt } if d.readUnified { - return storageObj, errObjectSt + return storageObj, nil } - return createdFromLegacy, err + return createdFromLegacy, nil } func (d *dualWriter) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { @@ -123,19 +123,19 @@ func (d *dualWriter) Delete(ctx context.Context, name string, deleteValidation r // as they would not be able to see the object in unistore anymore. objFromLegacy, asyncLegacy, err := d.legacy.Delete(ctx, name, deleteValidation, options) if err != nil && (!d.readUnified || !d.errorIsOK && !apierrors.IsNotFound(err)) { - return objFromLegacy, asyncLegacy, err + return nil, false, err } objFromStorage, asyncStorage, err := d.unified.Delete(ctx, name, deleteValidation, options) - if err != nil && apierrors.IsNotFound(err) || d.errorIsOK { - err = nil // clear the error + if err != nil && !apierrors.IsNotFound(err) && !d.errorIsOK { + return nil, false, err } if d.readUnified { - return objFromStorage, asyncStorage, err + return objFromStorage, asyncStorage, nil } - return objFromLegacy, asyncLegacy, err + return objFromLegacy, asyncLegacy, nil } // Update overrides the behavior of the generic DualWriter and writes first to Storage and then to LegacyStorage. @@ -155,7 +155,7 @@ func (d *dualWriter) Update(ctx context.Context, name string, objInfo rest.Updat objFromLegacy, createdLegacy, err := d.legacy.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) if err != nil { log.With("object", objFromLegacy).Error("could not update in legacy storage", "err", err) - return objFromLegacy, createdLegacy, err + return nil, false, err } objFromStorage, created, err := d.unified.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) @@ -164,13 +164,14 @@ func (d *dualWriter) Update(ctx context.Context, name string, objInfo rest.Updat if d.errorIsOK { return objFromLegacy, createdLegacy, nil } + return nil, false, err } if d.readUnified { - return objFromStorage, created, err + return objFromStorage, created, nil } - return objFromLegacy, createdLegacy, err + return objFromLegacy, createdLegacy, nil } // DeleteCollection overrides the behavior of the generic DualWriter and deletes from both LegacyStorage and Storage. @@ -186,7 +187,7 @@ func (d *dualWriter) DeleteCollection(ctx context.Context, deleteValidation rest deletedLegacy, err := d.legacy.DeleteCollection(ctx, deleteValidation, options, listOptions) if err != nil { log.With("deleted", deletedLegacy).Error("failed to delete collection successfully from legacy storage", "err", err) - return deletedLegacy, err + return nil, err } deletedStorage, err := d.unified.DeleteCollection(ctx, deleteValidation, options, listOptions) @@ -195,13 +196,14 @@ func (d *dualWriter) DeleteCollection(ctx context.Context, deleteValidation rest if d.errorIsOK { return deletedLegacy, nil } + return nil, err } if d.readUnified { - return deletedStorage, err + return deletedStorage, nil } - return deletedLegacy, err + return deletedLegacy, nil } func (d *dualWriter) Destroy() { From 774e565b09d0f80a4af73a7edc76281141a68587 Mon Sep 17 00:00:00 2001 From: Haris Rozajac <58232930+harisrozajac@users.noreply.github.com> Date: Mon, 10 Mar 2025 06:25:46 -0600 Subject: [PATCH 05/63] Dashboard Schema V2: Use the right version of transformer when detecting changes (#101850) use right version of transformer --- .../dashboard-scene/saving/DashboardSceneChangeTracker.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/public/app/features/dashboard-scene/saving/DashboardSceneChangeTracker.ts b/public/app/features/dashboard-scene/saving/DashboardSceneChangeTracker.ts index a76bb30de7b..2bfdb9b8646 100644 --- a/public/app/features/dashboard-scene/saving/DashboardSceneChangeTracker.ts +++ b/public/app/features/dashboard-scene/saving/DashboardSceneChangeTracker.ts @@ -22,7 +22,6 @@ import { LibraryPanelBehavior } from '../scene/LibraryPanelBehavior'; import { VizPanelLinks } from '../scene/PanelLinks'; import { PanelTimeRange } from '../scene/PanelTimeRange'; import { DashboardGridItem } from '../scene/layout-default/DashboardGridItem'; -import { transformSceneToSaveModel } from '../serialization/transformSceneToSaveModel'; import { isSceneVariableInstance } from '../settings/variables/utils'; import { DashboardChangeInfo } from './shared'; @@ -122,7 +121,7 @@ export class DashboardSceneChangeTracker { } private detectSaveModelChanges() { - const changedDashboard = transformSceneToSaveModel(this._dashboard); + const changedDashboard = this._dashboard.getSaveModel(); const initialDashboard = this._dashboard.getInitialSaveModel(); // Objects must be stringify to ensure they are clonable, so they don't contain functions From 768943bd75720885288c36b7a5bcd37061784aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 10 Mar 2025 13:26:00 +0100 Subject: [PATCH 06/63] Dashboard: Fixes issue with tabs with rows and default grid (#101865) --- .../layout-tabs/TabsLayoutManagerRenderer.tsx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManagerRenderer.tsx b/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManagerRenderer.tsx index 375f2f779ff..8a9e5a6a8f6 100644 --- a/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManagerRenderer.tsx +++ b/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManagerRenderer.tsx @@ -19,8 +19,8 @@ export function TabsLayoutManagerRenderer({ model }: SceneComponentProps - +
+
{tabs.map((tab) => ( @@ -35,12 +35,17 @@ export function TabsLayoutManagerRenderer({ model }: SceneComponentProps {currentTab && } - +
); } const getStyles = (theme: GrafanaTheme2) => ({ - tabsWrapper: css({ + tabLayoutContainer: css({ + display: 'flex', + flexDirection: 'column', + flex: '1 1 auto', + }), + tabsBar: css({ overflow: 'hidden', }), tabsRow: css({ @@ -60,9 +65,7 @@ const getStyles = (theme: GrafanaTheme2) => ({ backgroundColor: 'transparent', display: 'flex', flex: 1, - height: '100%', - overflow: 'auto', - scrollbarWidth: 'thin', + minHeight: 0, padding: '2px 2px 0 2px', }), }); From cf60c4e77f3047bb7bc6d3698b0df7894aad199b Mon Sep 17 00:00:00 2001 From: Beverly Buchanan <131809838+BeverlyJaneJ@users.noreply.github.com> Date: Mon, 10 Mar 2025 09:04:27 -0400 Subject: [PATCH 07/63] Update SAML configuration steps (#101663) * replace relrefs and minor edits * add new content and links * Update docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md Co-authored-by: Misi * Update docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md Co-authored-by: Misi * changes from linter and content suggestions * Update docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md Co-authored-by: Misi * Update docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md Co-authored-by: Misi * Update docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md Co-authored-by: Misi * Update docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md Co-authored-by: Misi * run prettier --------- Co-authored-by: Misi Co-authored-by: Irene Rodriguez --- .../configure-authentication/saml/index.md | 120 ++++++++++-------- 1 file changed, 67 insertions(+), 53 deletions(-) diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md index 28ac28100d3..a04761c8b13 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md @@ -22,23 +22,23 @@ weight: 500 # Configure SAML authentication using the configuration file {{% admonition type="note" %}} -Available in [Grafana Enterprise](../../../../introduction/grafana-enterprise/) and [Grafana Cloud](/docs/grafana-cloud). +Available in [Grafana Enterprise](/docs/grafana//introduction/grafana-enterprise/) and [Grafana Cloud](/docs/grafana-cloud). {{% /admonition %}} SAML authentication integration allows your Grafana users to log in by using an external SAML 2.0 Identity Provider (IdP). To enable this, Grafana becomes a Service Provider (SP) in the authentication flow, interacting with the IdP to exchange user information. You can configure SAML authentication in Grafana through one of the following methods: -- the Grafana configuration file -- the API (refer to [SSO Settings API](../../../../developers/http_api/sso-settings/)) -- the user interface (refer to [Configure SAML authentication using the Grafana user interface](../saml-ui/)) -- the Terraform provider (refer to [Terraform docs](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/sso_settings)) +- The Grafana configuration file +- The API (refer to [SSO Settings API](/docs/grafana//developers/http_api/sso-settings/) +- The user interface (refer to [Configure SAML authentication using the Grafana user interface](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/saml-ui/) +- The Terraform provider (refer to [Terraform docs](https://registry.terraform.io/providers/grafana/grafana//docs/resources/sso_settings)) {{% admonition type="note" %}} The API and Terraform support are available in Public Preview in Grafana v11.1 behind the `ssoSettingsSAML` feature toggle. You must also enable the `ssoSettingsApi` flag. {{% /admonition %}} -All methods offer the same configuration options, but you might prefer using the Grafana configuration file or the Terraform provider if you want to keep all of Grafana's authentication settings in one place. Grafana Cloud users do not have access to Grafana configuration file, so they should configure SAML through the other methods. +All methods offer the same configuration options. However, if you want to keep all of Grafana authentication settings in one place, use the Grafana configuration file or the Terraform provider. If you are a Grafana Cloud user, you do not have access to Grafana configuration file. Instead, configure SAML through the other methods. {{% admonition type="note" %}} Configuration in the API takes precedence over the configuration in the Grafana configuration file. SAML settings from the API will override any SAML configuration set in the Grafana configuration file. @@ -46,6 +46,10 @@ Configuration in the API takes precedence over the configuration in the Grafana ## Supported SAML +The following indicate what Grafana supports. + +### Bindings + Grafana supports the following SAML 2.0 bindings: - From the Service Provider (SP) to the Identity Provider (IdP): @@ -56,12 +60,13 @@ Grafana supports the following SAML 2.0 bindings: - From the Identity Provider (IdP) to the Service Provider (SP): - `HTTP-POST` binding -In terms of security: +### Security -- Grafana supports signed and encrypted assertions. -- Grafana does not support signed or encrypted requests. +Grafana supports signed and encrypted assertions, and does _not_ support encrypted requests. -In terms of initiation, Grafana supports: +### Initiation + +Grafana supports: - SP-initiated requests - IdP-initiated requests @@ -71,7 +76,7 @@ By default, SP-initiated requests are enabled. For instructions on how to enable {{% admonition type="note" %}} It is possible to set up Grafana with SAML authentication using Azure AD. However, if an Azure AD user belongs to more than 150 groups, a Graph API endpoint is shared instead. -Grafana versions 11.1 and below, do not support fetching the groups from the Graph API endpoint. As a result, users with more than 150 groups will not be able to retrieve their groups. Instead, it is recommended that you use OIDC/OAuth workflows,. +Grafana versions 11.1 and below, do not support fetching the groups from the Graph API endpoint. As a result, users with more than 150 groups will not be able to retrieve their groups. Instead, it is recommended that you use OIDC/OAuth workflows. As of Grafana 11.2, the SAML integration offers a mechanism to retrieve user groups from the Graph API. @@ -84,16 +89,16 @@ Related links: ### Edit SAML options in the Grafana config file -1. In the `[auth.saml]` section in the Grafana configuration file, set [`enabled`](../../../configure-grafana/enterprise-configuration/#enabled) to `true`. -1. Configure the [certificate and private key](#certificate-and-private-key). +1. In the `[auth.saml]` section in the Grafana configuration file, set [`enabled`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#enabled-3) to `true`. +1. Optionally, configure the [certificate and private key](#certificate-and-private-key"). 1. On the Okta application page where you have been redirected after application created, navigate to the **Sign On** tab and find **Identity Provider metadata** link in the **Settings** section. -1. Set the [`idp_metadata_url`](../../../configure-grafana/enterprise-configuration/#idp_metadata_url) to the URL obtained from the previous step. The URL should look like `https://.okta.com/app//sso/saml/metadata`. +1. Set the [`idp_metadata_url`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#idp_metadata_url) to the URL obtained from the previous step. The URL should look like `https://.okta.com/app//sso/saml/metadata`. 1. Set the following options to the attribute names configured at the **step 10** of the SAML integration setup. You can find this attributes on the **General** tab of the application page (**ATTRIBUTE STATEMENTS** and **GROUP ATTRIBUTE STATEMENTS** in the **SAML Settings** section). - - [`assertion_attribute_login`](../../../configure-grafana/enterprise-configuration/#assertion_attribute_login) - - [`assertion_attribute_email`](../../../configure-grafana/enterprise-configuration/#assertion_attribute_email) - - [`assertion_attribute_name`](../../../configure-grafana/enterprise-configuration/#assertion_attribute_name) - - [`assertion_attribute_groups`](../../../configure-grafana/enterprise-configuration/#assertion_attribute_groups) -1. (Optional) Set the `name` parameter in the `[auth.saml]` section in the Grafana configuration file. This parameter replaces SAML in the Grafana user interface in locations such as the sign-in button. + - [`assertion_attribute_login`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_login) + - [`assertion_attribute_email`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_email) + - [`assertion_attribute_name`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_name) + - [`assertion_attribute_groups`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_groups) +1. Optionally, set the `name` parameter in the `[auth.saml]` section in the Grafana configuration file. This parameter replaces SAML in the Grafana user interface in locations such as the sign-in button. 1. Save the configuration file and then restart the Grafana server. When you are finished, the Grafana configuration might look like this example: @@ -119,7 +124,7 @@ assertion_attribute_groups = Group To use the SAML integration, in the `auth.saml` section of in the Grafana custom configuration file, set `enabled` to `true`. -Refer to [Configuration](../../../configure-grafana/) for more information about configuring Grafana. +Refer to [Configuration](/docs/grafana//setup-grafana/configure-grafana/) for more information about configuring Grafana. ## Additional configuration for HTTP-Post binding @@ -133,9 +138,11 @@ For Grafana Cloud instances, please contact Grafana Support to update the `conte ## Certificate and private key +Commonly, the certificate and key are embedded in the [IDP metadata](#configure-the-saml-toolkit-application-endpoints) and refreshed as needed by Grafana automatically. However, if your IdP expects signed requests, you must supply a certificate and private key. + The SAML SSO standard uses asymmetric encryption to exchange information between the SP (Grafana) and the IdP. To perform such encryption, you need a public part and a private part. In this case, the X.509 certificate provides the public part, while the private key provides the private part. The private key needs to be issued in a [PKCS#8](https://en.wikipedia.org/wiki/PKCS_8) format. -Grafana supports two ways of specifying both the `certificate` and `private_key`. +If you are directly supplying the certificate and key, Grafana supports two ways of specifying both the `certificate` and `private_key`: - Without a suffix (`certificate` or `private_key`), the configuration assumes you've supplied the base64-encoded file contents. - With the `_path` suffix (`certificate_path` or `private_key_path`), then Grafana treats the value entered as a file path and attempts to read the file from the file system. @@ -144,9 +151,9 @@ Grafana supports two ways of specifying both the `certificate` and `private_key` You can only use one form of each configuration option. Using multiple forms, such as both `certificate` and `certificate_path`, results in an error. {{% /admonition %}} ---- +Always work with your company's security team on setting up certificates and private keys. If you need to generate them yourself (such as in the short term, for testing purposes, and so on), use the following example to generate your certificate and private key, including the step of ensuring that the key is generated with the [PKCS#8](https://en.wikipedia.org/wiki/PKCS_8) format. -### Generate private key for SAML authentication: +### Example of private key generation for SAML authentication An example of how to generate a self-signed certificate and private key that's valid for one year: @@ -154,7 +161,15 @@ An example of how to generate a self-signed certificate and private key that's v $ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes​ ``` -The generated `key.pem` and `cert.pem` files are then used for certificate and private_key. +Base64-encode the cert.pem and key.pem files: +(-w0 switch is not needed on Mac, only for Linux) + +```sh +$ base64 -i key.pem -o key.pem.base64 +$ base64 -i cert.pem -o cert.pem.base64 +``` + +The base64-encoded values (`key.pem.base64, cert.pem.base64` files) are then used for certificate and private key. The key you provide should look like: @@ -169,16 +184,15 @@ The key you provide should look like: Grafana supports user authentication through Azure AD, which is useful when you want users to access Grafana using single sign-on. This topic shows you how to configure SAML authentication in Grafana with [Azure AD](https://azure.microsoft.com/en-us/services/active-directory/). -**Before you begin:** +**Before you begin** -- Ensure you have permission to administer SAML authentication. For more information about roles and permissions in Grafana. - - [Roles and permissions](../../../../administration/roles-and-permissions/). -- Learn the limitations of Azure AD SAML integration. - - [Azure AD SAML limitations](https://learn.microsoft.com/en-us/entra/identity-platform/id-token-claims-reference#groups-overage-claim) -- Configure SAML integration with Azure AD, create an app integration inside the Azure AD organization first. - - [Add app integration in Azure AD](https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/add-application-portal-configure) -- If you have users that belong to more than 150 groups, you need to configure a registered application to provide an Azure Graph API to retrieve the groups. - - [Setup Azure AD Graph API applications](#set-up-saml-with-azure-ad) +Ensure you have permission to administer SAML authentication. For more information about roles and permissions in Grafana, refer to [Roles and permissions](/docs/grafana//administration/roles-and-permissions/). + +Learn the [limitations of Azure AD SAML] (https://learn.microsoft.com/en-us/entra/identity-platform/id-token-claims-reference#groups-overage-claim) integration. + +Configure SAML integration with Azure AD, [creating an Enterprise Application](#add-microsoft-entra-saml-toolkit-from-the-gallery) inside the Azure AD organization first and then [enable single sign-on](#configure-the-saml-toolkit-application-endpoints). + +If you have users that belong to more than 150 groups, configure a registered application to provide an Azure Graph API to retrieve the groups. Refer to [Setup Azure AD Graph API applications](#configure-a-graph-api-application-in-azure-ad). ### Generate self-signed certificates @@ -277,7 +291,7 @@ Grafana supports user authentication through Okta, which is useful when you want **Before you begin:** - To configure SAML integration with Okta, create an app integration inside the Okta organization first. [Add app integration in Okta](https://help.okta.com/en/prod/Content/Topics/Apps/apps-overview-add-apps.htm) -- Ensure you have permission to administer SAML authentication. For more information about roles and permissions in Grafana, refer to [Roles and permissions](../../../../administration/roles-and-permissions/). +- Ensure you have permission to administer SAML authentication. For more information about roles and permissions in Grafana, refer to [Roles and permissions](/docs/grafana//administration/roles-and-permissions/). **To set up SAML with Okta:** @@ -391,7 +405,7 @@ Additionally, Grafana did not support IdP sessions and could not include the `Se Starting from Grafana version 11.5, Grafana uses the `NameID` from the SAML assertion to create the logout request. If the `NameID` is not present in the assertion, Grafana defaults to using the user's `Login` attribute. Additionally, Grafana supports including the `SessionIndex` in the logout request if it is provided in the SAML assertion by the IdP. {{% admonition type="note" %}} -These improvements are available in public preview behind the `improvedExternalSessionHandling` feature toggle, starting from Grafana v11.5. To enable it, refer to the [Configure feature toggles](../../../configure-grafana/feature-toggles/) +These improvements are available in public preview behind the `improvedExternalSessionHandlingSAML` feature toggle, starting from Grafana v11.5. To enable it, refer to the [Configure feature toggles](/docs/grafana//setup-grafana/configure-grafana/feature-toggles/) {{% /admonition %}} ### Assertion mapping @@ -435,11 +449,11 @@ auto_login = true Group synchronization allows you to map user groups from an identity provider to Grafana teams and roles. -To use SAML group synchronization, set [`assertion_attribute_groups`](../../../configure-grafana/enterprise-configuration/#assertion_attribute_groups) to the attribute name where you store user groups. +To use SAML group synchronization, set [`assertion_attribute_groups`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_groups) to the attribute name where you store user groups. Then Grafana will use attribute values extracted from SAML assertion to add user to Grafana teams and grant them roles. {{% admonition type="note" %}} -Team sync allows you sync users from SAML to Grafana teams. It does not automatically create teams in Grafana. You need to create teams in Grafana before you can use this feature. +Team sync allows you sync users from SAML to Grafana teams, but you must create teams in Grafana before you can use this feature. It does not automatically create teams in Grafana. {{% /admonition %}} Given the following partial SAML assertion: @@ -474,22 +488,22 @@ The following `External Group ID`s would be valid for configuring team sync or r - `admins_group` - `division_1` -To learn more about how to configure group synchronization, refer to [Configure team sync](../../configure-team-sync/) and [Configure group attribute sync](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-group-attribute-sync) documentation. +To learn more about how to configure group synchronization, refer to [Configure team sync](/docs/grafana//setup-grafana/configure-security/configure-group-attribute-sync/) and [Configure group attribute sync](/docs/grafana//setup-grafana/configure-security/configure-group-attribute-sync) documentation. ### Configure role sync -Role sync allows you to map user roles from an identity provider to Grafana. To enable role sync, configure role attribute and possible values for the Editor, Admin, and Grafana Admin roles. For more information about user roles, refer to [Roles and permissions](../../../../administration/roles-and-permissions/). +Role sync allows you to map user roles from an identity provider to Grafana. To enable role sync, configure role attribute and possible values for the Editor, Admin, and Grafana Admin roles. For more information about user roles, refer to [Roles and permissions](/docs/grafana//administration/roles-and-permissions/). -1. In the configuration file, set [`assertion_attribute_role`](../../../configure-grafana/enterprise-configuration/#assertion_attribute_role) option to the attribute name where the role information will be extracted from. -1. Set the [`role_values_none`](../../../configure-grafana/enterprise-configuration/#role_values_none) option to the values mapped to the `None` role. -1. Set the [`role_values_viewer`](../../../configure-grafana/enterprise-configuration/#role_values_viewer) option to the values mapped to the `Viewer` role. -1. Set the [`role_values_editor`](../../../configure-grafana/enterprise-configuration/#role_values_editor) option to the values mapped to the `Editor` role. -1. Set the [`role_values_admin`](../../../configure-grafana/enterprise-configuration/#role_values_admin) option to the values mapped to the organization `Admin` role. -1. Set the [`role_values_grafana_admin`](../../../configure-grafana/enterprise-configuration/#role_values_grafana_admin) option to the values mapped to the `Grafana Admin` role. +1. In the configuration file, set [`assertion_attribute_role`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_role) option to the attribute name where the role information will be extracted from. +1. Set the [`role_values_none`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#role_values_none) option to the values mapped to the `None` role. +1. Set the [`role_values_viewer`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#role_values_viewer) option to the values mapped to the `Viewer` role. +1. Set the [`role_values_editor`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#role_values_editor) option to the values mapped to the `Editor` role. +1. Set the [`role_values_admin`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#role_values_admin) option to the values mapped to the organization `Admin` role. +1. Set the [`role_values_grafana_admin`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#role_values_grafana_admin) option to the values mapped to the `Grafana Admin` role. If a user role doesn't match any of configured values, then the role specified by the `auto_assign_org_role` config option will be assigned. If the `auto_assign_org_role` field is not set then the user role will default to `Viewer`. -For more information about roles and permissions in Grafana, refer to [Roles and permissions](../../../../administration/roles-and-permissions/). +For more information about roles and permissions in Grafana, refer to [Roles and permissions](/docs/grafana//administration/roles-and-permissions/). Example configuration: @@ -518,8 +532,8 @@ skip_org_role_sync = true Organization mapping allows you to assign users to particular organization in Grafana depending on attribute value obtained from identity provider. -1. In configuration file, set [`assertion_attribute_org`](../../../configure-grafana/enterprise-configuration/#assertion_attribute_org) to the attribute name you store organization info in. This attribute can be an array if you want a user to be in multiple organizations. -1. Set [`org_mapping`](../../../configure-grafana/enterprise-configuration/#org_mapping) option to the comma-separated list of `Organization:OrgId` pairs to map organization from IdP to Grafana organization specified by ID. If you want users to have different roles in multiple organizations, you can set this option to a comma-separated list of `Organization:OrgId:Role` mappings. +1. In configuration file, set [`assertion_attribute_org`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_org) to the attribute name you store organization info in. This attribute can be an array if you want a user to be in multiple organizations. +1. Set [`org_mapping`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#org_mapping) option to the comma-separated list of `Organization:OrgId` pairs to map organization from IdP to Grafana organization specified by ID. If you want users to have different roles in multiple organizations, you can set this option to a comma-separated list of `Organization:OrgId:Role` mappings. For example, use following configuration to assign users from `Engineering` organization to the Grafana organization with ID `2` as Editor and users from `Sales` - to the org with ID `3` as Admin, based on `Org` assertion attribute value: @@ -566,7 +580,7 @@ You can use `*` as the Grafana organization in the mapping if you want all users ### Configure allowed organizations -With the [`allowed_organizations`](../../../configure-grafana/enterprise-configuration/#allowed_organizations) option you can specify a list of organizations where the user must be a member of at least one of them to be able to log in to Grafana. +With the [`allowed_organizations`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#allowed_organizations) option you can specify a list of organizations where the user must be a member of at least one of them to be able to log in to Grafana. To put values containing spaces in the list, use the following JSON syntax: @@ -632,11 +646,11 @@ resource "grafana_sso_settings" "saml_sso_settings" { } ``` -Go to [Terraform Registry](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/sso_settings) for a complete reference on using the `grafana_sso_settings` resource. +Go to [Terraform Registry](https://registry.terraform.io/providers/grafana/grafana//docs/resources/sso_settings) for a complete reference on using the `grafana_sso_settings` resource. ## Troubleshoot SAML authentication in Grafana -To troubleshoot and get more log information, enable SAML debug logging in the configuration file. Refer to [Configuration](../../../configure-grafana/#filters) for more information. +To troubleshoot and get more log information, enable SAML debug logging in the configuration file. Refer to [Configuration](/docs/grafana//setup-grafana/configure-grafana/#filters) for more information. ```ini [log] @@ -692,7 +706,7 @@ The keys you provide should look like: When the user logs in using SAML and gets presented with "origin not allowed", the user might be issuing the login from an IdP (identity provider) service or the user is behind a reverse proxy. This potentially happens as Grafana's CSRF checks deem the requests to be invalid. For more information [CSRF](https://owasp.org/www-community/attacks/csrf). -To solve this issue, you can configure either the [`csrf_trusted_origins`](../../../configure-grafana/#csrf_trusted_origins) or [`csrf_additional_headers`](../../../configure-grafana/#csrf_additional_headers) option in the SAML configuration. +To solve this issue, you can configure either the [`csrf_trusted_origins`](/docs/grafana//setup-grafana/configure-grafana/#csrf_trusted_origins) or [`csrf_additional_headers`](/docs/grafana//setup-grafana/configure-grafana/#csrf_additional_headers) option in the SAML configuration. Example of a configuration file: @@ -735,7 +749,7 @@ Ensure cookie_secure is set to true to ensure that cookies are only sent over HT ## Configure SAML authentication in Grafana -The table below describes all SAML configuration options. Continue reading below for details on specific options. Like any other Grafana configuration, you can apply these options as [environment variables](../../../configure-grafana/#override-configuration-with-environment-variables). +The table below describes all SAML configuration options. Continue reading below for details on specific options. Like any other Grafana configuration, you can apply these options as [environment variables](/docs/grafana//setup-grafana/configure-grafana/#override-configuration-with-environment-variables). | Setting | Required | Description | Default | | ---------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- | From e7e0b689c2ee5caa7cc8b92b53d8440ed3f78448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Mon, 10 Mar 2025 15:03:54 +0100 Subject: [PATCH 08/63] Dashboard: Edit pane header design and refactorings (#101851) * Edit pane header * Update * Update * Progress * Progress * Update * Delete * Delete icon button * Update * Fix * remove need for arrow functions * Update * update * Update * Update * Update --- .../edit-pane/DashboardEditPane.tsx | 2 +- .../edit-pane/DashboardEditableElement.tsx | 12 +- .../edit-pane/DashboardOutline.tsx | 2 +- .../edit-pane/EditPaneHeader.tsx | 109 +++++++++++------- .../edit-pane/ElementEditPane.tsx | 40 +------ .../edit-pane/ElementSelection.ts | 78 +++++-------- .../MultiSelectedObjectsEditableElement.tsx | 42 ++----- .../MultiSelectedVizPanelsEditableElement.tsx | 29 ++--- .../edit-pane/VizPanelEditableElement.tsx | 40 ++++--- .../edit-pane/useEditableElement.ts | 3 +- .../SceneGridRowEditableElement.tsx | 16 +-- .../scene/layout-rows/RowItem.tsx | 6 +- .../scene/layout-rows/RowItemEditor.tsx | 10 +- .../scene/layout-rows/RowItems.tsx | 18 +-- .../scene/layout-rows/RowItemsEditor.tsx | 16 +-- .../scene/layout-tabs/TabItem.tsx | 6 +- .../scene/layout-tabs/TabItemEditor.tsx | 10 +- .../scene/layout-tabs/TabItems.tsx | 19 +-- .../scene/layout-tabs/TabItemsEditor.tsx | 27 ----- .../scene/types/EditableDashboardElement.ts | 37 +++--- .../MultiSelectedEditableDashboardElement.ts | 44 ------- .../PanelEditor/OptionsPaneCategory.tsx | 37 +++--- .../OptionsPaneCategoryDescriptor.tsx | 9 +- public/locales/en-US/grafana.json | 23 +--- 24 files changed, 226 insertions(+), 409 deletions(-) delete mode 100644 public/app/features/dashboard-scene/scene/layout-tabs/TabItemsEditor.tsx delete mode 100644 public/app/features/dashboard-scene/scene/types/MultiSelectedEditableDashboardElement.ts diff --git a/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx b/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx index e9c5c31e85b..cef94e5be88 100644 --- a/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx +++ b/public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx @@ -263,7 +263,7 @@ function getStyles(theme: GrafanaTheme2) { }), tabsbar: css({ padding: theme.spacing(0, 1), - margin: theme.spacing(0.5, 1), + margin: theme.spacing(0.5, 0), }), expandOptionsWrapper: css({ display: 'flex', diff --git a/public/app/features/dashboard-scene/edit-pane/DashboardEditableElement.tsx b/public/app/features/dashboard-scene/edit-pane/DashboardEditableElement.tsx index e324b09075c..7ccf14b4ff6 100644 --- a/public/app/features/dashboard-scene/edit-pane/DashboardEditableElement.tsx +++ b/public/app/features/dashboard-scene/edit-pane/DashboardEditableElement.tsx @@ -15,7 +15,11 @@ export class DashboardEditableElement implements EditableDashboardElement { public constructor(private dashboard: DashboardScene) {} public getEditableElementInfo(): EditableDashboardElementInfo { - return { typeId: 'dashboard', icon: 'apps', name: t('dashboard.edit-pane.elements.dashboard', 'Dashboard') }; + return { + typeName: t('dashboard.edit-pane.elements.dashboard', 'Dashboard'), + icon: 'apps', + instanceName: this.dashboard.state.title, + }; } public useEditPaneOptions(): OptionsPaneCategoryDescriptor[] { @@ -25,11 +29,7 @@ export class DashboardEditableElement implements EditableDashboardElement { const { body } = dashboard.useState(); const dashboardOptions = useMemo(() => { - const editPaneHeaderOptions = new OptionsPaneCategoryDescriptor({ - title: t('dashboard.options.title', 'Dashboard options'), - id: 'dashboard-options', - isOpenable: false, - }) + const editPaneHeaderOptions = new OptionsPaneCategoryDescriptor({ title: '', id: 'dashboard-options' }) .addItem( new OptionsPaneItemDescriptor({ title: t('dashboard.options.title-option', 'Title'), diff --git a/public/app/features/dashboard-scene/edit-pane/DashboardOutline.tsx b/public/app/features/dashboard-scene/edit-pane/DashboardOutline.tsx index 4f302a638fd..be3066396f4 100644 --- a/public/app/features/dashboard-scene/edit-pane/DashboardOutline.tsx +++ b/public/app/features/dashboard-scene/edit-pane/DashboardOutline.tsx @@ -65,7 +65,7 @@ function DashboardOutlineNode({ sceneObject, expandable }: { sceneObject: SceneO onPointerDown={(evt) => onSelect?.(evt)} > - {elementInfo.name} + {elementInfo.instanceName} {expandable && isExpanded && ( diff --git a/public/app/features/dashboard-scene/edit-pane/EditPaneHeader.tsx b/public/app/features/dashboard-scene/edit-pane/EditPaneHeader.tsx index 653daf384f2..5f9828c834b 100644 --- a/public/app/features/dashboard-scene/edit-pane/EditPaneHeader.tsx +++ b/public/app/features/dashboard-scene/edit-pane/EditPaneHeader.tsx @@ -1,57 +1,86 @@ -import { Dropdown, Button, IconButton, Menu, Stack, Icon } from '@grafana/ui'; +import { css } from '@emotion/css'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { Button, Menu, Stack, Text, useStyles2, ConfirmButton, Dropdown, Icon } from '@grafana/ui'; import { t } from 'app/core/internationalization'; +import { EditableDashboardElement } from '../scene/types/EditableDashboardElement'; + interface EditPaneHeaderProps { - title: string; - onDelete?: () => void; - onCopy?: () => void; - onDuplicate?: () => void; + element: EditableDashboardElement; } -export const EditPaneHeader = ({ title, onDelete, onCopy, onDuplicate }: EditPaneHeaderProps) => { - const addCopyOrDuplicate = onCopy || onDuplicate; +export function EditPaneHeader({ element }: EditPaneHeaderProps) { + const elementInfo = element.getEditableElementInfo(); + const styles = useStyles2(getStyles); + + const onCopy = element.onCopy?.bind(element); + const onDuplicate = element.onDuplicate?.bind(element); + const onDelete = element.onDelete?.bind(element); + return ( - - {title} - - {addCopyOrDuplicate ? ( - }> +
+ {elementInfo.typeName} + + {(onCopy || onDelete) && ( + + {onCopy ? ( + + ) : null} + {onDuplicate ? ( + + ) : null} + + } + > - ) : null} + )} - + {onDelete && ( + +
); -}; +} -type MenuItemsProps = { - onCopy?: () => void; - onDuplicate?: () => void; -}; - -const MenuItems = ({ onCopy, onDuplicate }: MenuItemsProps) => { - return ( - - {onCopy ? : null} - {onDuplicate ? ( - - ) : null} - - ); -}; +function getStyles(theme: GrafanaTheme2) { + return { + wrapper: css({ + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + padding: theme.spacing(2), + borderBottom: `1px solid ${theme.colors.border.weak}`, + }), + }; +} diff --git a/public/app/features/dashboard-scene/edit-pane/ElementEditPane.tsx b/public/app/features/dashboard-scene/edit-pane/ElementEditPane.tsx index 01b9a3f2398..f60b4bd7e26 100644 --- a/public/app/features/dashboard-scene/edit-pane/ElementEditPane.tsx +++ b/public/app/features/dashboard-scene/edit-pane/ElementEditPane.tsx @@ -1,50 +1,20 @@ -import { css } from '@emotion/css'; - -import { GrafanaTheme2 } from '@grafana/data'; -import { Stack, useStyles2 } from '@grafana/ui'; -import { OptionsPaneCategory } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategory'; +import { Stack } from '@grafana/ui'; import { EditableDashboardElement } from '../scene/types/EditableDashboardElement'; -import { MultiSelectedEditableDashboardElement } from '../scene/types/MultiSelectedEditableDashboardElement'; + +import { EditPaneHeader } from './EditPaneHeader'; export interface Props { - element: EditableDashboardElement | MultiSelectedEditableDashboardElement; + element: EditableDashboardElement; } export function ElementEditPane({ element }: Props) { const categories = element.useEditPaneOptions ? element.useEditPaneOptions() : []; - const styles = useStyles2(getStyles); - const elementInfo = element.getEditableElementInfo(); return ( - {element.renderActions && ( - -
{element.renderActions()}
-
- )} + {categories.map((cat) => cat.render())}
); } - -function getStyles(theme: GrafanaTheme2) { - return { - noBorderTop: css({ - borderTop: 'none', - }), - actionsBox: css({ - display: 'flex', - alignItems: 'center', - gap: theme.spacing(1), - paddingBottom: theme.spacing(1), - }), - }; -} diff --git a/public/app/features/dashboard-scene/edit-pane/ElementSelection.ts b/public/app/features/dashboard-scene/edit-pane/ElementSelection.ts index 2141781408d..0bae42a69f4 100644 --- a/public/app/features/dashboard-scene/edit-pane/ElementSelection.ts +++ b/public/app/features/dashboard-scene/edit-pane/ElementSelection.ts @@ -1,17 +1,14 @@ -import { SceneObject, SceneObjectRef, VizPanel } from '@grafana/scenes'; +import { SceneObject, SceneObjectRef } from '@grafana/scenes'; import { ElementSelectionContextItem } from '@grafana/ui'; import { isBulkActionElement } from '../scene/types/BulkActionElement'; -import { EditableDashboardElement, isEditableDashboardElement } from '../scene/types/EditableDashboardElement'; -import { MultiSelectedEditableDashboardElement } from '../scene/types/MultiSelectedEditableDashboardElement'; +import { EditableDashboardElement } from '../scene/types/EditableDashboardElement'; import { MultiSelectedObjectsEditableElement } from './MultiSelectedObjectsEditableElement'; -import { MultiSelectedVizPanelsEditableElement } from './MultiSelectedVizPanelsEditableElement'; -import { VizPanelEditableElement } from './VizPanelEditableElement'; import { getEditableElementFor } from './shared'; export class ElementSelection { - private selectedObjects?: Map>; + private selectedObjects: Map>; private sameType?: boolean; private _isMultiSelection: boolean; @@ -26,15 +23,15 @@ export class ElementSelection { } private checkSameType() { - const values = this.selectedObjects?.values(); - const firstType = values?.next().value?.resolve()?.constructor.name; + const values = this.selectedObjects.values(); + const firstType = values.next().value?.resolve().constructor.name; if (!firstType) { return false; } for (let obj of values ?? []) { - if (obj.resolve()?.constructor.name !== firstType) { + if (obj.resolve().constructor.name !== firstType) { return false; } } @@ -43,13 +40,13 @@ export class ElementSelection { } public hasValue(id: string) { - return this.selectedObjects?.has(id); + return this.selectedObjects.has(id); } public removeValue(id: string) { - this.selectedObjects?.delete(id); + this.selectedObjects.delete(id); - if (this.selectedObjects && this.selectedObjects.size < 2) { + if (this.selectedObjects.size < 2) { this.sameType = undefined; this._isMultiSelection = false; } @@ -95,11 +92,11 @@ export class ElementSelection { } public getSelectionEntries(): Array<[string, SceneObjectRef]> { - return Array.from(this.selectedObjects?.entries() ?? []); + return Array.from(this.selectedObjects.entries()); } public getFirstObject(): SceneObject | undefined { - return this.selectedObjects?.values().next().value?.resolve(); + return this.selectedObjects.values().next().value?.resolve(); } public get isMultiSelection(): boolean { @@ -107,51 +104,38 @@ export class ElementSelection { } private getSceneObjects(): SceneObject[] { - return Array.from(this.selectedObjects?.values() ?? []).map((obj) => obj.resolve()); + return Array.from(this.selectedObjects.values() ?? []).map((obj) => obj.resolve()); } - public createSelectionElement() { - if (this.isMultiSelection) { - return this.createMultiSelectedElement(); - } - - return this.createSingleSelectedElement(); - } - - private createSingleSelectedElement(): EditableDashboardElement | undefined { - const sceneObj = this.selectedObjects?.values().next().value?.resolve(); - return getEditableElementFor(sceneObj); - } - - private createMultiSelectedElement(): MultiSelectedEditableDashboardElement | undefined { - if (!this.isMultiSelection) { - return; - } - + public createSelectionElement(): EditableDashboardElement | undefined { const sceneObjects = this.getSceneObjects(); - if (this.sameType) { - const firstObj = this.selectedObjects?.values().next().value?.resolve(); + if (sceneObjects.length === 0) { + return undefined; + } - if (firstObj instanceof VizPanel) { - return new MultiSelectedVizPanelsEditableElement(sceneObjects.filter((obj) => obj instanceof VizPanel)); - } + const firstElement = getEditableElementFor(sceneObjects[0]); - if (isEditableDashboardElement(firstObj!)) { - return firstObj.createMultiSelectedElement?.(sceneObjects); - } + if (!firstElement) { + return undefined; + } + + if (sceneObjects.length === 1) { + return firstElement; + } + + if (this.sameType && firstElement.createMultiSelectedElement) { + const elements = sceneObjects.map((obj) => getEditableElementFor(obj)!); + return firstElement.createMultiSelectedElement(elements); } const bulkActionElements = []; for (const sceneObject of sceneObjects) { - if (sceneObject instanceof VizPanel) { - const editableElement = new VizPanelEditableElement(sceneObject); - bulkActionElements.push(editableElement); - } + const element = getEditableElementFor(sceneObject); - if (isBulkActionElement(sceneObject)) { - bulkActionElements.push(sceneObject); + if (element && isBulkActionElement(element)) { + bulkActionElements.push(element); } } diff --git a/public/app/features/dashboard-scene/edit-pane/MultiSelectedObjectsEditableElement.tsx b/public/app/features/dashboard-scene/edit-pane/MultiSelectedObjectsEditableElement.tsx index a55b5f0d8c9..25bcdd807c9 100644 --- a/public/app/features/dashboard-scene/edit-pane/MultiSelectedObjectsEditableElement.tsx +++ b/public/app/features/dashboard-scene/edit-pane/MultiSelectedObjectsEditableElement.tsx @@ -1,42 +1,20 @@ -import { ReactNode } from 'react'; -import { v4 as uuidv4 } from 'uuid'; - -import { Stack, Text, Button } from '@grafana/ui'; -import { t, Trans } from 'app/core/internationalization'; +import { t } from 'app/core/internationalization'; +import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor'; import { BulkActionElement } from '../scene/types/BulkActionElement'; -import { EditableDashboardElementInfo } from '../scene/types/EditableDashboardElement'; -import { MultiSelectedEditableDashboardElement } from '../scene/types/MultiSelectedEditableDashboardElement'; +import { EditableDashboardElement, EditableDashboardElementInfo } from '../scene/types/EditableDashboardElement'; -export class MultiSelectedObjectsEditableElement implements MultiSelectedEditableDashboardElement { - public readonly isMultiSelectedEditableDashboardElement = true; - public readonly key: string; +export class MultiSelectedObjectsEditableElement implements EditableDashboardElement { + public readonly isEditableDashboardElement = true; - constructor(private _elements: BulkActionElement[]) { - this.key = uuidv4(); + constructor(private _elements: BulkActionElement[]) {} + + public useEditPaneOptions(): OptionsPaneCategoryDescriptor[] { + return []; } public getEditableElementInfo(): EditableDashboardElementInfo { - return { name: t('dashboard.edit-pane.elements.objects', 'Objects'), typeId: 'objects', icon: 'folder' }; - } - - public renderActions(): ReactNode { - return ( - - - - No. of objects selected: {{ length }} - - - -
{isExpanded && (
@@ -179,8 +172,6 @@ const getStyles = (theme: GrafanaTheme2) => ({ padding: theme.spacing(0.5, 1.5), color: theme.colors.text.primary, fontWeight: theme.typography.fontWeightMedium, - }), - headerHover: css({ cursor: 'pointer', '&:hover': { background: theme.colors.emphasize(theme.colors.background.primary, 0.03), diff --git a/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor.tsx b/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor.tsx index bb1c76969d1..854b5be01e7 100644 --- a/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor.tsx +++ b/public/app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor.tsx @@ -16,7 +16,6 @@ export interface OptionsPaneCategoryDescriptorProps { itemsCount?: number; customRender?: () => React.ReactNode; sandboxId?: string; - isOpenable?: boolean; } /** @@ -60,8 +59,12 @@ export class OptionsPaneCategoryDescriptor { return this.props.customRender(); } - if (this.props.id === '') { - return {this.items.map((item) => item.render(searchQuery))}; + if (this.props.title === '') { + return ( + + {this.items.map((item) => item.render(searchQuery))} + + ); } return ( diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index cef94684d01..43f96108203 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -1068,23 +1068,18 @@ "elements": { "dashboard": "Dashboard", "objects": "Objects", + "panel": "Panel", "panels": "Panels", + "row": "Row", "rows": "Rows", + "tab": "Tab", "tabs": "Tabs" }, - "objects": { - "multi-select": { - "selection-number": "No. of objects selected: {{length}}" - } - }, "open": "Open options pane", "row": { "header": { "hide": "Hide", "title": "Row header" - }, - "multi-select": { - "title": "{{length}} rows selected" } } }, @@ -1165,13 +1160,11 @@ "copy-or-duplicate": "Copy or Duplicate", "delete": "Delete", "duplicate": "Duplicate", - "layout": "Layout", - "panels-title": "{{length}} panels selected" + "layout": "Layout" } }, "options": { "description": "Description", - "title": "Dashboard options", "title-option": "Title" }, "outline": { @@ -1214,7 +1207,6 @@ }, "rows-layout": { "description": "Rows layout", - "item-name": "Row", "name": "Rows", "option": { "height": "Height", @@ -1253,9 +1245,6 @@ "menu": { "move-tab": "Move tab" }, - "multi-select": { - "title": "{{length}} tabs selected" - }, "name": "Tabs", "tab": { "menu": { @@ -1270,7 +1259,6 @@ "new": "New tab" }, "tab-options": { - "title": "Tab", "title-option": "Title" } }, @@ -1345,9 +1333,8 @@ "viz-panel": { "options": { "description": "Description", - "open-edit": "Open Panel Edit", + "open-edit": "Open panel editor", "plugin-type-image": "Image of plugin type", - "title": "Panel", "title-option": "Title", "transparent-background": "Transparent background" } From da8966821f49ec947b2f841c618e2ac475acc93b Mon Sep 17 00:00:00 2001 From: Tom Ratcliffe Date: Mon, 10 Mar 2025 14:23:05 +0000 Subject: [PATCH 09/63] Alerting: Add target datasource dropdown for Grafana recording rules (#101805) * Update types with optional recording rules data source UID * Show target data source for recording rules * Add i18n * Fix types * Show datasource on recording rule page * Fix loading of initial value for target datasource * Update translations * Update rule-form.test.ts.snap * Update names and remove fragment --- .../rule-editor/AlertRuleNameInput.tsx | 41 ++++++++++++++++++- .../components/rule-viewer/tabs/Details.tsx | 29 ++++++++++++- .../alerting/unified/types/rule-form.ts | 2 +- .../__snapshots__/rule-form.test.ts.snap | 1 + .../alerting/unified/utils/rule-form.ts | 3 ++ public/app/types/unified-alerting-dto.ts | 1 + public/locales/en-US/grafana.json | 7 +++- 7 files changed, 80 insertions(+), 4 deletions(-) diff --git a/public/app/features/alerting/unified/components/rule-editor/AlertRuleNameInput.tsx b/public/app/features/alerting/unified/components/rule-editor/AlertRuleNameInput.tsx index 5aaf8a6f09e..87b680f616b 100644 --- a/public/app/features/alerting/unified/components/rule-editor/AlertRuleNameInput.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/AlertRuleNameInput.tsx @@ -1,7 +1,11 @@ -import { useFormContext } from 'react-hook-form'; +import { Controller, useFormContext } from 'react-hook-form'; +import { DataSourceInstanceSettings } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; +import { config } from '@grafana/runtime'; import { Field, Input, Stack, Text } from '@grafana/ui'; +import { t } from 'app/core/internationalization'; +import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker'; import { RuleFormType, RuleFormValues } from '../../types/rule-form'; import { isCloudRecordingRuleByType, isGrafanaRecordingRuleByType, isRecordingRuleByType } from '../../utils/rules'; @@ -21,9 +25,11 @@ const recordingRuleNameValidationPattern = (type: RuleFormType) => ({ */ export const AlertRuleNameAndMetric = () => { const { + control, register, watch, formState: { errors }, + setValue, } = useFormContext(); const ruleFormType = watch('type'); @@ -76,6 +82,39 @@ export const AlertRuleNameAndMetric = () => { /> )} + + {isGrafanaRecordingRule && config.featureToggles.grafanaManagedRecordingRulesDatasources && ( + + ( + ds.type === 'prometheus'} + onChange={(ds: DataSourceInstanceSettings) => { + setValue('targetDatasourceUid', ds.uid); + }} + /> + )} + name="targetDatasourceUid" + control={control} + rules={{ + required: { value: true, message: 'Please select a data source' }, + }} + /> + + )} ); diff --git a/public/app/features/alerting/unified/components/rule-viewer/tabs/Details.tsx b/public/app/features/alerting/unified/components/rule-viewer/tabs/Details.tsx index 8adb1023776..59d4d2d30d1 100644 --- a/public/app/features/alerting/unified/components/rule-viewer/tabs/Details.tsx +++ b/public/app/features/alerting/unified/components/rule-viewer/tabs/Details.tsx @@ -2,8 +2,10 @@ import { css } from '@emotion/css'; import { formatDistanceToNowStrict } from 'date-fns'; import { GrafanaTheme2, dateTimeFormat, dateTimeFormatTimeAgo } from '@grafana/data'; -import { Icon, Stack, Text, TextLink, useStyles2 } from '@grafana/ui'; +import { config } from '@grafana/runtime'; +import { Icon, Link, Stack, Text, TextLink, useStyles2 } from '@grafana/ui'; import { Trans, t } from 'app/core/internationalization'; +import { useDatasource } from 'app/features/datasources/hooks'; import { CombinedRule } from 'app/types/unified-alerting'; import { usePendingPeriod } from '../../../hooks/rules/usePendingPeriod'; @@ -53,6 +55,17 @@ export const Details = ({ rule }: DetailsProps) => { determinedRuleType = RuleType.CloudRecordingRule; } + const targetDatasourceUid = rulerRuleType.grafana.recordingRule(rule.rulerRule) + ? rule.rulerRule.grafana_alert.record?.target_datasource_uid + : null; + + const datasource = useDatasource(targetDatasourceUid); + + const showTargetDatasource = + config.featureToggles.grafanaManagedRecordingRulesDatasources && + targetDatasourceUid && + targetDatasourceUid !== 'grafana'; + const evaluationDuration = rule.promRule?.evaluationTime; const evaluationTimestamp = rule.promRule?.lastEvaluation; @@ -101,6 +114,20 @@ export const Details = ({ rule }: DetailsProps) => { )} )} + {showTargetDatasource && ( + + + datasource logo + {datasource?.name} + + + } + /> + )} diff --git a/public/app/features/alerting/unified/types/rule-form.ts b/public/app/features/alerting/unified/types/rule-form.ts index 07547e9c509..a4cc2dc2da7 100644 --- a/public/app/features/alerting/unified/types/rule-form.ts +++ b/public/app/features/alerting/unified/types/rule-form.ts @@ -54,7 +54,7 @@ export interface RuleFormValues { contactPoints?: AlertManagerManualRouting; editorSettings?: SimplifiedEditor; metric?: string; - + targetDatasourceUid?: string; // cortex / loki rules namespace: string; forTime: number; diff --git a/public/app/features/alerting/unified/utils/__snapshots__/rule-form.test.ts.snap b/public/app/features/alerting/unified/utils/__snapshots__/rule-form.test.ts.snap index 71e08950c88..d3d728fd59f 100644 --- a/public/app/features/alerting/unified/utils/__snapshots__/rule-form.test.ts.snap +++ b/public/app/features/alerting/unified/utils/__snapshots__/rule-form.test.ts.snap @@ -28,6 +28,7 @@ exports[`formValuesToRulerGrafanaRuleDTO should correctly convert rule form valu "record": { "from": "A", "metric": "", + "target_datasource_uid": undefined, }, "title": "", }, diff --git a/public/app/features/alerting/unified/utils/rule-form.ts b/public/app/features/alerting/unified/utils/rule-form.ts index d9e1130736e..7a95be75c1a 100644 --- a/public/app/features/alerting/unified/utils/rule-form.ts +++ b/public/app/features/alerting/unified/utils/rule-form.ts @@ -148,6 +148,7 @@ export function formValuesToRulerGrafanaRuleDTO(values: RuleFormValues): Postabl manualRouting, type, metric, + targetDatasourceUid, } = values; if (!condition) { throw new Error('You cannot create an alert rule without specifying the alert condition'); @@ -196,6 +197,7 @@ export function formValuesToRulerGrafanaRuleDTO(values: RuleFormValues): Postabl record: { metric: metric ?? name, from: condition, + target_datasource_uid: targetDatasourceUid, }, }, annotations, @@ -284,6 +286,7 @@ export function rulerRuleToFormValues(ruleWithLocation: RuleWithLocation): RuleF folder: { title: namespace, uid: ga.namespace_uid }, isPaused: ga.is_paused, metric: ga.record?.metric, + targetDatasourceUid: ga.record?.target_datasource_uid, }; } else if (rulerRuleType.grafana.rule(rule)) { // grafana alerting rule diff --git a/public/app/types/unified-alerting-dto.ts b/public/app/types/unified-alerting-dto.ts index bf112911756..6669d4fded9 100644 --- a/public/app/types/unified-alerting-dto.ts +++ b/public/app/types/unified-alerting-dto.ts @@ -262,6 +262,7 @@ export interface PostableGrafanaRuleDefinition { record?: { metric: string; from: string; + target_datasource_uid?: string; }; intervalSeconds?: number; } diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index 43f96108203..a2dd8f62e0d 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -184,7 +184,8 @@ "rule-identifier": "Rule identifier", "rule-type": "Rule type", "state-error-timeout": "Alert state if execution error or timeout", - "state-no-data": "Alert state if no data or all values are null" + "state-no-data": "Alert state if no data or all values are null", + "target-datasource-uid": "Target data source" }, "alert-recording-rule-form": { "evaluation-behaviour": { @@ -504,6 +505,10 @@ "preview": "Preview", "previewCondition": "Preview alert rule condition" }, + "recording-rules": { + "description-target-data-source": "The Prometheus data source to store the recording rule in", + "label-target-data-source": "Target data source" + }, "rule-form": { "evaluation": { "evaluation-group-and-interval": "Evaluation group and interval", From 696993e29b6539f5404821b2fd8052e789640570 Mon Sep 17 00:00:00 2001 From: Javi Date: Mon, 10 Mar 2025 15:30:22 +0100 Subject: [PATCH 10/63] Tempo: Update autocomplete (min, max, avg, sum over time) (#101861) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Tempo: Update autocomplete (min, max, avg, sum over time) * Fix typo * added sum_over_time to isTraceQlMetricsQuery --------- Co-authored-by: André Pereira --- .../plugins/datasource/tempo/datasource.ts | 2 +- .../datasource/tempo/traceql/autocomplete.ts | 24 +++++++++++++++++++ .../datasource/tempo/traceql/traceql.ts | 4 ++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/public/app/plugins/datasource/tempo/datasource.ts b/public/app/plugins/datasource/tempo/datasource.ts index b06a9d7bcc3..ee8727ce74f 100644 --- a/public/app/plugins/datasource/tempo/datasource.ts +++ b/public/app/plugins/datasource/tempo/datasource.ts @@ -312,7 +312,7 @@ export class TempoDatasource extends DataSourceWithBackend Date: Mon, 10 Mar 2025 15:58:12 +0100 Subject: [PATCH 11/63] Spanner: update DB snapshot (#101879) * Update spanner snapshot to include migrations from grafana-enterprise. * Move sql dump tool (test) to grafana-enterprise. --- .../migrations/dialect_migration_test.go | 121 ------------------ .../migrator/snapshot/spanner-ddl.json | 85 +++++++++--- .../migrator/snapshot/spanner-log.json | 117 ++++++++++++++++- 3 files changed, 181 insertions(+), 142 deletions(-) delete mode 100644 pkg/services/sqlstore/migrations/dialect_migration_test.go diff --git a/pkg/services/sqlstore/migrations/dialect_migration_test.go b/pkg/services/sqlstore/migrations/dialect_migration_test.go deleted file mode 100644 index cc7e271bd87..00000000000 --- a/pkg/services/sqlstore/migrations/dialect_migration_test.go +++ /dev/null @@ -1,121 +0,0 @@ -//go:build enterprise || pro - -package migrations - -import ( - "encoding/json" - "fmt" - "os" - "strconv" - "testing" - - "github.com/stretchr/testify/require" - "gopkg.in/ini.v1" - "xorm.io/core" - - "github.com/grafana/grafana/pkg/infra/log" - "github.com/grafana/grafana/pkg/setting" - "xorm.io/xorm" - - "github.com/grafana/grafana/pkg/services/sqlstore/migrator" - "github.com/grafana/grafana/pkg/services/sqlstore/sqlutil" -) - -func setupTestDB(t *testing.T) (*migrator.Migrator, *xorm.Engine) { - t.Helper() - dbType := sqlutil.GetTestDBType() - testDB, err := sqlutil.GetTestDB(dbType) - require.NoError(t, err) - - t.Cleanup(testDB.Cleanup) - - x, err := xorm.NewEngine(testDB.DriverName, testDB.ConnStr) - require.NoError(t, err) - - t.Cleanup(func() { - if err := x.Close(); err != nil { - fmt.Printf("failed to close xorm engine: %v", err) - } - }) - - err = migrator.NewDialect(x.DriverName()).CleanDB(x) - require.NoError(t, err) - - mg := migrator.NewMigrator(x, &setting.Cfg{ - Logger: log.New("users.test"), - Raw: ini.Empty(), - }) - migrations := &OSSMigrations{} - migrations.AddMigration(mg) - - err = mg.Start(false, 0) - require.NoError(t, err) - - return mg, x -} - -// This "test" migrates database from scratch, and then generates Spanner DDL statements for re-creating the same database. -func TestMigrateToSpannerDialect(t *testing.T) { - t.Skip("Skipping because test returns panic: unknown column type: INTEGER") - mg, eng := setupTestDB(t) - tables, err := eng.DBMetas() - require.NoError(t, err) - - var statements []string - - spannerDialect := migrator.NewSpannerDialect() - for _, table := range tables { - t := &migrator.Table{ - Name: table.Name, - Columns: nil, - PrimaryKeys: table.PrimaryKeys, - Indices: nil, - } - - for _, c := range table.Columns() { - col := &migrator.Column{ - Name: c.Name, - Type: c.SQLType.Name, - Length: c.Length, - Length2: c.Length2, - Nullable: c.Nullable, - IsPrimaryKey: c.IsPrimaryKey, - IsAutoIncrement: c.IsAutoIncrement, - IsLatin: false, - Default: c.Default, - } - if (col.Type == core.Bool || col.Type == core.TinyInt) && c.Default != "" { - b, err := strconv.ParseBool(c.Default) - if err == nil { - // Format bool values as true/false. - col.Default = strconv.FormatBool(b) - } - } - t.Columns = append(t.Columns, col) - } - - for _, ix := range table.Indexes { - nix := &migrator.Index{ - Name: ix.Name, - Type: ix.Type, - Cols: ix.Cols, - } - t.Indices = append(t.Indices, nix) - } - - statements = append(statements, spannerDialect.CreateTableSQL(t)) - - for _, nix := range t.Indices { - if nix.Name != "PRIMARY_KEY" { - statements = append(statements, spannerDialect.CreateIndexSQL(table.Name, nix)) - } - } - } - - enc := json.NewEncoder(os.Stdout) - enc.SetIndent("", " ") - - require.NoError(t, enc.Encode(statements)) - fmt.Println() - require.NoError(t, enc.Encode(mg.GetMigrationIDs(true))) -} diff --git a/pkg/services/sqlstore/migrator/snapshot/spanner-ddl.json b/pkg/services/sqlstore/migrator/snapshot/spanner-ddl.json index 83d748e09c8..a205475caa6 100644 --- a/pkg/services/sqlstore/migrator/snapshot/spanner-ddl.json +++ b/pkg/services/sqlstore/migrator/snapshot/spanner-ddl.json @@ -9,8 +9,8 @@ "CREATE TABLE `alert_image` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `token` STRING(190) NOT NULL, `path` STRING(190) NOT NULL, `url` STRING(2048) NOT NULL, `created_at` TIMESTAMP NOT NULL, `expires_at` TIMESTAMP NOT NULL) PRIMARY KEY (id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_alert_image_token` ON `alert_image` (token)", "CREATE TABLE `alert_instance` (`rule_org_id` INT64 NOT NULL, `rule_uid` STRING(40) NOT NULL, `labels` STRING(MAX) NOT NULL, `labels_hash` STRING(190) NOT NULL, `current_state` STRING(190) NOT NULL, `current_state_since` INT64 NOT NULL, `last_eval_time` INT64 NOT NULL, `current_state_end` INT64 NOT NULL DEFAULT (0), `current_reason` STRING(190), `result_fingerprint` STRING(16), `resolved_at` INT64, `last_sent_at` INT64) PRIMARY KEY (rule_org_id,rule_uid,labels_hash)", - "CREATE INDEX `IDX_alert_instance_rule_org_id_rule_uid_current_state` ON `alert_instance` (rule_org_id, rule_uid, current_state)", "CREATE INDEX `IDX_alert_instance_rule_org_id_current_state` ON `alert_instance` (rule_org_id, current_state)", + "CREATE INDEX `IDX_alert_instance_rule_org_id_rule_uid_current_state` ON `alert_instance` (rule_org_id, rule_uid, current_state)", "CREATE TABLE `alert_notification` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `org_id` INT64 NOT NULL, `name` STRING(190) NOT NULL, `type` STRING(255) NOT NULL, `settings` STRING(MAX) NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL, `is_default` BOOL NOT NULL DEFAULT (false), `frequency` INT64, `send_reminder` BOOL DEFAULT (false), `disable_resolve_message` BOOL NOT NULL DEFAULT (false), `uid` STRING(40), `secure_settings` STRING(MAX)) PRIMARY KEY (id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_alert_notification_org_id_uid` ON `alert_notification` (org_id, uid)", "CREATE TABLE `alert_notification_state` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `org_id` INT64 NOT NULL, `alert_id` INT64 NOT NULL, `notifier_id` INT64 NOT NULL, `state` STRING(50) NOT NULL, `version` INT64 NOT NULL, `updated_at` INT64 NOT NULL, `alert_rule_state_updated_version` INT64 NOT NULL) PRIMARY KEY (id)", @@ -48,11 +48,12 @@ "CREATE INDEX `IDX_api_key_org_id` ON `api_key` (org_id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_api_key_key` ON `api_key` (key)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_api_key_org_id_name` ON `api_key` (org_id, name)", + "CREATE TABLE `autoincrement_sequences` (`name` STRING(128) NOT NULL, `next_value` INT64 NOT NULL) PRIMARY KEY (name)", "CREATE TABLE `builtin_role` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `role` STRING(190) NOT NULL, `role_id` INT64 NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL, `org_id` INT64 NOT NULL DEFAULT (0)) PRIMARY KEY (id)", - "CREATE UNIQUE NULL_FILTERED INDEX `UQE_builtin_role_org_id_role_id_role` ON `builtin_role` (org_id, role_id, role)", "CREATE INDEX `IDX_builtin_role_org_id` ON `builtin_role` (org_id)", - "CREATE INDEX `IDX_builtin_role_role` ON `builtin_role` (role)", "CREATE INDEX `IDX_builtin_role_role_id` ON `builtin_role` (role_id)", + "CREATE INDEX `IDX_builtin_role_role` ON `builtin_role` (role)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_builtin_role_org_id_role_id_role` ON `builtin_role` (org_id, role_id, role)", "CREATE TABLE `cache_data` (`cache_key` STRING(168) NOT NULL, `data` BYTES(MAX) NOT NULL, `expires` INT64 NOT NULL, `created_at` INT64 NOT NULL) PRIMARY KEY (cache_key)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_cache_data_cache_key` ON `cache_data` (cache_key)", "CREATE TABLE `cloud_migration_resource` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `uid` STRING(40) NOT NULL, `resource_type` STRING(40) NOT NULL, `resource_uid` STRING(255), `status` STRING(20) NOT NULL, `error_string` STRING(MAX), `snapshot_uid` STRING(40) NOT NULL, `name` STRING(MAX), `parent_name` STRING(MAX), `error_code` STRING(MAX)) PRIMARY KEY (id)", @@ -61,48 +62,67 @@ "CREATE TABLE `cloud_migration_snapshot` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `uid` STRING(40), `session_uid` STRING(40), `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL, `finished` TIMESTAMP, `upload_url` STRING(MAX), `status` STRING(MAX) NOT NULL, `local_directory` STRING(MAX), `gms_snapshot_uid` STRING(MAX), `encryption_key` STRING(MAX), `error_string` STRING(MAX)) PRIMARY KEY (id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_cloud_migration_snapshot_uid` ON `cloud_migration_snapshot` (uid)", "CREATE TABLE `correlation` (`uid` STRING(40) NOT NULL, `org_id` INT64 NOT NULL DEFAULT (0), `source_uid` STRING(40) NOT NULL, `target_uid` STRING(40), `label` STRING(MAX) NOT NULL, `description` STRING(MAX) NOT NULL, `config` STRING(MAX), `provisioned` BOOL NOT NULL DEFAULT (false), `type` STRING(40) NOT NULL DEFAULT ('query')) PRIMARY KEY (uid,org_id,source_uid)", + "CREATE INDEX `IDX_correlation_org_id` ON `correlation` (org_id)", "CREATE INDEX `IDX_correlation_source_uid` ON `correlation` (source_uid)", "CREATE INDEX `IDX_correlation_uid` ON `correlation` (uid)", - "CREATE INDEX `IDX_correlation_org_id` ON `correlation` (org_id)", "CREATE TABLE `dashboard` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `version` INT64 NOT NULL, `slug` STRING(189) NOT NULL, `title` STRING(189) NOT NULL, `data` STRING(MAX) NOT NULL, `org_id` INT64 NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL, `updated_by` INT64, `created_by` INT64, `gnet_id` INT64, `plugin_id` STRING(189), `folder_id` INT64 NOT NULL DEFAULT (0), `is_folder` BOOL NOT NULL DEFAULT (false), `has_acl` BOOL NOT NULL DEFAULT (false), `uid` STRING(40), `is_public` BOOL NOT NULL DEFAULT (false), `deleted` TIMESTAMP, `api_version` STRING(16), `folder_uid` STRING(40)) PRIMARY KEY (id)", "CREATE INDEX `IDX_dashboard_deleted` ON `dashboard` (deleted)", + "CREATE INDEX `IDX_dashboard_gnet_id` ON `dashboard` (gnet_id)", "CREATE INDEX `IDX_dashboard_is_folder` ON `dashboard` (is_folder)", - "CREATE INDEX `IDX_dashboard_org_id` ON `dashboard` (org_id)", "CREATE INDEX `IDX_dashboard_org_id_folder_id_title` ON `dashboard` (org_id, folder_id, title)", "CREATE INDEX `IDX_dashboard_org_id_plugin_id` ON `dashboard` (org_id, plugin_id)", - "CREATE INDEX `IDX_dashboard_gnet_id` ON `dashboard` (gnet_id)", + "CREATE INDEX `IDX_dashboard_org_id` ON `dashboard` (org_id)", "CREATE INDEX `IDX_dashboard_title` ON `dashboard` (title)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_dashboard_org_id_uid` ON `dashboard` (org_id, uid)", "CREATE TABLE `dashboard_acl` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `org_id` INT64 NOT NULL, `dashboard_id` INT64 NOT NULL, `user_id` INT64, `team_id` INT64, `permission` INT64 NOT NULL DEFAULT (4), `role` STRING(20), `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL) PRIMARY KEY (id)", + "CREATE INDEX `IDX_dashboard_acl_dashboard_id` ON `dashboard_acl` (dashboard_id)", + "CREATE INDEX `IDX_dashboard_acl_org_id_role` ON `dashboard_acl` (org_id, role)", + "CREATE INDEX `IDX_dashboard_acl_permission` ON `dashboard_acl` (permission)", "CREATE INDEX `IDX_dashboard_acl_team_id` ON `dashboard_acl` (team_id)", "CREATE INDEX `IDX_dashboard_acl_user_id` ON `dashboard_acl` (user_id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_dashboard_acl_dashboard_id_team_id` ON `dashboard_acl` (dashboard_id, team_id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_dashboard_acl_dashboard_id_user_id` ON `dashboard_acl` (dashboard_id, user_id)", - "CREATE INDEX `IDX_dashboard_acl_dashboard_id` ON `dashboard_acl` (dashboard_id)", - "CREATE INDEX `IDX_dashboard_acl_org_id_role` ON `dashboard_acl` (org_id, role)", - "CREATE INDEX `IDX_dashboard_acl_permission` ON `dashboard_acl` (permission)", "CREATE TABLE `dashboard_provisioning` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `dashboard_id` INT64, `name` STRING(150) NOT NULL, `external_id` STRING(MAX) NOT NULL, `updated` INT64 NOT NULL DEFAULT (0), `check_sum` STRING(32)) PRIMARY KEY (id)", - "CREATE INDEX `IDX_dashboard_provisioning_dashboard_id` ON `dashboard_provisioning` (dashboard_id)", "CREATE INDEX `IDX_dashboard_provisioning_dashboard_id_name` ON `dashboard_provisioning` (dashboard_id, name)", + "CREATE INDEX `IDX_dashboard_provisioning_dashboard_id` ON `dashboard_provisioning` (dashboard_id)", "CREATE TABLE `dashboard_public` (`uid` STRING(40) NOT NULL, `dashboard_uid` STRING(40) NOT NULL, `org_id` INT64 NOT NULL, `time_settings` STRING(MAX), `template_variables` STRING(MAX), `access_token` STRING(32) NOT NULL, `created_by` INT64 NOT NULL, `updated_by` INT64, `created_at` TIMESTAMP NOT NULL, `updated_at` TIMESTAMP, `is_enabled` BOOL NOT NULL DEFAULT (false), `annotations_enabled` BOOL NOT NULL DEFAULT (false), `time_selection_enabled` BOOL NOT NULL DEFAULT (false), `share` STRING(64) NOT NULL DEFAULT ('public')) PRIMARY KEY (uid)", "CREATE INDEX `IDX_dashboard_public_config_org_id_dashboard_uid` ON `dashboard_public` (org_id, dashboard_uid)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_dashboard_public_config_access_token` ON `dashboard_public` (access_token)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_dashboard_public_config_uid` ON `dashboard_public` (uid)", + "CREATE TABLE `dashboard_public_email_share` (`uid` STRING(40) NOT NULL, `public_dashboard_uid` STRING(64) NOT NULL, `recipient` STRING(255) NOT NULL, `type` STRING(64) NOT NULL DEFAULT ('email'), `created_at` TIMESTAMP NOT NULL, `updated_at` TIMESTAMP NOT NULL) PRIMARY KEY (uid)", + "CREATE TABLE `dashboard_public_magic_link` (`uid` STRING(40) NOT NULL, `token_uuid` STRING(64) NOT NULL, `public_dashboard_uid` STRING(64) NOT NULL, `email` STRING(255) NOT NULL, `created_at` TIMESTAMP NOT NULL, `updated_at` TIMESTAMP NOT NULL) PRIMARY KEY (uid)", + "CREATE TABLE `dashboard_public_session` (`uid` STRING(40) NOT NULL, `cookie_uuid` STRING(64) NOT NULL, `public_dashboard_uid` STRING(64) NOT NULL, `email` STRING(255) NOT NULL, `created_at` TIMESTAMP NOT NULL, `updated_at` TIMESTAMP NOT NULL, `last_seen_at` TIMESTAMP) PRIMARY KEY (uid)", + "CREATE TABLE `dashboard_public_usage_by_day` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `public_dashboard_uid` STRING(255) NOT NULL, `day` STRING(40) NOT NULL, `views` INT64 NOT NULL, `queries` INT64 NOT NULL, `errors` INT64 NOT NULL, `load_duration` FLOAT64 NOT NULL, `cached_queries` INT64 NOT NULL DEFAULT (0)) PRIMARY KEY (id)", "CREATE TABLE `dashboard_snapshot` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `name` STRING(255) NOT NULL, `key` STRING(190) NOT NULL, `delete_key` STRING(190) NOT NULL, `org_id` INT64 NOT NULL, `user_id` INT64 NOT NULL, `external` BOOL NOT NULL, `external_url` STRING(255) NOT NULL, `dashboard` STRING(MAX) NOT NULL, `expires` TIMESTAMP NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL, `external_delete_url` STRING(255), `dashboard_encrypted` BYTES(MAX)) PRIMARY KEY (id)", "CREATE INDEX `IDX_dashboard_snapshot_user_id` ON `dashboard_snapshot` (user_id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_dashboard_snapshot_delete_key` ON `dashboard_snapshot` (delete_key)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_dashboard_snapshot_key` ON `dashboard_snapshot` (key)", "CREATE TABLE `dashboard_tag` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `dashboard_id` INT64 NOT NULL, `term` STRING(50) NOT NULL, `dashboard_uid` STRING(40), `org_id` INT64 DEFAULT (1)) PRIMARY KEY (id)", "CREATE INDEX `IDX_dashboard_tag_dashboard_id` ON `dashboard_tag` (dashboard_id)", + "CREATE TABLE `dashboard_usage_by_day` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `dashboard_id` INT64 NOT NULL, `day` STRING(40) NOT NULL, `views` INT64 NOT NULL, `queries` INT64 NOT NULL, `errors` INT64 NOT NULL, `load_duration` FLOAT64 NOT NULL, `cached_queries` INT64 NOT NULL DEFAULT (0), `dashboard_uid` STRING(40), `org_id` INT64 DEFAULT (1)) PRIMARY KEY (id)", + "CREATE INDEX `IDX_dashboard_usage_by_day_dashboard_id` ON `dashboard_usage_by_day` (dashboard_id)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_dashboard_usage_by_day_dashboard_id_day` ON `dashboard_usage_by_day` (dashboard_id, day)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_dashboard_usage_by_day_dashboard_uid_org_id_day` ON `dashboard_usage_by_day` (dashboard_uid, org_id, day)", + "CREATE TABLE `dashboard_usage_sums` (`dashboard_id` INT64 NOT NULL, `updated` TIMESTAMP NOT NULL, `views_last_1_days` INT64 NOT NULL, `views_last_7_days` INT64 NOT NULL, `views_last_30_days` INT64 NOT NULL, `views_total` INT64 NOT NULL, `queries_last_1_days` INT64 NOT NULL, `queries_last_7_days` INT64 NOT NULL, `queries_last_30_days` INT64 NOT NULL, `queries_total` INT64 NOT NULL, `errors_last_1_days` INT64 NOT NULL DEFAULT (0), `errors_last_7_days` INT64 NOT NULL DEFAULT (0), `errors_last_30_days` INT64 NOT NULL DEFAULT (0), `errors_total` INT64 NOT NULL DEFAULT (0), `dashboard_uid` STRING(40), `org_id` INT64 DEFAULT (1)) PRIMARY KEY (dashboard_id)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_dashboard_usage_sums_org_id_dashboard_uid` ON `dashboard_usage_sums` (org_id, dashboard_uid)", "CREATE TABLE `dashboard_version` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `dashboard_id` INT64 NOT NULL, `parent_version` INT64 NOT NULL, `restored_from` INT64 NOT NULL, `version` INT64 NOT NULL, `created` TIMESTAMP NOT NULL, `created_by` INT64 NOT NULL, `message` STRING(MAX) NOT NULL, `data` STRING(MAX), `api_version` STRING(16)) PRIMARY KEY (id)", - "CREATE UNIQUE NULL_FILTERED INDEX `UQE_dashboard_version_dashboard_id_version` ON `dashboard_version` (dashboard_id, version)", "CREATE INDEX `IDX_dashboard_version_dashboard_id` ON `dashboard_version` (dashboard_id)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_dashboard_version_dashboard_id_version` ON `dashboard_version` (dashboard_id, version)", "CREATE TABLE `data_keys` (`name` STRING(100) NOT NULL, `active` BOOL NOT NULL, `scope` STRING(30) NOT NULL, `provider` STRING(50) NOT NULL, `encrypted_data` BYTES(MAX) NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL, `label` STRING(100)) PRIMARY KEY (name)", "CREATE TABLE `data_source` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `org_id` INT64 NOT NULL, `version` INT64 NOT NULL, `type` STRING(255) NOT NULL, `name` STRING(190) NOT NULL, `access` STRING(255) NOT NULL, `url` STRING(255) NOT NULL, `password` STRING(255), `user` STRING(255), `database` STRING(255), `basic_auth` BOOL NOT NULL, `basic_auth_user` STRING(255), `basic_auth_password` STRING(255), `is_default` BOOL NOT NULL, `json_data` STRING(MAX), `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL, `with_credentials` BOOL NOT NULL DEFAULT (false), `secure_json_data` STRING(MAX), `read_only` BOOL, `uid` STRING(40) NOT NULL DEFAULT ('0'), `is_prunable` BOOL DEFAULT (false), `api_version` STRING(20)) PRIMARY KEY (id)", - "CREATE INDEX `IDX_data_source_org_id` ON `data_source` (org_id)", "CREATE INDEX `IDX_data_source_org_id_is_default` ON `data_source` (org_id, is_default)", + "CREATE INDEX `IDX_data_source_org_id` ON `data_source` (org_id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_data_source_org_id_name` ON `data_source` (org_id, name)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_data_source_org_id_uid` ON `data_source` (org_id, uid)", + "CREATE TABLE `data_source_acl` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `org_id` INT64 NOT NULL, `data_source_id` INT64 NOT NULL, `team_id` INT64 NOT NULL, `user_id` INT64 NOT NULL, `permission` INT64 NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL) PRIMARY KEY (id)", + "CREATE INDEX `IDX_data_source_acl_data_source_id` ON `data_source_acl` (data_source_id)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_data_source_acl_data_source_id_team_id_user_id` ON `data_source_acl` (data_source_id, team_id, user_id)", + "CREATE TABLE `data_source_cache` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `data_source_id` INT64 NOT NULL, `enabled` BOOL NOT NULL, `ttl_ms` INT64 NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL, `use_default_ttl` BOOL NOT NULL DEFAULT (true), `data_source_uid` STRING(40) NOT NULL DEFAULT ('0'), `ttl_resources_ms` INT64 NOT NULL DEFAULT (300000)) PRIMARY KEY (id)", + "CREATE INDEX `IDX_data_source_cache_data_source_id` ON `data_source_cache` (data_source_id)", + "CREATE INDEX `IDX_data_source_cache_data_source_uid` ON `data_source_cache` (data_source_uid)", + "CREATE TABLE `data_source_usage_by_day` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `data_source_id` INT64 NOT NULL, `day` STRING(40) NOT NULL, `queries` INT64 NOT NULL, `errors` INT64 NOT NULL, `load_duration_ms` INT64 NOT NULL) PRIMARY KEY (id)", + "CREATE INDEX `IDX_data_source_usage_by_day_data_source_id` ON `data_source_usage_by_day` (data_source_id)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_data_source_usage_by_day_data_source_id_day` ON `data_source_usage_by_day` (data_source_id, day)", "CREATE TABLE `entity_event` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `entity_id` STRING(1024) NOT NULL, `event_type` STRING(8) NOT NULL, `created` INT64 NOT NULL) PRIMARY KEY (id)", "CREATE TABLE `file` (`path` STRING(1024) NOT NULL, `path_hash` STRING(64) NOT NULL, `parent_folder_path_hash` STRING(64) NOT NULL, `contents` BYTES(MAX), `etag` STRING(32) NOT NULL, `cache_control` STRING(128) NOT NULL, `content_disposition` STRING(128) NOT NULL, `updated` TIMESTAMP NOT NULL, `created` TIMESTAMP NOT NULL, `size` INT64 NOT NULL, `mime_type` STRING(255) NOT NULL) PRIMARY KEY (path_hash)", "CREATE INDEX `IDX_file_parent_folder_path_hash` ON `file` (parent_folder_path_hash)", @@ -119,6 +139,7 @@ "CREATE UNIQUE NULL_FILTERED INDEX `UQE_library_element_org_id_uid` ON `library_element` (org_id, uid)", "CREATE TABLE `library_element_connection` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `element_id` INT64 NOT NULL, `kind` INT64 NOT NULL, `connection_id` INT64 NOT NULL, `created` TIMESTAMP NOT NULL, `created_by` INT64 NOT NULL) PRIMARY KEY (id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_library_element_connection_element_id_kind_connection_id` ON `library_element_connection` (element_id, kind, connection_id)", + "CREATE TABLE `license_token` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `token` STRING(MAX) NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL) PRIMARY KEY (id)", "CREATE TABLE `login_attempt` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `username` STRING(190) NOT NULL, `ip_address` STRING(30) NOT NULL, `created` INT64 NOT NULL DEFAULT (0)) PRIMARY KEY (id)", "CREATE INDEX `IDX_login_attempt_username` ON `login_attempt` (username)", "CREATE TABLE `migration_log` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `migration_id` STRING(255) NOT NULL, `sql` STRING(MAX) NOT NULL, `success` BOOL NOT NULL, `error` STRING(MAX) NOT NULL, `timestamp` TIMESTAMP NOT NULL) PRIMARY KEY (id)", @@ -127,13 +148,13 @@ "CREATE TABLE `org` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `version` INT64 NOT NULL, `name` STRING(190) NOT NULL, `address1` STRING(255), `address2` STRING(255), `city` STRING(255), `state` STRING(255), `zip_code` STRING(50), `country` STRING(255), `billing_email` STRING(255), `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL) PRIMARY KEY (id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_org_name` ON `org` (name)", "CREATE TABLE `org_user` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `org_id` INT64 NOT NULL, `user_id` INT64 NOT NULL, `role` STRING(20) NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL) PRIMARY KEY (id)", - "CREATE UNIQUE NULL_FILTERED INDEX `UQE_org_user_org_id_user_id` ON `org_user` (org_id, user_id)", "CREATE INDEX `IDX_org_user_org_id` ON `org_user` (org_id)", "CREATE INDEX `IDX_org_user_user_id` ON `org_user` (user_id)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_org_user_org_id_user_id` ON `org_user` (org_id, user_id)", "CREATE TABLE `permission` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `role_id` INT64 NOT NULL, `action` STRING(190) NOT NULL, `scope` STRING(190) NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL, `kind` STRING(40) NOT NULL DEFAULT (''), `attribute` STRING(40) NOT NULL DEFAULT (''), `identifier` STRING(40) NOT NULL DEFAULT ('')) PRIMARY KEY (id)", - "CREATE UNIQUE NULL_FILTERED INDEX `UQE_permission_action_scope_role_id` ON `permission` (action, scope, role_id)", "CREATE INDEX `IDX_permission_identifier` ON `permission` (identifier)", "CREATE INDEX `IDX_permission_role_id` ON `permission` (role_id)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_permission_action_scope_role_id` ON `permission` (action, scope, role_id)", "CREATE TABLE `playlist` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `name` STRING(255) NOT NULL, `interval` STRING(255) NOT NULL, `org_id` INT64 NOT NULL, `created_at` INT64 NOT NULL DEFAULT (0), `updated_at` INT64 NOT NULL DEFAULT (0), `uid` STRING(80) NOT NULL DEFAULT ('0')) PRIMARY KEY (id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_playlist_org_id_uid` ON `playlist` (org_id, uid)", "CREATE TABLE `playlist_item` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `playlist_id` INT64 NOT NULL, `type` STRING(255) NOT NULL, `value` STRING(MAX) NOT NULL, `title` STRING(MAX) NOT NULL, `order` INT64 NOT NULL) PRIMARY KEY (id)", @@ -151,6 +172,16 @@ "CREATE UNIQUE NULL_FILTERED INDEX `UQE_query_history_star_user_id_query_uid` ON `query_history_star` (user_id, query_uid)", "CREATE TABLE `quota` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `org_id` INT64, `user_id` INT64, `target` STRING(190) NOT NULL, `limit` INT64 NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL) PRIMARY KEY (id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_quota_org_id_user_id_target` ON `quota` (org_id, user_id, target)", + "CREATE TABLE `recording_rules` (`id` STRING(128) NOT NULL, `target_ref_id` STRING(128) NOT NULL, `name` STRING(128) NOT NULL, `description` STRING(MAX) NOT NULL, `org_id` INT64 NOT NULL, `interval` INT64 NOT NULL, `range` INT64 NOT NULL, `active` BOOL NOT NULL DEFAULT (false), `count` BOOL NOT NULL DEFAULT (false), `queries` BYTES(MAX) NOT NULL, `created_at` TIMESTAMP NOT NULL, `prom_name` STRING(128)) PRIMARY KEY (id,target_ref_id)", + "CREATE TABLE `remote_write_targets` (`id` STRING(128) NOT NULL, `data_source_uid` STRING(128) NOT NULL, `write_path` STRING(128) NOT NULL, `org_id` INT64 NOT NULL) PRIMARY KEY (id,data_source_uid,write_path)", + "CREATE TABLE `report` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `user_id` INT64 NOT NULL, `org_id` INT64 NOT NULL, `dashboard_id` INT64 NOT NULL, `name` STRING(MAX) NOT NULL, `recipients` STRING(MAX) NOT NULL, `reply_to` STRING(MAX), `message` STRING(MAX), `schedule_frequency` STRING(32) NOT NULL, `schedule_day` STRING(32) NOT NULL, `schedule_hour` INT64 NOT NULL, `schedule_minute` INT64 NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL, `schedule_timezone` STRING(50) NOT NULL DEFAULT ('Europe/Stockholm'), `time_from` STRING(255), `time_to` STRING(255), `pdf_landscape` BOOL, `schedule_day_of_month` STRING(32), `pdf_layout` STRING(255), `pdf_orientation` STRING(32), `dashboard_uid` STRING(40), `template_vars` STRING(MAX), `enable_dashboard_url` BOOL, `state` STRING(32), `enable_csv` BOOL, `schedule_start` INT64, `schedule_end` INT64, `schedule_interval_frequency` STRING(32), `schedule_interval_amount` INT64, `schedule_workdays_only` BOOL, `formats` STRING(190) NOT NULL DEFAULT ('[\"pdf\"]'), `scale_factor` INT64 NOT NULL DEFAULT (2), `uid` STRING(40), `pdf_show_template_variables` BOOL NOT NULL DEFAULT (false), `pdf_combine_one_file` BOOL NOT NULL DEFAULT (true), `subject` STRING(MAX)) PRIMARY KEY (id)", + "CREATE INDEX `IDX_report_dashboard_id` ON `report` (dashboard_id)", + "CREATE INDEX `IDX_report_org_id` ON `report` (org_id)", + "CREATE INDEX `IDX_report_user_id` ON `report` (user_id)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_report_org_id_uid` ON `report` (org_id, uid)", + "CREATE TABLE `report_dashboards` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `report_id` INT64 NOT NULL, `dashboard_uid` STRING(40) NOT NULL DEFAULT (''), `report_variables` STRING(MAX), `time_to` STRING(255), `time_from` STRING(255), `created` TIMESTAMP) PRIMARY KEY (id)", + "CREATE INDEX `IDX_report_dashboards_report_id` ON `report_dashboards` (report_id)", + "CREATE TABLE `report_settings` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `user_id` INT64 NOT NULL, `org_id` INT64 NOT NULL, `branding_report_logo_url` STRING(MAX), `branding_email_logo_url` STRING(MAX), `branding_email_footer_link` STRING(MAX), `branding_email_footer_text` STRING(MAX), `branding_email_footer_mode` STRING(50), `pdf_theme` STRING(40) NOT NULL DEFAULT ('light'), `embedded_image_theme` STRING(40) NOT NULL DEFAULT ('dark')) PRIMARY KEY (id)", "CREATE TABLE `role` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `name` STRING(190) NOT NULL, `description` STRING(MAX), `version` INT64 NOT NULL, `org_id` INT64 NOT NULL, `uid` STRING(40) NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL, `display_name` STRING(190), `group_name` STRING(190), `hidden` BOOL NOT NULL DEFAULT (false)) PRIMARY KEY (id)", "CREATE INDEX `IDX_role_org_id` ON `role` (org_id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_role_org_id_name` ON `role` (org_id, name)", @@ -162,6 +193,8 @@ "CREATE TABLE `server_lock` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `operation_uid` STRING(100) NOT NULL, `version` INT64 NOT NULL, `last_execution` INT64 NOT NULL) PRIMARY KEY (id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_server_lock_operation_uid` ON `server_lock` (operation_uid)", "CREATE TABLE `session` (`key` STRING(16) NOT NULL, `data` BYTES(MAX) NOT NULL, `expiry` INT64 NOT NULL) PRIMARY KEY (key)", + "CREATE TABLE `setting` (`section` STRING(100) NOT NULL, `key` STRING(100) NOT NULL, `value` STRING(MAX) NOT NULL, `encrypted_value` STRING(MAX)) PRIMARY KEY (section,key)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_setting_section_key` ON `setting` (section, key)", "CREATE TABLE `short_url` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `org_id` INT64 NOT NULL, `uid` STRING(40) NOT NULL, `path` STRING(MAX) NOT NULL, `created_by` INT64, `created_at` INT64 NOT NULL, `last_seen_at` INT64) PRIMARY KEY (id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_short_url_org_id_uid` ON `short_url` (org_id, uid)", "CREATE TABLE `signing_key` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `key_id` STRING(255) NOT NULL, `private_key` STRING(MAX) NOT NULL, `added_at` TIMESTAMP NOT NULL, `expires_at` TIMESTAMP, `alg` STRING(255) NOT NULL) PRIMARY KEY (id)", @@ -176,20 +209,24 @@ "CREATE INDEX `IDX_team_org_id` ON `team` (org_id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_team_org_id_name` ON `team` (org_id, name)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_team_org_id_uid` ON `team` (org_id, uid)", + "CREATE TABLE `team_group` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `org_id` INT64 NOT NULL, `team_id` INT64 NOT NULL, `group_id` STRING(190) NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL) PRIMARY KEY (id)", + "CREATE INDEX `IDX_team_group_group_id` ON `team_group` (group_id)", + "CREATE INDEX `IDX_team_group_org_id` ON `team_group` (org_id)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_team_group_org_id_team_id_group_id` ON `team_group` (org_id, team_id, group_id)", "CREATE TABLE `team_member` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `org_id` INT64 NOT NULL, `team_id` INT64 NOT NULL, `user_id` INT64 NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL, `external` BOOL, `permission` INT64) PRIMARY KEY (id)", - "CREATE UNIQUE NULL_FILTERED INDEX `UQE_team_member_org_id_team_id_user_id` ON `team_member` (org_id, team_id, user_id)", "CREATE INDEX `IDX_team_member_org_id` ON `team_member` (org_id)", "CREATE INDEX `IDX_team_member_team_id` ON `team_member` (team_id)", "CREATE INDEX `IDX_team_member_user_id_org_id` ON `team_member` (user_id, org_id)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_team_member_org_id_team_id_user_id` ON `team_member` (org_id, team_id, user_id)", "CREATE TABLE `team_role` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `org_id` INT64 NOT NULL, `team_id` INT64 NOT NULL, `role_id` INT64 NOT NULL, `created` TIMESTAMP NOT NULL) PRIMARY KEY (id)", "CREATE INDEX `IDX_team_role_org_id` ON `team_role` (org_id)", "CREATE INDEX `IDX_team_role_team_id` ON `team_role` (team_id)", "CREATE UNIQUE NULL_FILTERED INDEX `UQE_team_role_org_id_team_id_role_id` ON `team_role` (org_id, team_id, role_id)", "CREATE TABLE `temp_user` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `org_id` INT64 NOT NULL, `version` INT64 NOT NULL, `email` STRING(190) NOT NULL, `name` STRING(255), `role` STRING(20), `code` STRING(190) NOT NULL, `status` STRING(20) NOT NULL, `invited_by_user_id` INT64, `email_sent` BOOL NOT NULL, `email_sent_on` TIMESTAMP, `remote_addr` STRING(255), `created` INT64 NOT NULL DEFAULT (0), `updated` INT64 NOT NULL DEFAULT (0)) PRIMARY KEY (id)", - "CREATE INDEX `IDX_temp_user_org_id` ON `temp_user` (org_id)", - "CREATE INDEX `IDX_temp_user_status` ON `temp_user` (status)", "CREATE INDEX `IDX_temp_user_code` ON `temp_user` (code)", "CREATE INDEX `IDX_temp_user_email` ON `temp_user` (email)", + "CREATE INDEX `IDX_temp_user_org_id` ON `temp_user` (org_id)", + "CREATE INDEX `IDX_temp_user_status` ON `temp_user` (status)", "CREATE TABLE `test_data` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `metric1` STRING(20), `metric2` STRING(150), `value_big_int` INT64, `value_double` FLOAT64, `value_float` FLOAT64, `value_int` INT64, `time_epoch` INT64 NOT NULL, `time_date_time` TIMESTAMP NOT NULL, `time_time_stamp` TIMESTAMP NOT NULL) PRIMARY KEY (id)", "CREATE TABLE `user` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `version` INT64 NOT NULL, `login` STRING(190) NOT NULL, `email` STRING(190) NOT NULL, `name` STRING(255), `password` STRING(255), `salt` STRING(50), `rands` STRING(50), `company` STRING(255), `org_id` INT64 NOT NULL, `is_admin` BOOL NOT NULL, `email_verified` BOOL, `theme` STRING(255), `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL, `help_flags1` INT64 NOT NULL DEFAULT (0), `last_seen_at` TIMESTAMP, `is_disabled` BOOL NOT NULL DEFAULT (false), `is_service_account` BOOL DEFAULT (false), `uid` STRING(40), `is_provisioned` BOOL NOT NULL DEFAULT (false)) PRIMARY KEY (id)", "CREATE INDEX `IDX_user_login_email` ON `user` (login, email)", @@ -200,13 +237,21 @@ "CREATE INDEX `IDX_user_auth_auth_module_auth_id` ON `user_auth` (auth_module, auth_id)", "CREATE INDEX `IDX_user_auth_user_id` ON `user_auth` (user_id)", "CREATE TABLE `user_auth_token` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `user_id` INT64 NOT NULL, `auth_token` STRING(100) NOT NULL, `prev_auth_token` STRING(100) NOT NULL, `user_agent` STRING(255) NOT NULL, `client_ip` STRING(255) NOT NULL, `auth_token_seen` BOOL NOT NULL, `seen_at` INT64, `rotated_at` INT64 NOT NULL, `created_at` INT64 NOT NULL, `updated_at` INT64 NOT NULL, `revoked_at` INT64, `external_session_id` INT64) PRIMARY KEY (id)", - "CREATE UNIQUE NULL_FILTERED INDEX `UQE_user_auth_token_auth_token` ON `user_auth_token` (auth_token)", - "CREATE UNIQUE NULL_FILTERED INDEX `UQE_user_auth_token_prev_auth_token` ON `user_auth_token` (prev_auth_token)", "CREATE INDEX `IDX_user_auth_token_revoked_at` ON `user_auth_token` (revoked_at)", "CREATE INDEX `IDX_user_auth_token_user_id` ON `user_auth_token` (user_id)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_user_auth_token_auth_token` ON `user_auth_token` (auth_token)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_user_auth_token_prev_auth_token` ON `user_auth_token` (prev_auth_token)", + "CREATE TABLE `user_dashboard_views` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `user_id` INT64 NOT NULL, `dashboard_id` INT64 NOT NULL, `viewed` TIMESTAMP NOT NULL, `org_id` INT64, `dashboard_uid` STRING(40)) PRIMARY KEY (id)", + "CREATE INDEX `IDX_user_dashboard_views_dashboard_id` ON `user_dashboard_views` (dashboard_id)", + "CREATE INDEX `IDX_user_dashboard_views_org_id_dashboard_uid` ON `user_dashboard_views` (org_id, dashboard_uid)", + "CREATE INDEX `IDX_user_dashboard_views_user_id` ON `user_dashboard_views` (user_id)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_user_dashboard_views_user_id_dashboard_id` ON `user_dashboard_views` (user_id, dashboard_id)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_user_dashboard_views_user_id_org_id_dashboard_uid` ON `user_dashboard_views` (user_id, org_id, dashboard_uid)", "CREATE TABLE `user_external_session` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `user_auth_id` INT64 NOT NULL, `user_id` INT64 NOT NULL, `auth_module` STRING(190) NOT NULL, `access_token` STRING(MAX), `id_token` STRING(MAX), `refresh_token` STRING(MAX), `session_id` STRING(1024), `session_id_hash` STRING(44), `name_id` STRING(1024), `name_id_hash` STRING(44), `expires_at` TIMESTAMP, `created_at` TIMESTAMP NOT NULL) PRIMARY KEY (id)", "CREATE TABLE `user_role` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `org_id` INT64 NOT NULL, `user_id` INT64 NOT NULL, `role_id` INT64 NOT NULL, `created` TIMESTAMP NOT NULL, `group_mapping_uid` STRING(40) DEFAULT ('')) PRIMARY KEY (id)", "CREATE INDEX `IDX_user_role_org_id` ON `user_role` (org_id)", "CREATE INDEX `IDX_user_role_user_id` ON `user_role` (user_id)", - "CREATE UNIQUE NULL_FILTERED INDEX `UQE_user_role_org_id_user_id_role_id_group_mapping_uid` ON `user_role` (org_id, user_id, role_id, group_mapping_uid)" + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_user_role_org_id_user_id_role_id_group_mapping_uid` ON `user_role` (org_id, user_id, role_id, group_mapping_uid)", + "CREATE TABLE `user_stats` (`id` INT64 NOT NULL GENERATED BY DEFAULT AS IDENTITY (BIT_REVERSED_POSITIVE), `user_id` INT64 NOT NULL, `billing_role` STRING(40) NOT NULL, `created` TIMESTAMP NOT NULL, `updated` TIMESTAMP NOT NULL) PRIMARY KEY (id)", + "CREATE UNIQUE NULL_FILTERED INDEX `UQE_user_stats_user_id` ON `user_stats` (user_id)" ] diff --git a/pkg/services/sqlstore/migrator/snapshot/spanner-log.json b/pkg/services/sqlstore/migrator/snapshot/spanner-log.json index 3fa7cb68a16..f9f39d4083b 100644 --- a/pkg/services/sqlstore/migrator/snapshot/spanner-log.json +++ b/pkg/services/sqlstore/migrator/snapshot/spanner-log.json @@ -577,6 +577,7 @@ "create sso_setting table", "copy kvstore migration status to each org", "add back entry for orgid=0 migrated status", + "managed dashboard permissions annotation actions migration", "create cloud_migration table v1", "create cloud_migration_run table v1", "add stack_id column", @@ -640,5 +641,119 @@ "populate rule guid in alert rule table", "add index in alert_rule_version table on rule_org_id, rule_uid, rule_guid and version columns", "add index in alert_rule_version table on rule_guid and version columns", - "add index in alert_rule table on guid columns" + "add index in alert_rule table on guid columns", + "create data_source_usage_by_day table", + "create data_source_usage_by_day(data_source_id) index", + "create data_source_usage_by_day(data_source_id, day) unique index", + "create dashboard_usage_by_day table", + "create dashboard_usage_sums table", + "create dashboard_usage_by_day(dashboard_id) index", + "create dashboard_usage_by_day(dashboard_id, day) index", + "add column errors_last_1_days to dashboard_usage_sums", + "add column errors_last_7_days to dashboard_usage_sums", + "add column errors_last_30_days to dashboard_usage_sums", + "add column errors_total to dashboard_usage_sums", + "create dashboard_public_usage_by_day table", + "add column cached_queries to dashboard_usage_by_day table", + "add column cached_queries to dashboard_public_usage_by_day table", + "add column dashboard_uid to dashboard_usage_sums", + "add column org_id to dashboard_usage_sums", + "add column dashboard_uid to dashboard_usage_by_day", + "add column org_id to dashboard_usage_by_day", + "create dashboard_usage_by_day(dashboard_uid, org_id, day) unique index", + "Add missing dashboard_uid and org_id to dashboard_usage_by_day and dashboard_usage_sums", + "Add dashboard_usage_sums(org_id, dashboard_uid) index", + "create user_dashboard_views table", + "add index user_dashboard_views.user_id", + "add index user_dashboard_views.dashboard_id", + "add unique index user_dashboard_views_user_id_dashboard_id", + "add org_id column to user_dashboard_views", + "add dashboard_uid column to user_dashboard_views", + "add unique index user_dashboard_views_org_id_dashboard_uid", + "add unique index user_dashboard_views_org_id_user_id_dashboard_uid", + "populate user_dashboard_views.dashboard_uid and user_dashboard_views.org_id from dashboard table", + "create user_stats table", + "add unique index user_stats(user_id)", + "create data_source_cache table", + "add index data_source_cache.data_source_id", + "add use_default_ttl column", + "add data_source_cache.data_source_uid column", + "remove abandoned data_source_cache records", + "update data_source_cache.data_source_uid value", + "add index data_source_cache.data_source_uid", + "add data_source_cache.ttl_resources_ms column", + "update data_source_cache.ttl_resources_ms to have the same value as ttl_ms", + "create data_source_acl table", + "add index data_source_acl.data_source_id", + "add unique index datasource_acl.unique", + "create license_token table", + "drop recorded_queries table v14", + "drop recording_rules table v14", + "create recording_rules table v14", + "create remote_write_targets table v1", + "Add prom_name to recording_rules table", + "ensure remote_write_targets table", + "create report config table v1", + "Add index report.user_id", + "add index to dashboard_id", + "add index to org_id", + "Add timezone to the report", + "Add time_from to the report", + "Add time_to to the report", + "Add PDF landscape option to the report", + "Add monthly day scheduling option to the report", + "Add PDF layout option to the report", + "Add PDF orientation option to the report", + "Update report pdf_orientation from pdf_landscape", + "create report settings table", + "Add dashboard_uid field to the report", + "Add template_vars field to the report", + "Add option to include dashboard url in the report", + "Add state field to the report", + "Add option to add CSV files to the report", + "Add scheduling start date", + "Add missing schedule_start date for old reports", + "Add scheduling end date", + "Add schedulinng custom interval frequency", + "Add scheduling custom interval amount", + "Add workdays only flag to report", + "create report dashboards table", + "Add index report_dashboards.report_id", + "Migrate report fields into report_dashboards", + "Add formats option to the report", + "Migrate reports with csv enabled", + "Migrate ancient reports", + "Add created column in report_dashboards", + "Add scale_factor to the report", + "Alter scale_factor from TINYINT to SMALLINT", + "Add uid column to report", + "Add unique index reports_org_id_uid", + "Add pdf show template variable values to the report", + "Add pdf combine in one file", + "Add pdf theme to report settings table", + "Add email subject to the report", + "Populate email subject with report name", + "Add embedded image theme to report settings table", + "create team group table", + "add index team_group.org_id", + "add unique index team_group.org_id_team_id_group_id", + "add index team_group.group_id", + "create settings table", + "add unique index settings.section_key", + "add setting.encrypted_value", + "migrate role names", + "rename orgs roles", + "remove duplicated org role", + "migrate alerting role names", + "data source permissions", + "data source uid permissions", + "rename permissions:delegate scope", + "remove invalid managed permissions", + "builtin role migration", + "seed permissions migration", + "managed permissions migration enterprise", + "create table dashboard_public_email_share", + "create table dashboard_public_magic_link", + "create table dashboard_public_session", + "add last_seen_at column" ] From d5451f2e130a06b06f8a59e745e7fba3b1c9002e Mon Sep 17 00:00:00 2001 From: Ieva Date: Mon, 10 Mar 2025 14:58:31 +0000 Subject: [PATCH 12/63] Docs: Remove reference to a non-existent action (#101874) remove reference to a non-existent action --- .../access-control/rbac-fixed-basic-role-definitions/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md b/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md index 2c328c749b8..8458e4d9355 100644 --- a/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md +++ b/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md @@ -94,7 +94,7 @@ To learn how to use the roles API to determine the role UUIDs, refer to [Manage | `fixed:authentication.config:writer` | `fixed_0rYhZ2Qnzs8AdB1nX7gexk3fHDw` | `settings:read` for scope `settings:auth.saml:*`
`settings:write` for scope `settings:auth.saml:*` | Read and update authentication and SAML settings. | | `fixed:dashboards:creator` | `fixed_ZorKUcEPCM01A1fPakEzGBUyU64` | `dashboards:create`
`folders:read` | Create dashboards. | | `fixed:dashboards:reader` | `fixed_Sgr67JTOhjQGFlzYRahOe45TdWM` | `dashboards:read` | Read all dashboards. | -| `fixed:dashboards:writer` | `fixed_OK2YOQGIoI1G031hVzJB6rAJQAs` | All permissions from `fixed:dashboards:reader` and
`dashboards:write`
`dashboards:edit`
`dashboards:delete`
`dashboards:create`
`dashboards.permissions:read`
`dashboards.permissions:write` | Read, create, update, and delete all dashboards. | +| `fixed:dashboards:writer` | `fixed_OK2YOQGIoI1G031hVzJB6rAJQAs` | All permissions from `fixed:dashboards:reader` and
`dashboards:write`
`dashboards:delete`
`dashboards:create`
`dashboards.permissions:read`
`dashboards.permissions:write` | Read, create, update, and delete all dashboards. | | `fixed:dashboards.insights:reader` | `fixed_JlBJ2_gizP8zhgaeGE2rjyZe2Rs` | `dashboards.insights:read` | Read dashboard insights data and see presence indicators. | | `fixed:dashboards.permissions:reader` | `fixed_f17oxuXW_58LL8mYJsm4T_mCeIw` | `dashboards.permissions:read` | Read all dashboard permissions. | | `fixed:dashboards.permissions:writer` | `fixed_CcznxhWX_Yqn8uWMXMQ-b5iFW9k` | All permissions from `fixed:dashboards.permissions:reader` and
`dashboards.permissions:write` | Read and update all dashboard permissions. | From 0ce67dad74659c4d36dfe93709402a5bcf55d43c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20=C5=A0tibran=C3=BD?= Date: Mon, 10 Mar 2025 15:59:06 +0100 Subject: [PATCH 13/63] Spanner: support for lastInsertId (#101770) * Support for returning inserted ID in Spanner. * Convert bytes to string when storing them into text column. --- pkg/services/sqlstore/migrator/migrator.go | 6 +- pkg/services/sqlstore/session.go | 9 ++- pkg/util/xorm/go.mod | 4 +- pkg/util/xorm/go.sum | 4 ++ pkg/util/xorm/session_insert.go | 75 +++++++++------------- pkg/util/xorm/statement.go | 12 +++- pkg/util/xorm/xorm_spanner_test.go | 29 +++++++++ pkg/util/xorm/xorm_test.go | 44 +++++++++++-- 8 files changed, 124 insertions(+), 59 deletions(-) create mode 100644 pkg/util/xorm/xorm_spanner_test.go diff --git a/pkg/services/sqlstore/migrator/migrator.go b/pkg/services/sqlstore/migrator/migrator.go index b970711a80e..6e297af23a0 100644 --- a/pkg/services/sqlstore/migrator/migrator.go +++ b/pkg/services/sqlstore/migrator/migrator.go @@ -240,19 +240,19 @@ func (mg *Migrator) run(ctx context.Context) (err error) { migrationLogExists, err := mg.DBEngine.IsTableExist(mg.tableName) if err != nil { - return fmt.Errorf("%v: %w", "failed to check table existence", err) + return fmt.Errorf("failed to check table existence: %w", err) } if !migrationLogExists { // Check if dialect can initialize database from a snapshot. err := mg.Dialect.CreateDatabaseFromSnapshot(ctx, mg.DBEngine, mg.tableName) if err != nil { - return fmt.Errorf("%v: %w", "failed to create database from snapshot", err) + return fmt.Errorf("failed to create database from snapshot: %w", err) } migrationLogExists, err = mg.DBEngine.IsTableExist(mg.tableName) if err != nil { - return fmt.Errorf("%v: %w", "failed to check table existence after applying snapshot", err) + return fmt.Errorf("failed to check table existence after applying snapshot: %w", err) } } diff --git a/pkg/services/sqlstore/session.go b/pkg/services/sqlstore/session.go index 6abb32484a1..d1752451a7a 100644 --- a/pkg/services/sqlstore/session.go +++ b/pkg/services/sqlstore/session.go @@ -11,6 +11,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/otel/trace/noop" + "xorm.io/xorm" "github.com/grafana/grafana/pkg/apimachinery/errutil" @@ -140,14 +141,18 @@ func (sess *DBSession) InsertId(bean any, dialect migrator.Dialect) error { } func (sess *DBSession) WithReturningID(driverName string, query string, args []any) (int64, error) { - supported := driverName != migrator.Postgres var id int64 - if !supported { + if driverName == migrator.Postgres { query = fmt.Sprintf("%s RETURNING id", query) if _, err := sess.SQL(query, args...).Get(&id); err != nil { return id, err } } else { + if driverName == migrator.Spanner { + // Only works with INSERT statements. + query = fmt.Sprintf("%s THEN RETURN id", query) + } + sqlOrArgs := append([]any{query}, args...) res, err := sess.Exec(sqlOrArgs...) if err != nil { diff --git a/pkg/util/xorm/go.mod b/pkg/util/xorm/go.mod index 6c41f93b6f3..310a1bbc263 100644 --- a/pkg/util/xorm/go.mod +++ b/pkg/util/xorm/go.mod @@ -3,7 +3,9 @@ module github.com/grafana/grafana/pkg/util/xorm go 1.23.7 require ( + cloud.google.com/go/spanner v1.75.0 github.com/googleapis/go-sql-spanner v1.11.1 + github.com/grafana/grafana v5.4.5+incompatible github.com/mattn/go-sqlite3 v1.14.22 github.com/stretchr/testify v1.10.0 xorm.io/builder v0.3.6 @@ -19,9 +21,9 @@ require ( cloud.google.com/go/iam v1.3.1 // indirect cloud.google.com/go/longrunning v0.6.4 // indirect cloud.google.com/go/monitoring v1.23.0 // indirect - cloud.google.com/go/spanner v1.75.0 // indirect github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.2 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 // indirect + github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect diff --git a/pkg/util/xorm/go.sum b/pkg/util/xorm/go.sum index f93449ff49b..7febbb40654 100644 --- a/pkg/util/xorm/go.sum +++ b/pkg/util/xorm/go.sum @@ -632,6 +632,8 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -832,6 +834,8 @@ github.com/googleapis/go-sql-spanner v1.11.1 h1:z3ThtKV5HFvaNv9UGc26+ggS+lS0dsCA github.com/googleapis/go-sql-spanner v1.11.1/go.mod h1:fuA5q4yMS3SZiVfRr5bvksPNk7zUn/irbQW62H/ffZw= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/grafana/grafana v5.4.5+incompatible h1:xNuhSBxLgwDwesuQIAhQu1QCk6tD0TAghKHE36/hxrs= +github.com/grafana/grafana v5.4.5+incompatible/go.mod h1:U8QyUclJHj254BFcuw45p6sg7eeGYX44qn1ShYo5rGE= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= diff --git a/pkg/util/xorm/session_insert.go b/pkg/util/xorm/session_insert.go index e3fe11c1439..502a55e769e 100644 --- a/pkg/util/xorm/session_insert.go +++ b/pkg/util/xorm/session_insert.go @@ -438,9 +438,11 @@ func (session *Session) innerInsert(bean any) (int64, error) { } if len(table.AutoIncrement) > 0 && session.engine.dialect.DBType() == core.POSTGRES { - if _, err := buf.WriteString(" RETURNING " + session.engine.Quote(table.AutoIncrement)); err != nil { - return 0, err - } + buf.WriteString(" RETURNING " + session.engine.Quote(table.AutoIncrement)) + } + + if len(table.AutoIncrement) > 0 && session.engine.dialect.DBType() == "spanner" { + buf.WriteString(" THEN RETURN " + session.engine.Quote(table.AutoIncrement)) } sqlStr := buf.String() @@ -476,6 +478,7 @@ func (session *Session) innerInsert(bean any) (int64, error) { // for postgres, many of them didn't implement lastInsertId, so we should // implemented it ourself. + var insertID, rowsAffected int64 if session.engine.dialect.DBType() == core.ORACLE && len(table.AutoIncrement) > 0 { res, err := session.queryBytes("select seq_atable.currval from dual", args...) if err != nil { @@ -498,23 +501,11 @@ func (session *Session) innerInsert(bean any) (int64, error) { } idByte := res[0][table.AutoIncrement] - id, err := strconv.ParseInt(string(idByte), 10, 64) - if err != nil || id <= 0 { + insertID, err = strconv.ParseInt(string(idByte), 10, 64) + if err != nil || insertID <= 0 { return 1, err } - - aiValue, err := table.AutoIncrColumn().ValueOf(bean) - if err != nil { - session.engine.logger.Error(err) - } - - if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() { - return 1, nil - } - - aiValue.Set(int64ToIntValue(id, aiValue.Type())) - - return 1, nil + rowsAffected = 1 } else if len(table.AutoIncrement) > 0 && (session.engine.dialect.DBType() == core.POSTGRES) { res, err := session.queryBytes(sqlStr, args...) @@ -537,23 +528,11 @@ func (session *Session) innerInsert(bean any) (int64, error) { } idByte := res[0][table.AutoIncrement] - id, err := strconv.ParseInt(string(idByte), 10, 64) - if err != nil || id <= 0 { + insertID, err = strconv.ParseInt(string(idByte), 10, 64) + if err != nil || insertID <= 0 { return 1, err } - - aiValue, err := table.AutoIncrColumn().ValueOf(bean) - if err != nil { - session.engine.logger.Error(err) - } - - if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() { - return 1, nil - } - - aiValue.Set(int64ToIntValue(id, aiValue.Type())) - - return 1, nil + rowsAffected = 1 } else { res, err := session.exec(sqlStr, args...) if err != nil { @@ -575,25 +554,29 @@ func (session *Session) innerInsert(bean any) (int64, error) { return res.RowsAffected() } - var id int64 - id, err = res.LastInsertId() - if err != nil || id <= 0 { + insertID, err = res.LastInsertId() + if err != nil || insertID <= 0 { return res.RowsAffected() } - aiValue, err := table.AutoIncrColumn().ValueOf(bean) + rowsAffected, err = res.RowsAffected() if err != nil { - session.engine.logger.Error(err) + return 0, err } - - if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() { - return res.RowsAffected() - } - - aiValue.Set(int64ToIntValue(id, aiValue.Type())) - - return res.RowsAffected() } + + // Set insertID back to the bean. + aiValue, err := table.AutoIncrColumn().ValueOf(bean) + if err != nil { + session.engine.logger.Error(err) + } + + if aiValue == nil || !aiValue.IsValid() || !aiValue.CanSet() { + return rowsAffected, nil + } + + aiValue.Set(int64ToIntValue(insertID, aiValue.Type())) + return rowsAffected, nil } // InsertOne insert only one struct into database as a record. diff --git a/pkg/util/xorm/statement.go b/pkg/util/xorm/statement.go index e58903dea3e..a2ec2fd7aea 100644 --- a/pkg/util/xorm/statement.go +++ b/pkg/util/xorm/statement.go @@ -320,7 +320,11 @@ func (statement *Statement) buildUpdates(bean any, if err != nil { engine.logger.Error(err) } else { - val = data + if col.SQLType.IsText() { + val = string(data) + } else { + val = data + } } goto APPEND } @@ -331,7 +335,11 @@ func (statement *Statement) buildUpdates(bean any, if err != nil { engine.logger.Error(err) } else { - val = data + if col.SQLType.IsText() { + val = string(data) + } else { + val = data + } } goto APPEND } diff --git a/pkg/util/xorm/xorm_spanner_test.go b/pkg/util/xorm/xorm_spanner_test.go new file mode 100644 index 00000000000..a9c43a0b77d --- /dev/null +++ b/pkg/util/xorm/xorm_spanner_test.go @@ -0,0 +1,29 @@ +//go:build enterprise || pro + +package xorm + +import ( + "fmt" + "testing" + + "cloud.google.com/go/spanner/spannertest" + _ "github.com/mattn/go-sqlite3" + "github.com/stretchr/testify/require" +) + +func TestBasicOperationsWithSpanner(t *testing.T) { + span, err := spannertest.NewServer("localhost:0") + require.NoError(t, err) + defer span.Close() + + eng, err := NewEngine("spanner", fmt.Sprintf("%s/projects/test/instances/test/databases/test;usePlainText=true", span.Addr)) + require.NoError(t, err) + require.NotNil(t, eng) + require.Equal(t, "spanner", eng.DriverName()) + + _, err = eng.Exec("CREATE TABLE test_struct (id int64, comment string(max), json string(max)) primary key (id)") + require.NoError(t, err) + + // Currently broken because simple INSERT into spannertest doesn't work: https://github.com/googleapis/go-sql-spanner/issues/392 + // testBasicOperations(t, eng) +} diff --git a/pkg/util/xorm/xorm_test.go b/pkg/util/xorm/xorm_test.go index 988528edb6b..4dee7eb8294 100644 --- a/pkg/util/xorm/xorm_test.go +++ b/pkg/util/xorm/xorm_test.go @@ -5,13 +5,47 @@ import ( _ "github.com/mattn/go-sqlite3" "github.com/stretchr/testify/require" + + "github.com/grafana/grafana/pkg/components/simplejson" ) -func TestNewEngine(t *testing.T) { - t.Run("successfully create a new engine", func(t *testing.T) { - eng, err := NewEngine("sqlite3", "./test.db") +func TestBasicOperationsWithSqlite(t *testing.T) { + eng, err := NewEngine("sqlite3", ":memory:") + require.NoError(t, err) + require.NotNil(t, eng) + require.Equal(t, "sqlite3", eng.DriverName()) + + _, err = eng.Exec("CREATE TABLE test_struct (id int primary key, comment text, json text)") + require.NoError(t, err) + + testBasicOperations(t, eng) +} + +func testBasicOperations(t *testing.T, eng *Engine) { + t.Run("insert object", func(t *testing.T) { + obj := &TestStruct{Comment: "test comment"} + _, err := eng.Insert(obj) + require.NoError(t, err) + require.Equal(t, int64(1), obj.Id) + }) + + t.Run("update object with json field", func(t *testing.T) { + sess := eng.NewSession() + defer sess.Close() + + obj := &TestStruct{Comment: "new comment"} + _, err := sess.Insert(obj) + require.NoError(t, err) + require.NotZero(t, obj.Id) + + obj.Json = simplejson.MustJson([]byte(`{"test": "test", "key": null}`)) + _, err = sess.Update(obj) require.NoError(t, err) - require.NotNil(t, eng) - require.Equal(t, "sqlite3", eng.DriverName()) }) } + +type TestStruct struct { + Id int64 + Comment string + Json *simplejson.Json +} From 8c51af49e5fb0680f98e086f9ac40920b16e2826 Mon Sep 17 00:00:00 2001 From: Tito Lins Date: Mon, 10 Mar 2025 16:59:21 +0100 Subject: [PATCH 14/63] Alertmanager: upgrade alerting (#101870) --- go.mod | 2 +- go.sum | 4 ++-- pkg/storage/unified/apistore/go.mod | 2 +- pkg/storage/unified/apistore/go.sum | 4 ++-- pkg/storage/unified/resource/go.mod | 2 +- pkg/storage/unified/resource/go.sum | 4 ++-- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index b98b2a10987..e3249c27b66 100644 --- a/go.mod +++ b/go.mod @@ -73,7 +73,7 @@ require ( github.com/googleapis/go-sql-spanner v1.11.1 // @grafana/grafana-search-and-storage github.com/gorilla/mux v1.8.1 // @grafana/grafana-backend-group github.com/gorilla/websocket v1.5.3 // @grafana/grafana-app-platform-squad - github.com/grafana/alerting v0.0.0-20250307175047-1d263576d356 // @grafana/alerting-backend + github.com/grafana/alerting v0.0.0-20250310104713-16b885f1c79e // @grafana/alerting-backend github.com/grafana/authlib v0.0.0-20250305132846-37f49eb947fa // @grafana/identity-access-team github.com/grafana/authlib/types v0.0.0-20250224151205-5ef97131cc82 // @grafana/identity-access-team github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics diff --git a/go.sum b/go.sum index 5b7c938ba0b..680b16f06d5 100644 --- a/go.sum +++ b/go.sum @@ -1540,8 +1540,8 @@ github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7Fsg github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grafana/alerting v0.0.0-20250307175047-1d263576d356 h1:71o8Bxw/wg+aBRUASiGux67gDEUC2bqq3I+x2hw8eIc= -github.com/grafana/alerting v0.0.0-20250307175047-1d263576d356/go.mod h1:hdGB3dSl8Ma9Rjo2YiAEAjMkZ5HiNJbNDqRKDefRZrM= +github.com/grafana/alerting v0.0.0-20250310104713-16b885f1c79e h1:noJzp/qZGIto4XdZkvj2EKQ1bQeqCRs0bedxdJN17sQ= +github.com/grafana/alerting v0.0.0-20250310104713-16b885f1c79e/go.mod h1:HfvjmU3UqCIpoy9Z2wgKGrZ4A5vz+yQlP9ZXvCfEkiA= github.com/grafana/authlib v0.0.0-20250305132846-37f49eb947fa h1:08Wh/svkv8WpDuOBBKAzSPa14gKjYLZvQJsHWXLjPuc= github.com/grafana/authlib v0.0.0-20250305132846-37f49eb947fa/go.mod h1:XVpdLhaeYqz414FmGnW00/0vTe1x8c0GRH3KaeRtyg0= github.com/grafana/authlib/types v0.0.0-20250224151205-5ef97131cc82 h1:DnRUYiAotHXnrfYJCvhH1NkiyWVcPm5Pd+P7Ugqt/d8= diff --git a/pkg/storage/unified/apistore/go.mod b/pkg/storage/unified/apistore/go.mod index 7c11e4a2ce5..68d9aceafbc 100644 --- a/pkg/storage/unified/apistore/go.mod +++ b/pkg/storage/unified/apistore/go.mod @@ -203,7 +203,7 @@ require ( github.com/googleapis/go-sql-spanner v1.11.1 // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect - github.com/grafana/alerting v0.0.0-20250307175047-1d263576d356 // indirect + github.com/grafana/alerting v0.0.0-20250310104713-16b885f1c79e // indirect github.com/grafana/authlib v0.0.0-20250305132846-37f49eb947fa // indirect github.com/grafana/dataplane/sdata v0.0.9 // indirect github.com/grafana/dskit v0.0.0-20241105154643-a6b453a88040 // indirect diff --git a/pkg/storage/unified/apistore/go.sum b/pkg/storage/unified/apistore/go.sum index e77f6f4f072..2a54e8f0a54 100644 --- a/pkg/storage/unified/apistore/go.sum +++ b/pkg/storage/unified/apistore/go.sum @@ -1253,8 +1253,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grafana/alerting v0.0.0-20250307175047-1d263576d356 h1:71o8Bxw/wg+aBRUASiGux67gDEUC2bqq3I+x2hw8eIc= -github.com/grafana/alerting v0.0.0-20250307175047-1d263576d356/go.mod h1:hdGB3dSl8Ma9Rjo2YiAEAjMkZ5HiNJbNDqRKDefRZrM= +github.com/grafana/alerting v0.0.0-20250310104713-16b885f1c79e h1:noJzp/qZGIto4XdZkvj2EKQ1bQeqCRs0bedxdJN17sQ= +github.com/grafana/alerting v0.0.0-20250310104713-16b885f1c79e/go.mod h1:HfvjmU3UqCIpoy9Z2wgKGrZ4A5vz+yQlP9ZXvCfEkiA= github.com/grafana/authlib v0.0.0-20250305132846-37f49eb947fa h1:08Wh/svkv8WpDuOBBKAzSPa14gKjYLZvQJsHWXLjPuc= github.com/grafana/authlib v0.0.0-20250305132846-37f49eb947fa/go.mod h1:XVpdLhaeYqz414FmGnW00/0vTe1x8c0GRH3KaeRtyg0= github.com/grafana/authlib/types v0.0.0-20250224151205-5ef97131cc82 h1:DnRUYiAotHXnrfYJCvhH1NkiyWVcPm5Pd+P7Ugqt/d8= diff --git a/pkg/storage/unified/resource/go.mod b/pkg/storage/unified/resource/go.mod index f9a6be9a2c4..0a5d4a68146 100644 --- a/pkg/storage/unified/resource/go.mod +++ b/pkg/storage/unified/resource/go.mod @@ -131,7 +131,7 @@ require ( github.com/googleapis/gax-go/v2 v2.14.1 // indirect github.com/googleapis/go-sql-spanner v1.11.1 // indirect github.com/gorilla/mux v1.8.1 // indirect - github.com/grafana/alerting v0.0.0-20250307175047-1d263576d356 // indirect + github.com/grafana/alerting v0.0.0-20250310104713-16b885f1c79e // indirect github.com/grafana/dataplane/sdata v0.0.9 // indirect github.com/grafana/grafana-app-sdk/logging v0.30.0 // indirect github.com/grafana/grafana-aws-sdk v0.31.5 // indirect diff --git a/pkg/storage/unified/resource/go.sum b/pkg/storage/unified/resource/go.sum index 7f268922f89..aef2f25aee9 100644 --- a/pkg/storage/unified/resource/go.sum +++ b/pkg/storage/unified/resource/go.sum @@ -1150,8 +1150,8 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/grafana/alerting v0.0.0-20250307175047-1d263576d356 h1:71o8Bxw/wg+aBRUASiGux67gDEUC2bqq3I+x2hw8eIc= -github.com/grafana/alerting v0.0.0-20250307175047-1d263576d356/go.mod h1:hdGB3dSl8Ma9Rjo2YiAEAjMkZ5HiNJbNDqRKDefRZrM= +github.com/grafana/alerting v0.0.0-20250310104713-16b885f1c79e h1:noJzp/qZGIto4XdZkvj2EKQ1bQeqCRs0bedxdJN17sQ= +github.com/grafana/alerting v0.0.0-20250310104713-16b885f1c79e/go.mod h1:HfvjmU3UqCIpoy9Z2wgKGrZ4A5vz+yQlP9ZXvCfEkiA= github.com/grafana/authlib v0.0.0-20250305132846-37f49eb947fa h1:08Wh/svkv8WpDuOBBKAzSPa14gKjYLZvQJsHWXLjPuc= github.com/grafana/authlib v0.0.0-20250305132846-37f49eb947fa/go.mod h1:XVpdLhaeYqz414FmGnW00/0vTe1x8c0GRH3KaeRtyg0= github.com/grafana/authlib/types v0.0.0-20250224151205-5ef97131cc82 h1:DnRUYiAotHXnrfYJCvhH1NkiyWVcPm5Pd+P7Ugqt/d8= From 8142aef64d8cff9bf554891b89526adb9f57f3d0 Mon Sep 17 00:00:00 2001 From: Andres Martinez Gotor Date: Mon, 10 Mar 2025 17:09:11 +0100 Subject: [PATCH 15/63] Advisor: Avoid evaluating a check for another namespace (#101885) --- apps/advisor/pkg/app/app.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/apps/advisor/pkg/app/app.go b/apps/advisor/pkg/app/app.go index a640682b0fc..efa9188f8e5 100644 --- a/apps/advisor/pkg/app/app.go +++ b/apps/advisor/pkg/app/app.go @@ -13,6 +13,7 @@ import ( "github.com/grafana/grafana/apps/advisor/pkg/app/checks" "github.com/grafana/grafana/apps/advisor/pkg/app/checkscheduler" "github.com/grafana/grafana/apps/advisor/pkg/app/checktyperegisterer" + "github.com/grafana/grafana/pkg/infra/log" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/klog/v2" ) @@ -24,6 +25,12 @@ func New(cfg app.Config) (app.App, error) { return nil, fmt.Errorf("invalid config type") } checkRegistry := specificConfig.CheckRegistry + stackID := specificConfig.StackID + namespace, err := checks.GetNamespace(stackID) + if err != nil { + return nil, err + } + log := log.New("advisor.app") // Prepare storage client clientGenerator := k8s.NewClientRegistry(cfg.KubeConfig, k8s.ClientConfig{}) @@ -60,6 +67,13 @@ func New(cfg app.Config) (app.App, error) { }, Watcher: &simple.Watcher{ AddFunc: func(ctx context.Context, obj resource.Object) error { + log.Debug("Adding check", "namespace", obj.GetNamespace()) + if obj.GetNamespace() != namespace { + log.Debug("Skipping check in namespace", "namespace", obj.GetNamespace()) + return nil + } else { + log.Debug("Processing check in namespace", "namespace", obj.GetNamespace()) + } check, err := getCheck(obj, checkMap) if err != nil { return err From 9858e40a020cbd8a914103e10a611f742860efab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20=C5=A0tibran=C3=BD?= Date: Mon, 10 Mar 2025 17:37:44 +0100 Subject: [PATCH 16/63] Spanner: Add trivial sequence number generator. (#101777) * Add trivial sequence number generator. --- pkg/util/xorm/engine.go | 6 ++- pkg/util/xorm/sequence.go | 69 +++++++++++++++++++++++++++++++++ pkg/util/xorm/sequence_test.go | 31 +++++++++++++++ pkg/util/xorm/session_insert.go | 33 +++++++++------- pkg/util/xorm/xorm.go | 4 ++ 5 files changed, 128 insertions(+), 15 deletions(-) create mode 100644 pkg/util/xorm/sequence.go create mode 100644 pkg/util/xorm/sequence_test.go diff --git a/pkg/util/xorm/engine.go b/pkg/util/xorm/engine.go index 88135ef7a7c..c64b7b29f4f 100644 --- a/pkg/util/xorm/engine.go +++ b/pkg/util/xorm/engine.go @@ -42,7 +42,8 @@ type Engine struct { tagHandlers map[string]tagHandler - defaultContext context.Context + defaultContext context.Context + sequenceGenerator *sequenceGenerator // If not nil, this generator is used to generate auto-increment values for inserts. } // CondDeleted returns the conditions whether a record is soft deleted. @@ -237,6 +238,9 @@ func (engine *Engine) NewSession() *Session { // Close the engine func (engine *Engine) Close() error { + if engine.sequenceGenerator != nil { + engine.sequenceGenerator.close() + } return engine.db.Close() } diff --git a/pkg/util/xorm/sequence.go b/pkg/util/xorm/sequence.go new file mode 100644 index 00000000000..bb74e2064b6 --- /dev/null +++ b/pkg/util/xorm/sequence.go @@ -0,0 +1,69 @@ +package xorm + +import ( + "context" + "database/sql" + "errors" + "fmt" +) + +type sequenceGenerator struct { + db *sql.DB + sequencesTable string +} + +func newSequenceGenerator(db *sql.DB) *sequenceGenerator { + return &sequenceGenerator{ + db: db, + sequencesTable: "autoincrement_sequences", + } +} + +func (sg *sequenceGenerator) Next(ctx context.Context, table, column string) (int64, error) { + // Current implementation fetches new value for each Next call. + key := fmt.Sprintf("%s:%s", table, column) + + tx, err := sg.db.BeginTx(ctx, &sql.TxOptions{Isolation: sql.LevelSerializable}) + if err != nil { + return 0, err + } + + // TODO: "FOR UPDATE". (Somehow this doesn't seem to be supported in Spanner emulator?) + r, err := tx.QueryContext(ctx, "SELECT next_value FROM "+sg.sequencesTable+" WHERE name = ?", key) + if err != nil { + err2 := tx.Rollback() + return 0, errors.Join(err, err2) + } + defer r.Close() + + // Sequence doesn't exist yet. Return 1, and put 2 into the table. + if !r.Next() { + if err := r.Err(); err != nil { + return 0, errors.Join(err, tx.Rollback()) + } + val := int64(1) + + _, err := tx.ExecContext(ctx, "INSERT INTO "+sg.sequencesTable+" (name, next_value) VALUES(?, ?)", key, val+1) + if err != nil { + return 0, errors.Join(err, tx.Rollback()) + } + + return val, tx.Commit() + } + + var val int64 + if err := r.Scan(&val); err != nil { + return 0, errors.Join(err, tx.Rollback()) + } + + _, err = tx.ExecContext(ctx, "UPDATE "+sg.sequencesTable+" SET next_value = ? WHERE name = ?", val+1, key) + if err != nil { + return 0, errors.Join(err, tx.Rollback()) + } + + return val, tx.Commit() +} + +func (sg *sequenceGenerator) close() { + // Nothing to do just yet. +} diff --git a/pkg/util/xorm/sequence_test.go b/pkg/util/xorm/sequence_test.go new file mode 100644 index 00000000000..289e65e4034 --- /dev/null +++ b/pkg/util/xorm/sequence_test.go @@ -0,0 +1,31 @@ +package xorm + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestSequenceGenerator(t *testing.T) { + eng, err := NewEngine("sqlite3", ":memory:") + require.NoError(t, err) + require.NotNil(t, eng) + require.Equal(t, "sqlite3", eng.DriverName()) + + _, err = eng.Exec("CREATE TABLE `autoincrement_sequences` (`name` STRING(128) NOT NULL PRIMARY KEY, `next_value` INT64 NOT NULL)") + require.NoError(t, err) + + sg := newSequenceGenerator(eng.db.DB) + val, err := sg.Next(context.Background(), "test", "test") + require.NoError(t, err) + require.Equal(t, int64(1), val) + + val, err = sg.Next(context.Background(), "test", "different") + require.NoError(t, err) + require.Equal(t, int64(1), val) + + val, err = sg.Next(context.Background(), "test", "different") + require.NoError(t, err) + require.Equal(t, int64(2), val) +} diff --git a/pkg/util/xorm/session_insert.go b/pkg/util/xorm/session_insert.go index 502a55e769e..09016f17255 100644 --- a/pkg/util/xorm/session_insert.go +++ b/pkg/util/xorm/session_insert.go @@ -345,20 +345,25 @@ func (session *Session) innerInsert(bean any) (int64, error) { return 0, err } - //// XXX: hack to handle autoincrement in spanner - //if len(table.AutoIncrement) > 0 && session.engine.dialect.DBType() == "spanner" { - // var found bool - // for _, col := range colNames { - // if col == table.AutoIncrement { - // found = true - // break - // } - // } - // if !found { - // colNames = append(colNames, table.AutoIncrement) - // args = append(args, rand.Int63n(9e15)) - // } - //} + // If engine has a sequence number generator, use it to produce values for auto-increment columns. + if len(table.AutoIncrement) > 0 && session.engine.sequenceGenerator != nil { + var found bool + for _, col := range colNames { + if col == table.AutoIncrement { + found = true + break + } + } + if !found { + seq, err := session.engine.sequenceGenerator.Next(session.ctx, table.Name, table.AutoIncrement) + if err != nil { + return 0, fmt.Errorf("failed to generate next value for auto_increment columns: %v", err) + } + + colNames = append(colNames, table.AutoIncrement) + args = append(args, seq) + } + } exprs := session.statement.exprColumns colPlaces := strings.Repeat("?, ", len(colNames)) diff --git a/pkg/util/xorm/xorm.go b/pkg/util/xorm/xorm.go index b3178773518..40c1552cec5 100644 --- a/pkg/util/xorm/xorm.go +++ b/pkg/util/xorm/xorm.go @@ -106,5 +106,9 @@ func NewEngine(driverName string, dataSourceName string) (*Engine, error) { runtime.SetFinalizer(engine, close) + if dialect.DBType() == "spanner" { + engine.sequenceGenerator = newSequenceGenerator(db.DB) + } + return engine, nil } From 64f1df69d53405c9b5f328fb313ce3da4d5e992b Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Mon, 10 Mar 2025 19:48:53 +0300 Subject: [PATCH 17/63] Search: Rename managed object index (#101856) --- pkg/registry/apis/dashboard/legacy/client.go | 8 +- pkg/registry/apis/dashboard/legacy/storage.go | 4 +- pkg/registry/apis/dashboard/search_test.go | 4 +- pkg/storage/unified/apistore/store_test.go | 2 +- pkg/storage/unified/resource/client.go | 42 +- pkg/storage/unified/resource/document.go | 34 +- pkg/storage/unified/resource/document_test.go | 7 +- pkg/storage/unified/resource/resource.pb.go | 856 +++++++++--------- pkg/storage/unified/resource/resource.proto | 40 +- .../unified/resource/resource_grpc.pb.go | 104 +-- pkg/storage/unified/resource/search.go | 36 +- pkg/storage/unified/resource/server.go | 10 +- .../resource/testdata/playlist-resource.json | 2 +- pkg/storage/unified/search/bleve.go | 57 +- pkg/storage/unified/search/bleve_mappings.go | 14 +- .../unified/search/bleve_mappings_test.go | 3 +- .../unified/search/bleve_search_test.go | 52 +- pkg/storage/unified/search/bleve_test.go | 36 +- .../search/testdata/doc/folder-aaa-out.json | 3 +- .../search/testdata/doc/folder-bbb-out.json | 3 +- pkg/storage/unified/sql/search.go | 4 +- pkg/storage/unified/sql/service.go | 2 +- 22 files changed, 688 insertions(+), 635 deletions(-) diff --git a/pkg/registry/apis/dashboard/legacy/client.go b/pkg/registry/apis/dashboard/legacy/client.go index db0b0403f6b..afcd1e0fddf 100644 --- a/pkg/registry/apis/dashboard/legacy/client.go +++ b/pkg/registry/apis/dashboard/legacy/client.go @@ -52,12 +52,12 @@ func (d *directResourceClient) List(ctx context.Context, in *resource.ListReques return d.server.List(ctx, in) } -func (d *directResourceClient) ListRepositoryObjects(ctx context.Context, in *resource.ListRepositoryObjectsRequest, opts ...grpc.CallOption) (*resource.ListRepositoryObjectsResponse, error) { - return d.server.ListRepositoryObjects(ctx, in) +func (d *directResourceClient) ListManagedObjects(ctx context.Context, in *resource.ListManagedObjectsRequest, opts ...grpc.CallOption) (*resource.ListManagedObjectsResponse, error) { + return d.server.ListManagedObjects(ctx, in) } -func (d *directResourceClient) CountRepositoryObjects(ctx context.Context, in *resource.CountRepositoryObjectsRequest, opts ...grpc.CallOption) (*resource.CountRepositoryObjectsResponse, error) { - return d.server.CountRepositoryObjects(ctx, in) +func (d *directResourceClient) CountManagedObjects(ctx context.Context, in *resource.CountManagedObjectsRequest, opts ...grpc.CallOption) (*resource.CountManagedObjectsResponse, error) { + return d.server.CountManagedObjects(ctx, in) } // PutBlob implements ResourceClient. diff --git a/pkg/registry/apis/dashboard/legacy/storage.go b/pkg/registry/apis/dashboard/legacy/storage.go index 463246120c4..fc787fe76fa 100644 --- a/pkg/registry/apis/dashboard/legacy/storage.go +++ b/pkg/registry/apis/dashboard/legacy/storage.go @@ -262,11 +262,11 @@ func (a *dashboardSqlAccess) Search(ctx context.Context, req *resource.ResourceS return a.dashboardSearchClient.Search(ctx, req) } -func (a *dashboardSqlAccess) ListRepositoryObjects(ctx context.Context, req *resource.ListRepositoryObjectsRequest) (*resource.ListRepositoryObjectsResponse, error) { +func (a *dashboardSqlAccess) ListManagedObjects(ctx context.Context, req *resource.ListManagedObjectsRequest) (*resource.ListManagedObjectsResponse, error) { return nil, fmt.Errorf("not implemented") } -func (a *dashboardSqlAccess) CountRepositoryObjects(context.Context, *resource.CountRepositoryObjectsRequest) (*resource.CountRepositoryObjectsResponse, error) { +func (a *dashboardSqlAccess) CountManagedObjects(context.Context, *resource.CountManagedObjectsRequest) (*resource.CountManagedObjectsResponse, error) { return nil, fmt.Errorf("not implemented") } diff --git a/pkg/registry/apis/dashboard/search_test.go b/pkg/registry/apis/dashboard/search_test.go index 70a669b5c55..08fb919f86f 100644 --- a/pkg/registry/apis/dashboard/search_test.go +++ b/pkg/registry/apis/dashboard/search_test.go @@ -674,7 +674,7 @@ func (m *MockClient) Search(ctx context.Context, in *resource.ResourceSearchRequ func (m *MockClient) GetStats(ctx context.Context, in *resource.ResourceStatsRequest, opts ...grpc.CallOption) (*resource.ResourceStatsResponse, error) { return nil, nil } -func (m *MockClient) CountRepositoryObjects(ctx context.Context, in *resource.CountRepositoryObjectsRequest, opts ...grpc.CallOption) (*resource.CountRepositoryObjectsResponse, error) { +func (m *MockClient) CountManagedObjects(ctx context.Context, in *resource.CountManagedObjectsRequest, opts ...grpc.CallOption) (*resource.CountManagedObjectsResponse, error) { return nil, nil } func (m *MockClient) Watch(ctx context.Context, in *resource.WatchRequest, opts ...grpc.CallOption) (resource.ResourceStore_WatchClient, error) { @@ -704,7 +704,7 @@ func (m *MockClient) PutBlob(ctx context.Context, in *resource.PutBlobRequest, o func (m *MockClient) List(ctx context.Context, in *resource.ListRequest, opts ...grpc.CallOption) (*resource.ListResponse, error) { return nil, nil } -func (m *MockClient) ListRepositoryObjects(ctx context.Context, in *resource.ListRepositoryObjectsRequest, opts ...grpc.CallOption) (*resource.ListRepositoryObjectsResponse, error) { +func (m *MockClient) ListManagedObjects(ctx context.Context, in *resource.ListManagedObjectsRequest, opts ...grpc.CallOption) (*resource.ListManagedObjectsResponse, error) { return nil, nil } func (m *MockClient) IsHealthy(ctx context.Context, in *resource.HealthCheckRequest, opts ...grpc.CallOption) (*resource.HealthCheckResponse, error) { diff --git a/pkg/storage/unified/apistore/store_test.go b/pkg/storage/unified/apistore/store_test.go index b5ada26a95c..3c66beda27d 100644 --- a/pkg/storage/unified/apistore/store_test.go +++ b/pkg/storage/unified/apistore/store_test.go @@ -155,7 +155,7 @@ func TestDeleteWithSuggestionAndConflict(t *testing.T) { type resourceClientMock struct { resource.ResourceStoreClient resource.ResourceIndexClient - resource.RepositoryIndexClient + resource.ManagedObjectIndexClient resource.BulkStoreClient resource.BlobStoreClient resource.DiagnosticsClient diff --git a/pkg/storage/unified/resource/client.go b/pkg/storage/unified/resource/client.go index b059b0b855a..649a0b7c9c0 100644 --- a/pkg/storage/unified/resource/client.go +++ b/pkg/storage/unified/resource/client.go @@ -24,7 +24,7 @@ import ( type ResourceClient interface { ResourceStoreClient ResourceIndexClient - RepositoryIndexClient + ManagedObjectIndexClient BulkStoreClient BlobStoreClient DiagnosticsClient @@ -34,7 +34,7 @@ type ResourceClient interface { type resourceClient struct { ResourceStoreClient ResourceIndexClient - RepositoryIndexClient + ManagedObjectIndexClient BulkStoreClient BlobStoreClient DiagnosticsClient @@ -43,12 +43,12 @@ type resourceClient struct { func NewLegacyResourceClient(channel *grpc.ClientConn) ResourceClient { cc := grpchan.InterceptClientConn(channel, grpcUtils.UnaryClientInterceptor, grpcUtils.StreamClientInterceptor) return &resourceClient{ - ResourceStoreClient: NewResourceStoreClient(cc), - ResourceIndexClient: NewResourceIndexClient(cc), - RepositoryIndexClient: NewRepositoryIndexClient(cc), - BulkStoreClient: NewBulkStoreClient(cc), - BlobStoreClient: NewBlobStoreClient(cc), - DiagnosticsClient: NewDiagnosticsClient(cc), + ResourceStoreClient: NewResourceStoreClient(cc), + ResourceIndexClient: NewResourceIndexClient(cc), + ManagedObjectIndexClient: NewManagedObjectIndexClient(cc), + BulkStoreClient: NewBulkStoreClient(cc), + BlobStoreClient: NewBlobStoreClient(cc), + DiagnosticsClient: NewDiagnosticsClient(cc), } } @@ -60,7 +60,7 @@ func NewLocalResourceClient(server ResourceServer) ResourceClient { for _, desc := range []*grpc.ServiceDesc{ &ResourceStore_ServiceDesc, &ResourceIndex_ServiceDesc, - &RepositoryIndex_ServiceDesc, + &ManagedObjectIndex_ServiceDesc, &BlobStore_ServiceDesc, &BulkStore_ServiceDesc, &Diagnostics_ServiceDesc, @@ -82,12 +82,12 @@ func NewLocalResourceClient(server ResourceServer) ResourceClient { cc := grpchan.InterceptClientConn(channel, clientInt.UnaryClientInterceptor, clientInt.StreamClientInterceptor) return &resourceClient{ - ResourceStoreClient: NewResourceStoreClient(cc), - ResourceIndexClient: NewResourceIndexClient(cc), - RepositoryIndexClient: NewRepositoryIndexClient(cc), - BulkStoreClient: NewBulkStoreClient(cc), - BlobStoreClient: NewBlobStoreClient(cc), - DiagnosticsClient: NewDiagnosticsClient(cc), + ResourceStoreClient: NewResourceStoreClient(cc), + ResourceIndexClient: NewResourceIndexClient(cc), + ManagedObjectIndexClient: NewManagedObjectIndexClient(cc), + BulkStoreClient: NewBulkStoreClient(cc), + BlobStoreClient: NewBlobStoreClient(cc), + DiagnosticsClient: NewDiagnosticsClient(cc), } } @@ -124,12 +124,12 @@ func NewRemoteResourceClient(tracer tracing.Tracer, conn *grpc.ClientConn, cfg R cc := grpchan.InterceptClientConn(conn, clientInt.UnaryClientInterceptor, clientInt.StreamClientInterceptor) return &resourceClient{ - ResourceStoreClient: NewResourceStoreClient(cc), - ResourceIndexClient: NewResourceIndexClient(cc), - BlobStoreClient: NewBlobStoreClient(cc), - BulkStoreClient: NewBulkStoreClient(cc), - RepositoryIndexClient: NewRepositoryIndexClient(cc), - DiagnosticsClient: NewDiagnosticsClient(cc), + ResourceStoreClient: NewResourceStoreClient(cc), + ResourceIndexClient: NewResourceIndexClient(cc), + BlobStoreClient: NewBlobStoreClient(cc), + BulkStoreClient: NewBulkStoreClient(cc), + ManagedObjectIndexClient: NewManagedObjectIndexClient(cc), + DiagnosticsClient: NewDiagnosticsClient(cc), }, nil } diff --git a/pkg/storage/unified/resource/document.go b/pkg/storage/unified/resource/document.go index c8d3b72072b..9a2c6c36716 100644 --- a/pkg/storage/unified/resource/document.go +++ b/pkg/storage/unified/resource/document.go @@ -107,10 +107,22 @@ type IndexableDocument struct { // When the resource is managed by an upstream repository Manager *utils.ManagerProperties `json:"manager,omitempty"` + // indexed only field for faceting manager info + ManagedBy string `json:"managedBy,omitempty"` + // When the manager knows about file paths Source *utils.SourceProperties `json:"source,omitempty"` } +func (m *IndexableDocument) UpdateCopyFields() *IndexableDocument { + m.TitleNgram = m.Title + m.TitlePhrase = strings.ToLower(m.Title) // Lowercase for case-insensitive sorting ?? in the analyzer? + if m.Manager != nil { + m.ManagedBy = fmt.Sprintf("%s:%s", m.Manager.Kind, m.Manager.Identity) + } + return m +} + func (m *IndexableDocument) Type() string { return m.Key.Resource } @@ -169,20 +181,19 @@ func NewIndexableDocument(key *ResourceKey, rv int64, obj utils.GrafanaMetaAcces } } doc := &IndexableDocument{ - Key: key, - RV: rv, - Name: key.Name, - Title: title, // We always want *something* to display - TitleNgram: title, - TitlePhrase: strings.ToLower(title), // Lowercase for case-insensitive sorting - Labels: obj.GetLabels(), - Folder: obj.GetFolder(), - CreatedBy: obj.GetCreatedBy(), - UpdatedBy: obj.GetUpdatedBy(), + Key: key, + RV: rv, + Name: key.Name, + Title: title, // We always want *something* to display + Labels: obj.GetLabels(), + Folder: obj.GetFolder(), + CreatedBy: obj.GetCreatedBy(), + UpdatedBy: obj.GetUpdatedBy(), } m, ok := obj.GetManagerProperties() if ok { doc.Manager = &m + doc.ManagedBy = fmt.Sprintf("%s:%s", m.Kind, m.Identity) } s, ok := obj.GetSourceProperties() if ok { @@ -196,7 +207,7 @@ func NewIndexableDocument(key *ResourceKey, rv int64, obj utils.GrafanaMetaAcces if err != nil && tt != nil { doc.Updated = tt.UnixMilli() } - return doc + return doc.UpdateCopyFields() } func StandardDocumentBuilder() DocumentBuilder { @@ -280,6 +291,7 @@ const SEARCH_FIELD_CREATED_BY = "createdBy" const SEARCH_FIELD_UPDATED = "updated" const SEARCH_FIELD_UPDATED_BY = "updatedBy" +const SEARCH_FIELD_MANAGED_BY = "managedBy" // {kind}:{id} const SEARCH_FIELD_MANAGER_KIND = "manager.kind" const SEARCH_FIELD_MANAGER_ID = "manager.id" const SEARCH_FIELD_SOURCE_PATH = "source.path" diff --git a/pkg/storage/unified/resource/document_test.go b/pkg/storage/unified/resource/document_test.go index 8c14550578b..838adfae494 100644 --- a/pkg/storage/unified/resource/document_test.go +++ b/pkg/storage/unified/resource/document_test.go @@ -35,9 +35,9 @@ func TestStandardDocumentBuilder(t *testing.T) { }, "name": "test1", "rv": 10, - "title": "test playlist unified storage", - "title_phrase": "test playlist unified storage", - "title_ngram": "test playlist unified storage", + "title": "Test Playlist from Unified Storage", + "title_ngram": "Test Playlist from Unified Storage", + "title_phrase": "test playlist from unified storage", "created": 1717236672000, "createdBy": "user:ABC", "updatedBy": "user:XYZ", @@ -45,6 +45,7 @@ func TestStandardDocumentBuilder(t *testing.T) { "kind": "repo", "id": "something" }, + "managedBy": "repo:something", "source": { "path": "path/in/system.json", "checksum": "xyz" diff --git a/pkg/storage/unified/resource/resource.pb.go b/pkg/storage/unified/resource/resource.pb.go index 7cc91fbafa4..8f8d7925e13 100644 --- a/pkg/storage/unified/resource/resource.pb.go +++ b/pkg/storage/unified/resource/resource.pb.go @@ -2236,32 +2236,34 @@ func (x *ResourceSearchResponse) GetFacet() map[string]*ResourceSearchResponse_F // List items within a resource type & repository name // Access control is managed above this request -type ListRepositoryObjectsRequest struct { +type ListManagedObjectsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` // Starting from the requested page (other query parameters must match!) NextPageToken string `protobuf:"bytes,1,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` // Namespace (tenant) Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` - // The name of the repository - Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + // The manager type (eg, terraform vs repo) + Kind string `protobuf:"bytes,3,opt,name=kind,proto3" json:"kind,omitempty"` + // The name of the manager + Id string `protobuf:"bytes,4,opt,name=id,proto3" json:"id,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *ListRepositoryObjectsRequest) Reset() { - *x = ListRepositoryObjectsRequest{} +func (x *ListManagedObjectsRequest) Reset() { + *x = ListManagedObjectsRequest{} mi := &file_resource_proto_msgTypes[25] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ListRepositoryObjectsRequest) String() string { +func (x *ListManagedObjectsRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListRepositoryObjectsRequest) ProtoMessage() {} +func (*ListManagedObjectsRequest) ProtoMessage() {} -func (x *ListRepositoryObjectsRequest) ProtoReflect() protoreflect.Message { +func (x *ListManagedObjectsRequest) ProtoReflect() protoreflect.Message { mi := &file_resource_proto_msgTypes[25] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2273,36 +2275,43 @@ func (x *ListRepositoryObjectsRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListRepositoryObjectsRequest.ProtoReflect.Descriptor instead. -func (*ListRepositoryObjectsRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use ListManagedObjectsRequest.ProtoReflect.Descriptor instead. +func (*ListManagedObjectsRequest) Descriptor() ([]byte, []int) { return file_resource_proto_rawDescGZIP(), []int{25} } -func (x *ListRepositoryObjectsRequest) GetNextPageToken() string { +func (x *ListManagedObjectsRequest) GetNextPageToken() string { if x != nil { return x.NextPageToken } return "" } -func (x *ListRepositoryObjectsRequest) GetNamespace() string { +func (x *ListManagedObjectsRequest) GetNamespace() string { if x != nil { return x.Namespace } return "" } -func (x *ListRepositoryObjectsRequest) GetName() string { +func (x *ListManagedObjectsRequest) GetKind() string { if x != nil { - return x.Name + return x.Kind } return "" } -type ListRepositoryObjectsResponse struct { +func (x *ListManagedObjectsRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type ListManagedObjectsResponse struct { state protoimpl.MessageState `protogen:"open.v1"` // Item iterator - Items []*ListRepositoryObjectsResponse_Item `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + Items []*ListManagedObjectsResponse_Item `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` // More results exist... pass this in the next request NextPageToken string `protobuf:"bytes,2,opt,name=next_page_token,json=nextPageToken,proto3" json:"next_page_token,omitempty"` // Error details @@ -2311,20 +2320,20 @@ type ListRepositoryObjectsResponse struct { sizeCache protoimpl.SizeCache } -func (x *ListRepositoryObjectsResponse) Reset() { - *x = ListRepositoryObjectsResponse{} +func (x *ListManagedObjectsResponse) Reset() { + *x = ListManagedObjectsResponse{} mi := &file_resource_proto_msgTypes[26] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ListRepositoryObjectsResponse) String() string { +func (x *ListManagedObjectsResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListRepositoryObjectsResponse) ProtoMessage() {} +func (*ListManagedObjectsResponse) ProtoMessage() {} -func (x *ListRepositoryObjectsResponse) ProtoReflect() protoreflect.Message { +func (x *ListManagedObjectsResponse) ProtoReflect() protoreflect.Message { mi := &file_resource_proto_msgTypes[26] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2336,26 +2345,26 @@ func (x *ListRepositoryObjectsResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use ListRepositoryObjectsResponse.ProtoReflect.Descriptor instead. -func (*ListRepositoryObjectsResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use ListManagedObjectsResponse.ProtoReflect.Descriptor instead. +func (*ListManagedObjectsResponse) Descriptor() ([]byte, []int) { return file_resource_proto_rawDescGZIP(), []int{26} } -func (x *ListRepositoryObjectsResponse) GetItems() []*ListRepositoryObjectsResponse_Item { +func (x *ListManagedObjectsResponse) GetItems() []*ListManagedObjectsResponse_Item { if x != nil { return x.Items } return nil } -func (x *ListRepositoryObjectsResponse) GetNextPageToken() string { +func (x *ListManagedObjectsResponse) GetNextPageToken() string { if x != nil { return x.NextPageToken } return "" } -func (x *ListRepositoryObjectsResponse) GetError() *ErrorResult { +func (x *ListManagedObjectsResponse) GetError() *ErrorResult { if x != nil { return x.Error } @@ -2363,31 +2372,32 @@ func (x *ListRepositoryObjectsResponse) GetError() *ErrorResult { } // Count the items that exist with -type CountRepositoryObjectsRequest struct { +type CountManagedObjectsRequest struct { state protoimpl.MessageState `protogen:"open.v1"` // Namespace (tenant) Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` - // The name of the repository - // empty to count across all repositories - Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` + // Manager kind: terraform, plugin, kubectl, repo + Kind string `protobuf:"bytes,2,opt,name=kind,proto3" json:"kind,omitempty"` + // Name of the manager (meaningful inside kind) + Id string `protobuf:"bytes,3,opt,name=id,proto3" json:"id,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *CountRepositoryObjectsRequest) Reset() { - *x = CountRepositoryObjectsRequest{} +func (x *CountManagedObjectsRequest) Reset() { + *x = CountManagedObjectsRequest{} mi := &file_resource_proto_msgTypes[27] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *CountRepositoryObjectsRequest) String() string { +func (x *CountManagedObjectsRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CountRepositoryObjectsRequest) ProtoMessage() {} +func (*CountManagedObjectsRequest) ProtoMessage() {} -func (x *CountRepositoryObjectsRequest) ProtoReflect() protoreflect.Message { +func (x *CountManagedObjectsRequest) ProtoReflect() protoreflect.Message { mi := &file_resource_proto_msgTypes[27] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2399,50 +2409,57 @@ func (x *CountRepositoryObjectsRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CountRepositoryObjectsRequest.ProtoReflect.Descriptor instead. -func (*CountRepositoryObjectsRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use CountManagedObjectsRequest.ProtoReflect.Descriptor instead. +func (*CountManagedObjectsRequest) Descriptor() ([]byte, []int) { return file_resource_proto_rawDescGZIP(), []int{27} } -func (x *CountRepositoryObjectsRequest) GetNamespace() string { +func (x *CountManagedObjectsRequest) GetNamespace() string { if x != nil { return x.Namespace } return "" } -func (x *CountRepositoryObjectsRequest) GetName() string { +func (x *CountManagedObjectsRequest) GetKind() string { if x != nil { - return x.Name + return x.Kind + } + return "" +} + +func (x *CountManagedObjectsRequest) GetId() string { + if x != nil { + return x.Id } return "" } // Count the items that exist with -type CountRepositoryObjectsResponse struct { +type CountManagedObjectsResponse struct { state protoimpl.MessageState `protogen:"open.v1"` // Resource counts - Items []*CountRepositoryObjectsResponse_ResourceCount `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + Items []*CountManagedObjectsResponse_ResourceCount `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` // Error details Error *ErrorResult `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *CountRepositoryObjectsResponse) Reset() { - *x = CountRepositoryObjectsResponse{} +func (x *CountManagedObjectsResponse) Reset() { + *x = CountManagedObjectsResponse{} mi := &file_resource_proto_msgTypes[28] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *CountRepositoryObjectsResponse) String() string { +func (x *CountManagedObjectsResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CountRepositoryObjectsResponse) ProtoMessage() {} +func (*CountManagedObjectsResponse) ProtoMessage() {} -func (x *CountRepositoryObjectsResponse) ProtoReflect() protoreflect.Message { +func (x *CountManagedObjectsResponse) ProtoReflect() protoreflect.Message { mi := &file_resource_proto_msgTypes[28] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -2454,19 +2471,19 @@ func (x *CountRepositoryObjectsResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use CountRepositoryObjectsResponse.ProtoReflect.Descriptor instead. -func (*CountRepositoryObjectsResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use CountManagedObjectsResponse.ProtoReflect.Descriptor instead. +func (*CountManagedObjectsResponse) Descriptor() ([]byte, []int) { return file_resource_proto_rawDescGZIP(), []int{28} } -func (x *CountRepositoryObjectsResponse) GetItems() []*CountRepositoryObjectsResponse_ResourceCount { +func (x *CountManagedObjectsResponse) GetItems() []*CountManagedObjectsResponse_ResourceCount { if x != nil { return x.Items } return nil } -func (x *CountRepositoryObjectsResponse) GetError() *ErrorResult { +func (x *CountManagedObjectsResponse) GetError() *ErrorResult { if x != nil { return x.Error } @@ -3757,7 +3774,7 @@ func (x *ResourceSearchResponse_TermFacet) GetCount() int64 { return 0 } -type ListRepositoryObjectsResponse_Item struct { +type ListManagedObjectsResponse_Item struct { state protoimpl.MessageState `protogen:"open.v1"` // The resource object key Object *ResourceKey `protobuf:"bytes,1,opt,name=object,proto3" json:"object,omitempty"` @@ -3775,20 +3792,20 @@ type ListRepositoryObjectsResponse_Item struct { sizeCache protoimpl.SizeCache } -func (x *ListRepositoryObjectsResponse_Item) Reset() { - *x = ListRepositoryObjectsResponse_Item{} +func (x *ListManagedObjectsResponse_Item) Reset() { + *x = ListManagedObjectsResponse_Item{} mi := &file_resource_proto_msgTypes[50] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *ListRepositoryObjectsResponse_Item) String() string { +func (x *ListManagedObjectsResponse_Item) String() string { return protoimpl.X.MessageStringOf(x) } -func (*ListRepositoryObjectsResponse_Item) ProtoMessage() {} +func (*ListManagedObjectsResponse_Item) ProtoMessage() {} -func (x *ListRepositoryObjectsResponse_Item) ProtoReflect() protoreflect.Message { +func (x *ListManagedObjectsResponse_Item) ProtoReflect() protoreflect.Message { mi := &file_resource_proto_msgTypes[50] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -3800,77 +3817,78 @@ func (x *ListRepositoryObjectsResponse_Item) ProtoReflect() protoreflect.Message return mi.MessageOf(x) } -// Deprecated: Use ListRepositoryObjectsResponse_Item.ProtoReflect.Descriptor instead. -func (*ListRepositoryObjectsResponse_Item) Descriptor() ([]byte, []int) { +// Deprecated: Use ListManagedObjectsResponse_Item.ProtoReflect.Descriptor instead. +func (*ListManagedObjectsResponse_Item) Descriptor() ([]byte, []int) { return file_resource_proto_rawDescGZIP(), []int{26, 0} } -func (x *ListRepositoryObjectsResponse_Item) GetObject() *ResourceKey { +func (x *ListManagedObjectsResponse_Item) GetObject() *ResourceKey { if x != nil { return x.Object } return nil } -func (x *ListRepositoryObjectsResponse_Item) GetPath() string { +func (x *ListManagedObjectsResponse_Item) GetPath() string { if x != nil { return x.Path } return "" } -func (x *ListRepositoryObjectsResponse_Item) GetHash() string { +func (x *ListManagedObjectsResponse_Item) GetHash() string { if x != nil { return x.Hash } return "" } -func (x *ListRepositoryObjectsResponse_Item) GetTime() int64 { +func (x *ListManagedObjectsResponse_Item) GetTime() int64 { if x != nil { return x.Time } return 0 } -func (x *ListRepositoryObjectsResponse_Item) GetTitle() string { +func (x *ListManagedObjectsResponse_Item) GetTitle() string { if x != nil { return x.Title } return "" } -func (x *ListRepositoryObjectsResponse_Item) GetFolder() string { +func (x *ListManagedObjectsResponse_Item) GetFolder() string { if x != nil { return x.Folder } return "" } -type CountRepositoryObjectsResponse_ResourceCount struct { +type CountManagedObjectsResponse_ResourceCount struct { state protoimpl.MessageState `protogen:"open.v1"` - Repository string `protobuf:"bytes,1,opt,name=repository,proto3" json:"repository,omitempty"` - Group string `protobuf:"bytes,2,opt,name=group,proto3" json:"group,omitempty"` - Resource string `protobuf:"bytes,3,opt,name=resource,proto3" json:"resource,omitempty"` - Count int64 `protobuf:"varint,4,opt,name=count,proto3" json:"count,omitempty"` + Kind string `protobuf:"bytes,1,opt,name=kind,proto3" json:"kind,omitempty"` + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + Group string `protobuf:"bytes,3,opt,name=group,proto3" json:"group,omitempty"` + Resource string `protobuf:"bytes,4,opt,name=resource,proto3" json:"resource,omitempty"` + Count int64 `protobuf:"varint,5,opt,name=count,proto3" json:"count,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *CountRepositoryObjectsResponse_ResourceCount) Reset() { - *x = CountRepositoryObjectsResponse_ResourceCount{} +func (x *CountManagedObjectsResponse_ResourceCount) Reset() { + *x = CountManagedObjectsResponse_ResourceCount{} mi := &file_resource_proto_msgTypes[51] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *CountRepositoryObjectsResponse_ResourceCount) String() string { +func (x *CountManagedObjectsResponse_ResourceCount) String() string { return protoimpl.X.MessageStringOf(x) } -func (*CountRepositoryObjectsResponse_ResourceCount) ProtoMessage() {} +func (*CountManagedObjectsResponse_ResourceCount) ProtoMessage() {} -func (x *CountRepositoryObjectsResponse_ResourceCount) ProtoReflect() protoreflect.Message { +func (x *CountManagedObjectsResponse_ResourceCount) ProtoReflect() protoreflect.Message { mi := &file_resource_proto_msgTypes[51] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -3882,33 +3900,40 @@ func (x *CountRepositoryObjectsResponse_ResourceCount) ProtoReflect() protorefle return mi.MessageOf(x) } -// Deprecated: Use CountRepositoryObjectsResponse_ResourceCount.ProtoReflect.Descriptor instead. -func (*CountRepositoryObjectsResponse_ResourceCount) Descriptor() ([]byte, []int) { +// Deprecated: Use CountManagedObjectsResponse_ResourceCount.ProtoReflect.Descriptor instead. +func (*CountManagedObjectsResponse_ResourceCount) Descriptor() ([]byte, []int) { return file_resource_proto_rawDescGZIP(), []int{28, 0} } -func (x *CountRepositoryObjectsResponse_ResourceCount) GetRepository() string { +func (x *CountManagedObjectsResponse_ResourceCount) GetKind() string { if x != nil { - return x.Repository + return x.Kind } return "" } -func (x *CountRepositoryObjectsResponse_ResourceCount) GetGroup() string { +func (x *CountManagedObjectsResponse_ResourceCount) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *CountManagedObjectsResponse_ResourceCount) GetGroup() string { if x != nil { return x.Group } return "" } -func (x *CountRepositoryObjectsResponse_ResourceCount) GetResource() string { +func (x *CountManagedObjectsResponse_ResourceCount) GetResource() string { if x != nil { return x.Resource } return "" } -func (x *CountRepositoryObjectsResponse_ResourceCount) GetCount() int64 { +func (x *CountManagedObjectsResponse_ResourceCount) GetCount() int64 { if x != nil { return x.Count } @@ -4335,275 +4360,276 @@ var file_resource_proto_rawDesc = string([]byte{ 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x61, 0x63, 0x65, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x78, 0x0a, 0x1c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, - 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1c, 0x0a, - 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, - 0xda, 0x02, 0x0a, 0x1d, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x42, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x2c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, - 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, - 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2b, 0x0a, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x1a, 0x9f, 0x01, 0x0a, 0x04, 0x49, - 0x74, 0x65, 0x6d, 0x12, 0x2d, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, - 0x69, 0x74, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x07, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x22, 0x51, 0x0a, 0x1d, - 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, - 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, - 0x94, 0x02, 0x0a, 0x1e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x4c, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x36, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4f, 0x62, 0x6a, 0x65, - 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, - 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x1a, 0x77, 0x0a, - 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1e, - 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x67, - 0x72, 0x6f, 0x75, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x2e, 0x0a, 0x12, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, - 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0xab, 0x01, 0x0a, 0x13, 0x48, 0x65, 0x61, 0x6c, 0x74, - 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x43, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x53, 0x65, - 0x72, 0x76, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x22, 0x4f, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, - 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x45, 0x52, 0x56, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0f, - 0x0a, 0x0b, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, - 0x13, 0x0a, 0x0f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, - 0x57, 0x4e, 0x10, 0x03, 0x22, 0x87, 0x02, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x52, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x04, 0x72, 0x6f, 0x77, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, - 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, - 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x30, 0x0a, 0x14, - 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x74, 0x65, 0x6d, 0x5f, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x72, 0x65, 0x6d, 0x61, - 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xf1, - 0x04, 0x0a, 0x1d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, - 0x6e, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6c, 0x75, - 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, - 0x69, 0x73, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, - 0x69, 0x73, 0x41, 0x72, 0x72, 0x61, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, - 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, - 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x0a, 0x70, 0x72, 0x6f, - 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x44, 0x65, 0x66, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, - 0x73, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x1a, 0x0a, - 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x1a, 0xae, 0x01, 0x0a, 0x0a, 0x50, 0x72, - 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x75, 0x6e, 0x69, 0x71, - 0x75, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0c, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x1b, 0x0a, - 0x09, 0x66, 0x72, 0x65, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x08, 0x66, 0x72, 0x65, 0x65, 0x54, 0x65, 0x78, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x66, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, - 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6e, 0x6f, - 0x74, 0x5f, 0x6e, 0x75, 0x6c, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x6e, 0x6f, - 0x74, 0x4e, 0x75, 0x6c, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, - 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x64, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x95, 0x01, 0x0a, 0x0a, 0x43, - 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x55, 0x4e, 0x4b, - 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x53, - 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x42, 0x4f, 0x4f, 0x4c, 0x45, - 0x41, 0x4e, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x33, 0x32, 0x10, 0x03, 0x12, - 0x09, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x46, 0x4c, - 0x4f, 0x41, 0x54, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x4f, 0x55, 0x42, 0x4c, 0x45, 0x10, - 0x06, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x45, 0x10, 0x07, 0x12, 0x0d, 0x0a, 0x09, 0x44, - 0x41, 0x54, 0x45, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x08, 0x12, 0x0a, 0x0a, 0x06, 0x42, 0x49, - 0x4e, 0x41, 0x52, 0x59, 0x10, 0x09, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x42, 0x4a, 0x45, 0x43, 0x54, - 0x10, 0x0a, 0x22, 0x94, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x85, 0x01, 0x0a, 0x19, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, + 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x6e, + 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x0e, 0x0a, + 0x02, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0xd4, 0x02, + 0x0a, 0x1a, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3f, 0x0a, 0x05, + 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, + 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x49, 0x74, 0x65, 0x6d, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, 0x26, 0x0a, + 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, + 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x63, - 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x63, 0x65, 0x6c, 0x6c, - 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x64, 0x0a, 0x0e, 0x52, 0x65, 0x73, - 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, - 0x69, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x45, 0x72, 0x72, - 0x6f, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, - 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd3, 0x01, 0x0a, 0x0e, 0x50, - 0x75, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, - 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x12, 0x37, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, - 0x32, 0x1f, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, 0x75, 0x74, 0x42, - 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, - 0x64, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x22, 0x1c, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x08, 0x0a, 0x04, - 0x47, 0x52, 0x50, 0x43, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, 0x50, 0x10, 0x01, - 0x22, 0xc1, 0x01, 0x0a, 0x0f, 0x50, 0x75, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x75, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x61, 0x73, - 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, 0x12, 0x1b, 0x0a, - 0x09, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x08, 0x6d, 0x69, 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, - 0x61, 0x72, 0x73, 0x65, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x72, 0x73, 0x65, 0x74, 0x22, 0xaa, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, - 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, - 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x75, 0x73, 0x74, 0x5f, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x0e, 0x6d, 0x75, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, - 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x69, - 0x64, 0x22, 0x89, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x1a, 0x9f, 0x01, 0x0a, 0x04, 0x49, 0x74, 0x65, 0x6d, 0x12, 0x2d, 0x0a, 0x06, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, + 0x65, 0x79, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, + 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x12, + 0x0a, 0x04, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, + 0x73, 0x68, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x16, 0x0a, 0x06, + 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x66, 0x6f, + 0x6c, 0x64, 0x65, 0x72, 0x22, 0x5e, 0x0a, 0x1a, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x69, 0x64, 0x22, 0x92, 0x02, 0x0a, 0x1b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x49, 0x0a, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x43, + 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x05, 0x69, 0x74, 0x65, 0x6d, 0x73, 0x12, + 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, + 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x1a, 0x7b, 0x0a, 0x0d, + 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6b, 0x69, 0x6e, + 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x12, 0x14, 0x0a, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x03, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x2e, 0x0a, 0x12, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x18, 0x0a, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0xab, 0x01, 0x0a, 0x13, 0x48, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x43, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0e, 0x32, 0x2b, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, + 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x4f, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76, 0x69, 0x6e, + 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0b, 0x0a, 0x07, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, + 0x57, 0x4e, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x45, 0x52, 0x56, 0x49, 0x4e, 0x47, 0x10, + 0x01, 0x12, 0x0f, 0x0a, 0x0b, 0x4e, 0x4f, 0x54, 0x5f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x4e, 0x47, + 0x10, 0x02, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x45, 0x52, 0x56, 0x49, 0x43, 0x45, 0x5f, 0x55, 0x4e, + 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x22, 0x87, 0x02, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x41, 0x0a, 0x07, 0x63, 0x6f, 0x6c, + 0x75, 0x6d, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x07, 0x63, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x73, 0x12, 0x2e, 0x0a, 0x04, + 0x72, 0x6f, 0x77, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x52, 0x04, 0x72, 0x6f, 0x77, 0x73, 0x12, 0x26, 0x0a, 0x0f, + 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, 0x65, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x30, 0x0a, 0x14, 0x72, 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x5f, 0x69, 0x74, 0x65, + 0x6d, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x72, + 0x65, 0x6d, 0x61, 0x69, 0x6e, 0x69, 0x6e, 0x67, 0x49, 0x74, 0x65, 0x6d, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x22, 0xf1, 0x04, 0x0a, 0x1d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, + 0x6c, 0x75, 0x6d, 0x6e, 0x44, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x43, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, + 0x19, 0x0a, 0x08, 0x69, 0x73, 0x5f, 0x61, 0x72, 0x72, 0x61, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x69, 0x73, 0x41, 0x72, 0x72, 0x61, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, + 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x0a, + 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x32, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x44, + 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, + 0x74, 0x69, 0x65, 0x73, 0x52, 0x0a, 0x70, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, + 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x08, 0x70, 0x72, 0x69, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x1a, 0xae, 0x01, 0x0a, + 0x0a, 0x50, 0x72, 0x6f, 0x70, 0x65, 0x72, 0x74, 0x69, 0x65, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x75, + 0x6e, 0x69, 0x71, 0x75, 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0c, 0x75, 0x6e, 0x69, 0x71, 0x75, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, + 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x72, 0x65, 0x65, 0x5f, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x08, 0x66, 0x72, 0x65, 0x65, 0x54, 0x65, 0x78, 0x74, 0x12, 0x1e, 0x0a, + 0x0a, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0a, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x19, 0x0a, + 0x08, 0x6e, 0x6f, 0x74, 0x5f, 0x6e, 0x75, 0x6c, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x6e, 0x6f, 0x74, 0x4e, 0x75, 0x6c, 0x6c, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, + 0x75, 0x6c, 0x74, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x95, 0x01, + 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x54, 0x79, 0x70, 0x65, 0x12, 0x10, 0x0a, 0x0c, + 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x10, 0x00, 0x12, 0x0a, + 0x0a, 0x06, 0x53, 0x54, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x42, 0x4f, + 0x4f, 0x4c, 0x45, 0x41, 0x4e, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x33, 0x32, + 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x49, 0x4e, 0x54, 0x36, 0x34, 0x10, 0x04, 0x12, 0x09, 0x0a, + 0x05, 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x10, 0x05, 0x12, 0x0a, 0x0a, 0x06, 0x44, 0x4f, 0x55, 0x42, + 0x4c, 0x45, 0x10, 0x06, 0x12, 0x08, 0x0a, 0x04, 0x44, 0x41, 0x54, 0x45, 0x10, 0x07, 0x12, 0x0d, + 0x0a, 0x09, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x08, 0x12, 0x0a, 0x0a, + 0x06, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x09, 0x12, 0x0a, 0x0a, 0x06, 0x4f, 0x42, 0x4a, + 0x45, 0x43, 0x54, 0x10, 0x0a, 0x22, 0x94, 0x01, 0x0a, 0x10, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x12, 0x27, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, + 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, + 0x0a, 0x05, 0x63, 0x65, 0x6c, 0x6c, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x05, 0x63, + 0x65, 0x6c, 0x6c, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x22, 0x64, 0x0a, 0x0e, + 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, + 0x65, 0x79, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x03, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, + 0x6f, 0x6e, 0x22, 0x69, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x75, 0x72, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, - 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, - 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x2a, 0x33, 0x0a, - 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, - 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x10, 0x0a, 0x0c, 0x4e, 0x6f, 0x74, 0x4f, 0x6c, 0x64, 0x65, - 0x72, 0x54, 0x68, 0x61, 0x6e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x78, 0x61, 0x63, 0x74, - 0x10, 0x01, 0x32, 0xad, 0x03, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, 0x15, 0x2e, 0x72, - 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, - 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x12, 0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12, - 0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x18, 0x2e, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x15, 0x2e, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x05, 0x57, 0x61, 0x74, - 0x63, 0x68, 0x12, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x57, 0x61, - 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x45, 0x76, 0x65, 0x6e, 0x74, - 0x30, 0x01, 0x32, 0x4b, 0x0a, 0x09, 0x42, 0x75, 0x6c, 0x6b, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, - 0x3e, 0x0a, 0x0b, 0x42, 0x75, 0x6c, 0x6b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x12, 0x15, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x32, - 0xa9, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x64, 0x65, - 0x78, 0x12, 0x4b, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x1f, 0x2e, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, - 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x72, + 0x6f, 0x72, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0xd3, 0x01, + 0x0a, 0x0e, 0x50, 0x75, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x12, 0x31, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4b, 0x65, 0x79, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x12, 0x37, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x1f, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, + 0x75, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, + 0x74, 0x68, 0x6f, 0x64, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, 0x21, 0x0a, 0x0c, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x1c, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x12, + 0x08, 0x0a, 0x04, 0x47, 0x52, 0x50, 0x43, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x48, 0x54, 0x54, + 0x50, 0x10, 0x01, 0x22, 0xc1, 0x01, 0x0a, 0x0f, 0x50, 0x75, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x75, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x69, 0x7a, 0x65, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x73, 0x69, 0x7a, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x68, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x61, 0x73, 0x68, + 0x12, 0x1b, 0x0a, 0x09, 0x6d, 0x69, 0x6d, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x69, 0x6d, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, + 0x07, 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x63, 0x68, 0x61, 0x72, 0x73, 0x65, 0x74, 0x22, 0xaa, 0x01, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x42, + 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x08, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4b, - 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x1e, 0x2e, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x72, 0x65, 0x73, - 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xe8, 0x01, 0x0a, 0x0f, - 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, - 0x6b, 0x0a, 0x16, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x27, 0x2e, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x43, 0x6f, - 0x75, 0x6e, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4f, 0x62, 0x6a, - 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x68, 0x0a, 0x15, - 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4f, 0x62, - 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x26, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4f, - 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x70, - 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8b, 0x01, 0x0a, 0x09, 0x42, 0x6c, 0x6f, 0x62, 0x53, - 0x74, 0x6f, 0x72, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x50, 0x75, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x12, - 0x18, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, 0x75, 0x74, 0x42, 0x6c, - 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, 0x75, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x12, - 0x18, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, - 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x57, 0x0a, 0x0b, 0x44, 0x69, 0x61, 0x67, 0x6e, 0x6f, 0x73, 0x74, - 0x69, 0x63, 0x73, 0x12, 0x48, 0x0a, 0x09, 0x49, 0x73, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, - 0x12, 0x1c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x6c, - 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, - 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x39, 0x5a, - 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x66, - 0x61, 0x6e, 0x61, 0x2f, 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x70, 0x6b, 0x67, 0x2f, - 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2f, 0x75, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x2f, - 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x4b, 0x65, 0x79, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x29, 0x0a, + 0x10, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x0a, 0x10, 0x6d, 0x75, 0x73, 0x74, + 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x0e, 0x6d, 0x75, 0x73, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x75, 0x69, 0x64, 0x22, 0x89, 0x01, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x2a, 0x33, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, + 0x69, 0x6f, 0x6e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x10, 0x0a, 0x0c, 0x4e, 0x6f, 0x74, 0x4f, + 0x6c, 0x64, 0x65, 0x72, 0x54, 0x68, 0x61, 0x6e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x78, + 0x61, 0x63, 0x74, 0x10, 0x01, 0x32, 0xad, 0x03, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x52, 0x65, 0x61, 0x64, 0x12, + 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, + 0x0a, 0x06, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, + 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3b, 0x0a, 0x06, 0x44, 0x65, 0x6c, 0x65, + 0x74, 0x65, 0x12, 0x17, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, + 0x12, 0x18, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x74, + 0x6f, 0x72, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x65, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x35, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x15, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x05, + 0x57, 0x61, 0x74, 0x63, 0x68, 0x12, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x57, 0x61, 0x74, 0x63, 0x68, 0x45, 0x76, + 0x65, 0x6e, 0x74, 0x30, 0x01, 0x32, 0x4b, 0x0a, 0x09, 0x42, 0x75, 0x6c, 0x6b, 0x53, 0x74, 0x6f, + 0x72, 0x65, 0x12, 0x3e, 0x0a, 0x0b, 0x42, 0x75, 0x6c, 0x6b, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x12, 0x15, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x42, 0x75, 0x6c, + 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x2e, 0x42, 0x75, 0x6c, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x28, 0x01, 0x32, 0xa9, 0x01, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, + 0x6e, 0x64, 0x65, 0x78, 0x12, 0x4b, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x1f, + 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, + 0x63, 0x65, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x20, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x4b, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x1e, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xd9, + 0x01, 0x0a, 0x12, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x62, 0x0a, 0x13, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x61, + 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, 0x24, 0x2e, 0x72, + 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4d, 0x61, 0x6e, + 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x25, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x5f, 0x0a, 0x12, 0x4c, 0x69, 0x73, + 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x12, + 0x23, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x24, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x61, 0x6e, 0x61, 0x67, 0x65, 0x64, 0x4f, 0x62, 0x6a, 0x65, 0x63, + 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x8b, 0x01, 0x0a, 0x09, 0x42, + 0x6c, 0x6f, 0x62, 0x53, 0x74, 0x6f, 0x72, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x50, 0x75, 0x74, 0x42, + 0x6c, 0x6f, 0x62, 0x12, 0x18, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, + 0x75, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x50, 0x75, 0x74, 0x42, 0x6c, 0x6f, 0x62, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x3e, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x42, + 0x6c, 0x6f, 0x62, 0x12, 0x18, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x47, + 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x6c, 0x6f, 0x62, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x57, 0x0a, 0x0b, 0x44, 0x69, 0x61, 0x67, + 0x6e, 0x6f, 0x73, 0x74, 0x69, 0x63, 0x73, 0x12, 0x48, 0x0a, 0x09, 0x49, 0x73, 0x48, 0x65, 0x61, + 0x6c, 0x74, 0x68, 0x79, 0x12, 0x1c, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, + 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x48, 0x65, + 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x42, 0x39, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, + 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, 0x67, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x2f, + 0x70, 0x6b, 0x67, 0x2f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x2f, 0x75, 0x6e, 0x69, 0x66, + 0x69, 0x65, 0x64, 0x2f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, }) var ( @@ -4621,66 +4647,66 @@ func file_resource_proto_rawDescGZIP() []byte { var file_resource_proto_enumTypes = make([]protoimpl.EnumInfo, 7) var file_resource_proto_msgTypes = make([]protoimpl.MessageInfo, 53) var file_resource_proto_goTypes = []any{ - (ResourceVersionMatch)(0), // 0: resource.ResourceVersionMatch - (ListRequest_Source)(0), // 1: resource.ListRequest.Source - (WatchEvent_Type)(0), // 2: resource.WatchEvent.Type - (BulkRequest_Action)(0), // 3: resource.BulkRequest.Action - (HealthCheckResponse_ServingStatus)(0), // 4: resource.HealthCheckResponse.ServingStatus - (ResourceTableColumnDefinition_ColumnType)(0), // 5: resource.ResourceTableColumnDefinition.ColumnType - (PutBlobRequest_Method)(0), // 6: resource.PutBlobRequest.Method - (*ResourceKey)(nil), // 7: resource.ResourceKey - (*ResourceWrapper)(nil), // 8: resource.ResourceWrapper - (*ErrorResult)(nil), // 9: resource.ErrorResult - (*ErrorDetails)(nil), // 10: resource.ErrorDetails - (*ErrorCause)(nil), // 11: resource.ErrorCause - (*CreateRequest)(nil), // 12: resource.CreateRequest - (*CreateResponse)(nil), // 13: resource.CreateResponse - (*UpdateRequest)(nil), // 14: resource.UpdateRequest - (*UpdateResponse)(nil), // 15: resource.UpdateResponse - (*DeleteRequest)(nil), // 16: resource.DeleteRequest - (*DeleteResponse)(nil), // 17: resource.DeleteResponse - (*ReadRequest)(nil), // 18: resource.ReadRequest - (*ReadResponse)(nil), // 19: resource.ReadResponse - (*Requirement)(nil), // 20: resource.Requirement - (*ListOptions)(nil), // 21: resource.ListOptions - (*ListRequest)(nil), // 22: resource.ListRequest - (*ListResponse)(nil), // 23: resource.ListResponse - (*WatchRequest)(nil), // 24: resource.WatchRequest - (*WatchEvent)(nil), // 25: resource.WatchEvent - (*BulkRequest)(nil), // 26: resource.BulkRequest - (*BulkResponse)(nil), // 27: resource.BulkResponse - (*ResourceStatsRequest)(nil), // 28: resource.ResourceStatsRequest - (*ResourceStatsResponse)(nil), // 29: resource.ResourceStatsResponse - (*ResourceSearchRequest)(nil), // 30: resource.ResourceSearchRequest - (*ResourceSearchResponse)(nil), // 31: resource.ResourceSearchResponse - (*ListRepositoryObjectsRequest)(nil), // 32: resource.ListRepositoryObjectsRequest - (*ListRepositoryObjectsResponse)(nil), // 33: resource.ListRepositoryObjectsResponse - (*CountRepositoryObjectsRequest)(nil), // 34: resource.CountRepositoryObjectsRequest - (*CountRepositoryObjectsResponse)(nil), // 35: resource.CountRepositoryObjectsResponse - (*HealthCheckRequest)(nil), // 36: resource.HealthCheckRequest - (*HealthCheckResponse)(nil), // 37: resource.HealthCheckResponse - (*ResourceTable)(nil), // 38: resource.ResourceTable - (*ResourceTableColumnDefinition)(nil), // 39: resource.ResourceTableColumnDefinition - (*ResourceTableRow)(nil), // 40: resource.ResourceTableRow - (*RestoreRequest)(nil), // 41: resource.RestoreRequest - (*RestoreResponse)(nil), // 42: resource.RestoreResponse - (*PutBlobRequest)(nil), // 43: resource.PutBlobRequest - (*PutBlobResponse)(nil), // 44: resource.PutBlobResponse - (*GetBlobRequest)(nil), // 45: resource.GetBlobRequest - (*GetBlobResponse)(nil), // 46: resource.GetBlobResponse - (*WatchEvent_Resource)(nil), // 47: resource.WatchEvent.Resource - (*BulkResponse_Summary)(nil), // 48: resource.BulkResponse.Summary - (*BulkResponse_Rejected)(nil), // 49: resource.BulkResponse.Rejected - (*ResourceStatsResponse_Stats)(nil), // 50: resource.ResourceStatsResponse.Stats - (*ResourceSearchRequest_Sort)(nil), // 51: resource.ResourceSearchRequest.Sort - (*ResourceSearchRequest_Facet)(nil), // 52: resource.ResourceSearchRequest.Facet - nil, // 53: resource.ResourceSearchRequest.FacetEntry - (*ResourceSearchResponse_Facet)(nil), // 54: resource.ResourceSearchResponse.Facet - (*ResourceSearchResponse_TermFacet)(nil), // 55: resource.ResourceSearchResponse.TermFacet - nil, // 56: resource.ResourceSearchResponse.FacetEntry - (*ListRepositoryObjectsResponse_Item)(nil), // 57: resource.ListRepositoryObjectsResponse.Item - (*CountRepositoryObjectsResponse_ResourceCount)(nil), // 58: resource.CountRepositoryObjectsResponse.ResourceCount - (*ResourceTableColumnDefinition_Properties)(nil), // 59: resource.ResourceTableColumnDefinition.Properties + (ResourceVersionMatch)(0), // 0: resource.ResourceVersionMatch + (ListRequest_Source)(0), // 1: resource.ListRequest.Source + (WatchEvent_Type)(0), // 2: resource.WatchEvent.Type + (BulkRequest_Action)(0), // 3: resource.BulkRequest.Action + (HealthCheckResponse_ServingStatus)(0), // 4: resource.HealthCheckResponse.ServingStatus + (ResourceTableColumnDefinition_ColumnType)(0), // 5: resource.ResourceTableColumnDefinition.ColumnType + (PutBlobRequest_Method)(0), // 6: resource.PutBlobRequest.Method + (*ResourceKey)(nil), // 7: resource.ResourceKey + (*ResourceWrapper)(nil), // 8: resource.ResourceWrapper + (*ErrorResult)(nil), // 9: resource.ErrorResult + (*ErrorDetails)(nil), // 10: resource.ErrorDetails + (*ErrorCause)(nil), // 11: resource.ErrorCause + (*CreateRequest)(nil), // 12: resource.CreateRequest + (*CreateResponse)(nil), // 13: resource.CreateResponse + (*UpdateRequest)(nil), // 14: resource.UpdateRequest + (*UpdateResponse)(nil), // 15: resource.UpdateResponse + (*DeleteRequest)(nil), // 16: resource.DeleteRequest + (*DeleteResponse)(nil), // 17: resource.DeleteResponse + (*ReadRequest)(nil), // 18: resource.ReadRequest + (*ReadResponse)(nil), // 19: resource.ReadResponse + (*Requirement)(nil), // 20: resource.Requirement + (*ListOptions)(nil), // 21: resource.ListOptions + (*ListRequest)(nil), // 22: resource.ListRequest + (*ListResponse)(nil), // 23: resource.ListResponse + (*WatchRequest)(nil), // 24: resource.WatchRequest + (*WatchEvent)(nil), // 25: resource.WatchEvent + (*BulkRequest)(nil), // 26: resource.BulkRequest + (*BulkResponse)(nil), // 27: resource.BulkResponse + (*ResourceStatsRequest)(nil), // 28: resource.ResourceStatsRequest + (*ResourceStatsResponse)(nil), // 29: resource.ResourceStatsResponse + (*ResourceSearchRequest)(nil), // 30: resource.ResourceSearchRequest + (*ResourceSearchResponse)(nil), // 31: resource.ResourceSearchResponse + (*ListManagedObjectsRequest)(nil), // 32: resource.ListManagedObjectsRequest + (*ListManagedObjectsResponse)(nil), // 33: resource.ListManagedObjectsResponse + (*CountManagedObjectsRequest)(nil), // 34: resource.CountManagedObjectsRequest + (*CountManagedObjectsResponse)(nil), // 35: resource.CountManagedObjectsResponse + (*HealthCheckRequest)(nil), // 36: resource.HealthCheckRequest + (*HealthCheckResponse)(nil), // 37: resource.HealthCheckResponse + (*ResourceTable)(nil), // 38: resource.ResourceTable + (*ResourceTableColumnDefinition)(nil), // 39: resource.ResourceTableColumnDefinition + (*ResourceTableRow)(nil), // 40: resource.ResourceTableRow + (*RestoreRequest)(nil), // 41: resource.RestoreRequest + (*RestoreResponse)(nil), // 42: resource.RestoreResponse + (*PutBlobRequest)(nil), // 43: resource.PutBlobRequest + (*PutBlobResponse)(nil), // 44: resource.PutBlobResponse + (*GetBlobRequest)(nil), // 45: resource.GetBlobRequest + (*GetBlobResponse)(nil), // 46: resource.GetBlobResponse + (*WatchEvent_Resource)(nil), // 47: resource.WatchEvent.Resource + (*BulkResponse_Summary)(nil), // 48: resource.BulkResponse.Summary + (*BulkResponse_Rejected)(nil), // 49: resource.BulkResponse.Rejected + (*ResourceStatsResponse_Stats)(nil), // 50: resource.ResourceStatsResponse.Stats + (*ResourceSearchRequest_Sort)(nil), // 51: resource.ResourceSearchRequest.Sort + (*ResourceSearchRequest_Facet)(nil), // 52: resource.ResourceSearchRequest.Facet + nil, // 53: resource.ResourceSearchRequest.FacetEntry + (*ResourceSearchResponse_Facet)(nil), // 54: resource.ResourceSearchResponse.Facet + (*ResourceSearchResponse_TermFacet)(nil), // 55: resource.ResourceSearchResponse.TermFacet + nil, // 56: resource.ResourceSearchResponse.FacetEntry + (*ListManagedObjectsResponse_Item)(nil), // 57: resource.ListManagedObjectsResponse.Item + (*CountManagedObjectsResponse_ResourceCount)(nil), // 58: resource.CountManagedObjectsResponse.ResourceCount + (*ResourceTableColumnDefinition_Properties)(nil), // 59: resource.ResourceTableColumnDefinition.Properties } var file_resource_proto_depIdxs = []int32{ 10, // 0: resource.ErrorResult.details:type_name -> resource.ErrorDetails @@ -4720,10 +4746,10 @@ var file_resource_proto_depIdxs = []int32{ 7, // 34: resource.ResourceSearchResponse.key:type_name -> resource.ResourceKey 38, // 35: resource.ResourceSearchResponse.results:type_name -> resource.ResourceTable 56, // 36: resource.ResourceSearchResponse.facet:type_name -> resource.ResourceSearchResponse.FacetEntry - 57, // 37: resource.ListRepositoryObjectsResponse.items:type_name -> resource.ListRepositoryObjectsResponse.Item - 9, // 38: resource.ListRepositoryObjectsResponse.error:type_name -> resource.ErrorResult - 58, // 39: resource.CountRepositoryObjectsResponse.items:type_name -> resource.CountRepositoryObjectsResponse.ResourceCount - 9, // 40: resource.CountRepositoryObjectsResponse.error:type_name -> resource.ErrorResult + 57, // 37: resource.ListManagedObjectsResponse.items:type_name -> resource.ListManagedObjectsResponse.Item + 9, // 38: resource.ListManagedObjectsResponse.error:type_name -> resource.ErrorResult + 58, // 39: resource.CountManagedObjectsResponse.items:type_name -> resource.CountManagedObjectsResponse.ResourceCount + 9, // 40: resource.CountManagedObjectsResponse.error:type_name -> resource.ErrorResult 4, // 41: resource.HealthCheckResponse.status:type_name -> resource.HealthCheckResponse.ServingStatus 39, // 42: resource.ResourceTable.columns:type_name -> resource.ResourceTableColumnDefinition 40, // 43: resource.ResourceTable.rows:type_name -> resource.ResourceTableRow @@ -4742,7 +4768,7 @@ var file_resource_proto_depIdxs = []int32{ 52, // 56: resource.ResourceSearchRequest.FacetEntry.value:type_name -> resource.ResourceSearchRequest.Facet 55, // 57: resource.ResourceSearchResponse.Facet.terms:type_name -> resource.ResourceSearchResponse.TermFacet 54, // 58: resource.ResourceSearchResponse.FacetEntry.value:type_name -> resource.ResourceSearchResponse.Facet - 7, // 59: resource.ListRepositoryObjectsResponse.Item.object:type_name -> resource.ResourceKey + 7, // 59: resource.ListManagedObjectsResponse.Item.object:type_name -> resource.ResourceKey 18, // 60: resource.ResourceStore.Read:input_type -> resource.ReadRequest 12, // 61: resource.ResourceStore.Create:input_type -> resource.CreateRequest 14, // 62: resource.ResourceStore.Update:input_type -> resource.UpdateRequest @@ -4753,8 +4779,8 @@ var file_resource_proto_depIdxs = []int32{ 26, // 67: resource.BulkStore.BulkProcess:input_type -> resource.BulkRequest 30, // 68: resource.ResourceIndex.Search:input_type -> resource.ResourceSearchRequest 28, // 69: resource.ResourceIndex.GetStats:input_type -> resource.ResourceStatsRequest - 34, // 70: resource.RepositoryIndex.CountRepositoryObjects:input_type -> resource.CountRepositoryObjectsRequest - 32, // 71: resource.RepositoryIndex.ListRepositoryObjects:input_type -> resource.ListRepositoryObjectsRequest + 34, // 70: resource.ManagedObjectIndex.CountManagedObjects:input_type -> resource.CountManagedObjectsRequest + 32, // 71: resource.ManagedObjectIndex.ListManagedObjects:input_type -> resource.ListManagedObjectsRequest 43, // 72: resource.BlobStore.PutBlob:input_type -> resource.PutBlobRequest 45, // 73: resource.BlobStore.GetBlob:input_type -> resource.GetBlobRequest 36, // 74: resource.Diagnostics.IsHealthy:input_type -> resource.HealthCheckRequest @@ -4768,8 +4794,8 @@ var file_resource_proto_depIdxs = []int32{ 27, // 82: resource.BulkStore.BulkProcess:output_type -> resource.BulkResponse 31, // 83: resource.ResourceIndex.Search:output_type -> resource.ResourceSearchResponse 29, // 84: resource.ResourceIndex.GetStats:output_type -> resource.ResourceStatsResponse - 35, // 85: resource.RepositoryIndex.CountRepositoryObjects:output_type -> resource.CountRepositoryObjectsResponse - 33, // 86: resource.RepositoryIndex.ListRepositoryObjects:output_type -> resource.ListRepositoryObjectsResponse + 35, // 85: resource.ManagedObjectIndex.CountManagedObjects:output_type -> resource.CountManagedObjectsResponse + 33, // 86: resource.ManagedObjectIndex.ListManagedObjects:output_type -> resource.ListManagedObjectsResponse 44, // 87: resource.BlobStore.PutBlob:output_type -> resource.PutBlobResponse 46, // 88: resource.BlobStore.GetBlob:output_type -> resource.GetBlobResponse 37, // 89: resource.Diagnostics.IsHealthy:output_type -> resource.HealthCheckResponse diff --git a/pkg/storage/unified/resource/resource.proto b/pkg/storage/unified/resource/resource.proto index ea1d59cc83f..830c2a4d890 100644 --- a/pkg/storage/unified/resource/resource.proto +++ b/pkg/storage/unified/resource/resource.proto @@ -503,18 +503,21 @@ message ResourceSearchResponse { // List items within a resource type & repository name // Access control is managed above this request -message ListRepositoryObjectsRequest { +message ListManagedObjectsRequest { // Starting from the requested page (other query parameters must match!) string next_page_token = 1; // Namespace (tenant) string namespace = 2; - // The name of the repository - string name = 3; + // The manager type (eg, terraform vs repo) + string kind = 3; + + // The name of the manager + string id = 4; } -message ListRepositoryObjectsResponse { +message ListManagedObjectsResponse { message Item { // The resource object key ResourceKey object = 1; @@ -546,22 +549,25 @@ message ListRepositoryObjectsResponse { } // Count the items that exist with -message CountRepositoryObjectsRequest { +message CountManagedObjectsRequest { // Namespace (tenant) string namespace = 1; - // The name of the repository - // empty to count across all repositories - string name = 2; + // Manager kind: terraform, plugin, kubectl, repo + string kind = 2; + + // Name of the manager (meaningful inside kind) + string id = 3; } // Count the items that exist with -message CountRepositoryObjectsResponse { +message CountManagedObjectsResponse { message ResourceCount { - string repository = 1; - string group = 2; - string resource = 3; - int64 count = 4; + string kind = 1; + string id = 2; + string group = 3; + string resource = 4; + int64 count = 5; } // Resource counts @@ -834,14 +840,14 @@ service ResourceIndex { rpc GetStats(ResourceStatsRequest) returns (ResourceStatsResponse); } -// Query repository info from the search index. +// Query managed objects // Results access control is based on access to the repository *not* the items -service RepositoryIndex { +service ManagedObjectIndex { // Describe how many resources of each type exist within a repository - rpc CountRepositoryObjects(CountRepositoryObjectsRequest) returns (CountRepositoryObjectsResponse); + rpc CountManagedObjects(CountManagedObjectsRequest) returns (CountManagedObjectsResponse); // List the resources of a specific kind within a repository - rpc ListRepositoryObjects(ListRepositoryObjectsRequest) returns (ListRepositoryObjectsResponse); + rpc ListManagedObjects(ListManagedObjectsRequest) returns (ListManagedObjectsResponse); } service BlobStore { diff --git a/pkg/storage/unified/resource/resource_grpc.pb.go b/pkg/storage/unified/resource/resource_grpc.pb.go index 74b085ccea0..25c4a937f9c 100644 --- a/pkg/storage/unified/resource/resource_grpc.pb.go +++ b/pkg/storage/unified/resource/resource_grpc.pb.go @@ -650,136 +650,136 @@ var ResourceIndex_ServiceDesc = grpc.ServiceDesc{ } const ( - RepositoryIndex_CountRepositoryObjects_FullMethodName = "/resource.RepositoryIndex/CountRepositoryObjects" - RepositoryIndex_ListRepositoryObjects_FullMethodName = "/resource.RepositoryIndex/ListRepositoryObjects" + ManagedObjectIndex_CountManagedObjects_FullMethodName = "/resource.ManagedObjectIndex/CountManagedObjects" + ManagedObjectIndex_ListManagedObjects_FullMethodName = "/resource.ManagedObjectIndex/ListManagedObjects" ) -// RepositoryIndexClient is the client API for RepositoryIndex service. +// ManagedObjectIndexClient is the client API for ManagedObjectIndex service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. // -// Query repository info from the search index. +// Query managed objects // Results access control is based on access to the repository *not* the items -type RepositoryIndexClient interface { +type ManagedObjectIndexClient interface { // Describe how many resources of each type exist within a repository - CountRepositoryObjects(ctx context.Context, in *CountRepositoryObjectsRequest, opts ...grpc.CallOption) (*CountRepositoryObjectsResponse, error) + CountManagedObjects(ctx context.Context, in *CountManagedObjectsRequest, opts ...grpc.CallOption) (*CountManagedObjectsResponse, error) // List the resources of a specific kind within a repository - ListRepositoryObjects(ctx context.Context, in *ListRepositoryObjectsRequest, opts ...grpc.CallOption) (*ListRepositoryObjectsResponse, error) + ListManagedObjects(ctx context.Context, in *ListManagedObjectsRequest, opts ...grpc.CallOption) (*ListManagedObjectsResponse, error) } -type repositoryIndexClient struct { +type managedObjectIndexClient struct { cc grpc.ClientConnInterface } -func NewRepositoryIndexClient(cc grpc.ClientConnInterface) RepositoryIndexClient { - return &repositoryIndexClient{cc} +func NewManagedObjectIndexClient(cc grpc.ClientConnInterface) ManagedObjectIndexClient { + return &managedObjectIndexClient{cc} } -func (c *repositoryIndexClient) CountRepositoryObjects(ctx context.Context, in *CountRepositoryObjectsRequest, opts ...grpc.CallOption) (*CountRepositoryObjectsResponse, error) { +func (c *managedObjectIndexClient) CountManagedObjects(ctx context.Context, in *CountManagedObjectsRequest, opts ...grpc.CallOption) (*CountManagedObjectsResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(CountRepositoryObjectsResponse) - err := c.cc.Invoke(ctx, RepositoryIndex_CountRepositoryObjects_FullMethodName, in, out, cOpts...) + out := new(CountManagedObjectsResponse) + err := c.cc.Invoke(ctx, ManagedObjectIndex_CountManagedObjects_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -func (c *repositoryIndexClient) ListRepositoryObjects(ctx context.Context, in *ListRepositoryObjectsRequest, opts ...grpc.CallOption) (*ListRepositoryObjectsResponse, error) { +func (c *managedObjectIndexClient) ListManagedObjects(ctx context.Context, in *ListManagedObjectsRequest, opts ...grpc.CallOption) (*ListManagedObjectsResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) - out := new(ListRepositoryObjectsResponse) - err := c.cc.Invoke(ctx, RepositoryIndex_ListRepositoryObjects_FullMethodName, in, out, cOpts...) + out := new(ListManagedObjectsResponse) + err := c.cc.Invoke(ctx, ManagedObjectIndex_ListManagedObjects_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } return out, nil } -// RepositoryIndexServer is the server API for RepositoryIndex service. -// All implementations should embed UnimplementedRepositoryIndexServer +// ManagedObjectIndexServer is the server API for ManagedObjectIndex service. +// All implementations should embed UnimplementedManagedObjectIndexServer // for forward compatibility // -// Query repository info from the search index. +// Query managed objects // Results access control is based on access to the repository *not* the items -type RepositoryIndexServer interface { +type ManagedObjectIndexServer interface { // Describe how many resources of each type exist within a repository - CountRepositoryObjects(context.Context, *CountRepositoryObjectsRequest) (*CountRepositoryObjectsResponse, error) + CountManagedObjects(context.Context, *CountManagedObjectsRequest) (*CountManagedObjectsResponse, error) // List the resources of a specific kind within a repository - ListRepositoryObjects(context.Context, *ListRepositoryObjectsRequest) (*ListRepositoryObjectsResponse, error) + ListManagedObjects(context.Context, *ListManagedObjectsRequest) (*ListManagedObjectsResponse, error) } -// UnimplementedRepositoryIndexServer should be embedded to have forward compatible implementations. -type UnimplementedRepositoryIndexServer struct { +// UnimplementedManagedObjectIndexServer should be embedded to have forward compatible implementations. +type UnimplementedManagedObjectIndexServer struct { } -func (UnimplementedRepositoryIndexServer) CountRepositoryObjects(context.Context, *CountRepositoryObjectsRequest) (*CountRepositoryObjectsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method CountRepositoryObjects not implemented") +func (UnimplementedManagedObjectIndexServer) CountManagedObjects(context.Context, *CountManagedObjectsRequest) (*CountManagedObjectsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CountManagedObjects not implemented") } -func (UnimplementedRepositoryIndexServer) ListRepositoryObjects(context.Context, *ListRepositoryObjectsRequest) (*ListRepositoryObjectsResponse, error) { - return nil, status.Errorf(codes.Unimplemented, "method ListRepositoryObjects not implemented") +func (UnimplementedManagedObjectIndexServer) ListManagedObjects(context.Context, *ListManagedObjectsRequest) (*ListManagedObjectsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListManagedObjects not implemented") } -// UnsafeRepositoryIndexServer may be embedded to opt out of forward compatibility for this service. -// Use of this interface is not recommended, as added methods to RepositoryIndexServer will +// UnsafeManagedObjectIndexServer may be embedded to opt out of forward compatibility for this service. +// Use of this interface is not recommended, as added methods to ManagedObjectIndexServer will // result in compilation errors. -type UnsafeRepositoryIndexServer interface { - mustEmbedUnimplementedRepositoryIndexServer() +type UnsafeManagedObjectIndexServer interface { + mustEmbedUnimplementedManagedObjectIndexServer() } -func RegisterRepositoryIndexServer(s grpc.ServiceRegistrar, srv RepositoryIndexServer) { - s.RegisterService(&RepositoryIndex_ServiceDesc, srv) +func RegisterManagedObjectIndexServer(s grpc.ServiceRegistrar, srv ManagedObjectIndexServer) { + s.RegisterService(&ManagedObjectIndex_ServiceDesc, srv) } -func _RepositoryIndex_CountRepositoryObjects_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(CountRepositoryObjectsRequest) +func _ManagedObjectIndex_CountManagedObjects_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CountManagedObjectsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(RepositoryIndexServer).CountRepositoryObjects(ctx, in) + return srv.(ManagedObjectIndexServer).CountManagedObjects(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: RepositoryIndex_CountRepositoryObjects_FullMethodName, + FullMethod: ManagedObjectIndex_CountManagedObjects_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RepositoryIndexServer).CountRepositoryObjects(ctx, req.(*CountRepositoryObjectsRequest)) + return srv.(ManagedObjectIndexServer).CountManagedObjects(ctx, req.(*CountManagedObjectsRequest)) } return interceptor(ctx, in, info, handler) } -func _RepositoryIndex_ListRepositoryObjects_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ListRepositoryObjectsRequest) +func _ManagedObjectIndex_ListManagedObjects_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListManagedObjectsRequest) if err := dec(in); err != nil { return nil, err } if interceptor == nil { - return srv.(RepositoryIndexServer).ListRepositoryObjects(ctx, in) + return srv.(ManagedObjectIndexServer).ListManagedObjects(ctx, in) } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: RepositoryIndex_ListRepositoryObjects_FullMethodName, + FullMethod: ManagedObjectIndex_ListManagedObjects_FullMethodName, } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(RepositoryIndexServer).ListRepositoryObjects(ctx, req.(*ListRepositoryObjectsRequest)) + return srv.(ManagedObjectIndexServer).ListManagedObjects(ctx, req.(*ListManagedObjectsRequest)) } return interceptor(ctx, in, info, handler) } -// RepositoryIndex_ServiceDesc is the grpc.ServiceDesc for RepositoryIndex service. +// ManagedObjectIndex_ServiceDesc is the grpc.ServiceDesc for ManagedObjectIndex service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) -var RepositoryIndex_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "resource.RepositoryIndex", - HandlerType: (*RepositoryIndexServer)(nil), +var ManagedObjectIndex_ServiceDesc = grpc.ServiceDesc{ + ServiceName: "resource.ManagedObjectIndex", + HandlerType: (*ManagedObjectIndexServer)(nil), Methods: []grpc.MethodDesc{ { - MethodName: "CountRepositoryObjects", - Handler: _RepositoryIndex_CountRepositoryObjects_Handler, + MethodName: "CountManagedObjects", + Handler: _ManagedObjectIndex_CountManagedObjects_Handler, }, { - MethodName: "ListRepositoryObjects", - Handler: _RepositoryIndex_ListRepositoryObjects_Handler, + MethodName: "ListManagedObjects", + Handler: _ManagedObjectIndex_ListManagedObjects_Handler, }, }, Streams: []grpc.StreamDesc{}, diff --git a/pkg/storage/unified/resource/search.go b/pkg/storage/unified/resource/search.go index 06447822659..3a85832c93b 100644 --- a/pkg/storage/unified/resource/search.go +++ b/pkg/storage/unified/resource/search.go @@ -48,10 +48,10 @@ type ResourceIndex interface { Search(ctx context.Context, access types.AccessClient, req *ResourceSearchRequest, federate []ResourceIndex) (*ResourceSearchResponse, error) // List within an response - ListRepositoryObjects(ctx context.Context, req *ListRepositoryObjectsRequest) (*ListRepositoryObjectsResponse, error) + ListManagedObjects(ctx context.Context, req *ListManagedObjectsRequest) (*ListManagedObjectsResponse, error) // Counts the values in a repo - CountRepositoryObjects(ctx context.Context) ([]*CountRepositoryObjectsResponse_ResourceCount, error) + CountManagedObjects(ctx context.Context) ([]*CountManagedObjectsResponse_ResourceCount, error) // Get the number of documents in the index DocCount(ctx context.Context, folder string) (int64, error) @@ -99,8 +99,8 @@ type searchSupport struct { } var ( - _ ResourceIndexServer = (*searchSupport)(nil) - _ RepositoryIndexServer = (*searchSupport)(nil) + _ ResourceIndexServer = (*searchSupport)(nil) + _ ManagedObjectIndexServer = (*searchSupport)(nil) ) func newSearchSupport(opts SearchOptions, storage StorageBackend, access types.AccessClient, blob BlobSupport, tracer trace.Tracer) (support *searchSupport, err error) { @@ -139,14 +139,14 @@ func newSearchSupport(opts SearchOptions, storage StorageBackend, access types.A return support, err } -func (s *searchSupport) ListRepositoryObjects(ctx context.Context, req *ListRepositoryObjectsRequest) (*ListRepositoryObjectsResponse, error) { +func (s *searchSupport) ListManagedObjects(ctx context.Context, req *ListManagedObjectsRequest) (*ListManagedObjectsResponse, error) { if req.NextPageToken != "" { - return &ListRepositoryObjectsResponse{ + return &ListManagedObjectsResponse{ Error: NewBadRequestError("multiple pages not yet supported"), }, nil } - rsp := &ListRepositoryObjectsResponse{} + rsp := &ListManagedObjectsResponse{} stats, err := s.storage.GetResourceStats(ctx, req.Namespace, 0) if err != nil { rsp.Error = AsErrorResult(err) @@ -164,7 +164,7 @@ func (s *searchSupport) ListRepositoryObjects(ctx context.Context, req *ListRepo return rsp, nil } - kind, err := idx.ListRepositoryObjects(ctx, req) + kind, err := idx.ListManagedObjects(ctx, req) if err != nil { rsp.Error = AsErrorResult(err) return rsp, nil @@ -179,15 +179,15 @@ func (s *searchSupport) ListRepositoryObjects(ctx context.Context, req *ListRepo } // Sort based on path - slices.SortFunc(rsp.Items, func(a, b *ListRepositoryObjectsResponse_Item) int { + slices.SortFunc(rsp.Items, func(a, b *ListManagedObjectsResponse_Item) int { return cmp.Compare(a.Path, b.Path) }) return rsp, nil } -func (s *searchSupport) CountRepositoryObjects(ctx context.Context, req *CountRepositoryObjectsRequest) (*CountRepositoryObjectsResponse, error) { - rsp := &CountRepositoryObjectsResponse{} +func (s *searchSupport) CountManagedObjects(ctx context.Context, req *CountManagedObjectsRequest) (*CountManagedObjectsResponse, error) { + rsp := &CountManagedObjectsResponse{} stats, err := s.storage.GetResourceStats(ctx, req.Namespace, 0) if err != nil { rsp.Error = AsErrorResult(err) @@ -205,27 +205,27 @@ func (s *searchSupport) CountRepositoryObjects(ctx context.Context, req *CountRe return rsp, nil } - counts, err := idx.CountRepositoryObjects(ctx) + counts, err := idx.CountManagedObjects(ctx) if err != nil { rsp.Error = AsErrorResult(err) return rsp, nil } - if req.Name == "" { + if req.Id == "" { rsp.Items = append(rsp.Items, counts...) } else { for _, k := range counts { - if k.Repository == req.Name { - k.Repository = "" // avoid duplicate response metadata + if k.Id == req.Id { rsp.Items = append(rsp.Items, k) } } } } - // Sort based on repo/group/resource - slices.SortFunc(rsp.Items, func(a, b *CountRepositoryObjectsResponse_ResourceCount) int { + // Sort based on manager/group/resource + slices.SortFunc(rsp.Items, func(a, b *CountManagedObjectsResponse_ResourceCount) int { return cmp.Or( - cmp.Compare(a.Repository, b.Repository), + cmp.Compare(a.Kind, b.Kind), + cmp.Compare(a.Id, b.Id), cmp.Compare(a.Group, b.Group), cmp.Compare(a.Resource, b.Resource), ) diff --git a/pkg/storage/unified/resource/server.go b/pkg/storage/unified/resource/server.go index 9cc505d40f6..0acc0dd2520 100644 --- a/pkg/storage/unified/resource/server.go +++ b/pkg/storage/unified/resource/server.go @@ -28,7 +28,7 @@ type ResourceServer interface { ResourceStoreServer BulkStoreServer ResourceIndexServer - RepositoryIndexServer + ManagedObjectIndexServer BlobStoreServer DiagnosticsServer } @@ -1105,12 +1105,12 @@ func (s *server) GetStats(ctx context.Context, req *ResourceStatsRequest) (*Reso return s.search.GetStats(ctx, req) } -func (s *server) ListRepositoryObjects(ctx context.Context, req *ListRepositoryObjectsRequest) (*ListRepositoryObjectsResponse, error) { - return s.search.ListRepositoryObjects(ctx, req) +func (s *server) ListManagedObjects(ctx context.Context, req *ListManagedObjectsRequest) (*ListManagedObjectsResponse, error) { + return s.search.ListManagedObjects(ctx, req) } -func (s *server) CountRepositoryObjects(ctx context.Context, req *CountRepositoryObjectsRequest) (*CountRepositoryObjectsResponse, error) { - return s.search.CountRepositoryObjects(ctx, req) +func (s *server) CountManagedObjects(ctx context.Context, req *CountManagedObjectsRequest) (*CountManagedObjectsResponse, error) { + return s.search.CountManagedObjects(ctx, req) } // IsHealthy implements ResourceServer. diff --git a/pkg/storage/unified/resource/testdata/playlist-resource.json b/pkg/storage/unified/resource/testdata/playlist-resource.json index 236ce893368..c1d4081d9c3 100644 --- a/pkg/storage/unified/resource/testdata/playlist-resource.json +++ b/pkg/storage/unified/resource/testdata/playlist-resource.json @@ -16,7 +16,7 @@ } }, "spec": { - "title": "test playlist unified storage", + "title": "Test Playlist from Unified Storage", "description": "description for the test playlist" } } \ No newline at end of file diff --git a/pkg/storage/unified/search/bleve.go b/pkg/storage/unified/search/bleve.go index 621e6c3c1b5..630c9832315 100644 --- a/pkg/storage/unified/search/bleve.go +++ b/pkg/storage/unified/search/bleve.go @@ -263,6 +263,8 @@ type bleveIndex struct { // Write implements resource.DocumentIndex. func (b *bleveIndex) Write(v *resource.IndexableDocument) error { + v = v.UpdateCopyFields() + // remove references (for now!) v.References = nil if b.batch != nil { @@ -297,21 +299,33 @@ func (b *bleveIndex) Flush() (err error) { return err } -func (b *bleveIndex) ListRepositoryObjects(ctx context.Context, req *resource.ListRepositoryObjectsRequest) (*resource.ListRepositoryObjectsResponse, error) { +func (b *bleveIndex) ListManagedObjects(ctx context.Context, req *resource.ListManagedObjectsRequest) (*resource.ListManagedObjectsResponse, error) { if req.NextPageToken != "" { return nil, fmt.Errorf("next page not implemented yet") } - if req.Name == "" { - return &resource.ListRepositoryObjectsResponse{ - Error: resource.NewBadRequestError("empty repository name"), + if req.Kind == "" { + return &resource.ListManagedObjectsResponse{ + Error: resource.NewBadRequestError("empty manager kind"), + }, nil + } + if req.Id == "" { + return &resource.ListManagedObjectsResponse{ + Error: resource.NewBadRequestError("empty manager id"), }, nil } + q := bleve.NewBooleanQuery() + q.AddMust(&query.TermQuery{ + Term: req.Kind, + FieldVal: resource.SEARCH_FIELD_MANAGER_KIND, + }) + q.AddMust(&query.TermQuery{ + Term: req.Id, + FieldVal: resource.SEARCH_FIELD_MANAGER_ID, + }) + found, err := b.index.SearchInContext(ctx, &bleve.SearchRequest{ - Query: &query.TermQuery{ - Term: req.Name, - FieldVal: resource.SEARCH_FIELD_MANAGER_ID, - }, + Query: q, Fields: []string{ resource.SEARCH_FIELD_TITLE, resource.SEARCH_FIELD_FOLDER, @@ -366,9 +380,9 @@ func (b *bleveIndex) ListRepositoryObjects(ctx context.Context, req *resource.Li return 0 } - rsp := &resource.ListRepositoryObjectsResponse{} + rsp := &resource.ListManagedObjectsResponse{} for _, hit := range found.Hits { - item := &resource.ListRepositoryObjectsResponse_Item{ + item := &resource.ListManagedObjectsResponse_Item{ Object: &resource.ResourceKey{}, Hash: asString(hit.Fields[resource.SEARCH_FIELD_SOURCE_CHECKSUM]), Path: asString(hit.Fields[resource.SEARCH_FIELD_SOURCE_PATH]), @@ -385,27 +399,32 @@ func (b *bleveIndex) ListRepositoryObjects(ctx context.Context, req *resource.Li return rsp, nil } -func (b *bleveIndex) CountRepositoryObjects(ctx context.Context) ([]*resource.CountRepositoryObjectsResponse_ResourceCount, error) { +func (b *bleveIndex) CountManagedObjects(ctx context.Context) ([]*resource.CountManagedObjectsResponse_ResourceCount, error) { found, err := b.index.SearchInContext(ctx, &bleve.SearchRequest{ Query: bleve.NewMatchAllQuery(), Size: 0, Facets: bleve.FacetsRequest{ - "count": bleve.NewFacetRequest(resource.SEARCH_FIELD_MANAGER_ID, 1000), // typically less then 5 + "count": bleve.NewFacetRequest(resource.SEARCH_FIELD_MANAGED_BY, 1000), // typically less then 5 }, }) if err != nil { return nil, err } - vals := make([]*resource.CountRepositoryObjectsResponse_ResourceCount, 0) + vals := make([]*resource.CountManagedObjectsResponse_ResourceCount, 0) f, ok := found.Facets["count"] if ok && f.Terms != nil { for _, v := range f.Terms.Terms() { - vals = append(vals, &resource.CountRepositoryObjectsResponse_ResourceCount{ - Repository: v.Term, - Group: b.key.Group, - Resource: b.key.Resource, - Count: int64(v.Count), - }) + val := v.Term + idx := strings.Index(val, ":") + if idx > 0 { + vals = append(vals, &resource.CountManagedObjectsResponse_ResourceCount{ + Kind: val[0:idx], + Id: val[idx+1:], + Group: b.key.Group, + Resource: b.key.Resource, + Count: int64(v.Count), + }) + } } } return vals, nil diff --git a/pkg/storage/unified/search/bleve_mappings.go b/pkg/storage/unified/search/bleve_mappings.go index 8ffceeca568..c9afce91a09 100644 --- a/pkg/storage/unified/search/bleve_mappings.go +++ b/pkg/storage/unified/search/bleve_mappings.go @@ -34,7 +34,7 @@ func getBleveDocMappings(_ resource.SearchableDocumentFields) *mapping.DocumentM // for searching by title - uses an edge ngram token filter titleSearchMapping := bleve.NewTextFieldMapping() titleSearchMapping.Analyzer = TITLE_ANALYZER - titleSearchMapping.Store = true + titleSearchMapping.Store = false // already stored in title mapper.AddFieldMappingsAt(resource.SEARCH_FIELD_TITLE_NGRAM, titleSearchMapping) // mapping for title to search on words/tokens larger than the ngram size @@ -45,6 +45,7 @@ func getBleveDocMappings(_ resource.SearchableDocumentFields) *mapping.DocumentM // for filtering/sorting by title full phrase titlePhraseMapping := bleve.NewKeywordFieldMapping() + titleSearchMapping.Store = false // already stored in title mapper.AddFieldMappingsAt(resource.SEARCH_FIELD_TITLE_PHRASE, titlePhraseMapping) descriptionMapping := &mapping.FieldMapping{ @@ -124,8 +125,17 @@ func getBleveDocMappings(_ resource.SearchableDocumentFields) *mapping.DocumentM }) source.AddFieldMappingsAt("timestampMillis", mapping.NewNumericFieldMapping()) - mapper.AddSubDocumentMapping("manager", manager) mapper.AddSubDocumentMapping("source", source) + mapper.AddSubDocumentMapping("manager", manager) + mapper.AddFieldMappingsAt(resource.SEARCH_FIELD_MANAGED_BY, &mapping.FieldMapping{ + Name: "managedBy", + Type: "text", + Analyzer: keyword.Name, + Index: true, // only used for faceting + Store: false, + IncludeTermVectors: false, + IncludeInAll: false, + }) labelMapper := bleve.NewDocumentMapping() mapper.AddSubDocumentMapping(resource.SEARCH_FIELD_LABELS, labelMapper) diff --git a/pkg/storage/unified/search/bleve_mappings_test.go b/pkg/storage/unified/search/bleve_mappings_test.go index e4aa1165a8a..9c1c6c7f8ad 100644 --- a/pkg/storage/unified/search/bleve_mappings_test.go +++ b/pkg/storage/unified/search/bleve_mappings_test.go @@ -36,6 +36,7 @@ func TestDocumentMapping(t *testing.T) { TimestampMillis: 1234, }, } + data.UpdateCopyFields() doc := document.NewDocument("id") err = mappings.MapDocument(doc, data) @@ -47,5 +48,5 @@ func TestDocumentMapping(t *testing.T) { fmt.Printf("DOC: fields %d\n", len(doc.Fields)) fmt.Printf("DOC: size %d\n", doc.Size()) - require.Equal(t, 15, len(doc.Fields)) + require.Equal(t, 16, len(doc.Fields)) } diff --git a/pkg/storage/unified/search/bleve_search_test.go b/pkg/storage/unified/search/bleve_search_test.go index ce4e8814916..39eb0638995 100644 --- a/pkg/storage/unified/search/bleve_search_test.go +++ b/pkg/storage/unified/search/bleve_search_test.go @@ -8,13 +8,14 @@ import ( "testing" "github.com/blevesearch/bleve/v2" + "github.com/stretchr/testify/require" + "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/store/kind/dashboard" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/storage/unified/resource" - "github.com/stretchr/testify/require" ) func TestCanSearchByTitle(t *testing.T) { @@ -35,9 +36,7 @@ func TestCanSearchByTitle(t *testing.T) { Group: key.Group, Resource: key.Resource, }, - Title: "bbb", - TitleNgram: "bbb", - TitlePhrase: "bbb", + Title: "bbb", }) require.NoError(t, err) err = index.Write(&resource.IndexableDocument{ @@ -49,9 +48,7 @@ func TestCanSearchByTitle(t *testing.T) { Group: key.Group, Resource: key.Resource, }, - Title: "aaa", - TitleNgram: "aaa", - TitlePhrase: "aaa", + Title: "aaa", }) require.NoError(t, err) @@ -74,9 +71,7 @@ func TestCanSearchByTitle(t *testing.T) { Group: key.Group, Resource: key.Resource, }, - Title: "I want to say a hello", - TitleNgram: "I want to say a hello", - TitlePhrase: "I want to say a hello", + Title: "I want to say a hello", }) require.NoError(t, err) err = index.Write(&resource.IndexableDocument{ @@ -88,9 +83,7 @@ func TestCanSearchByTitle(t *testing.T) { Group: key.Group, Resource: key.Resource, }, - Title: "we want hello", - TitleNgram: "we want hello", - TitlePhrase: "we want hello", + Title: "we want hello", }) require.NoError(t, err) @@ -113,9 +106,7 @@ func TestCanSearchByTitle(t *testing.T) { Group: key.Group, Resource: key.Resource, }, - Title: "Asserts Dashboards", - TitleNgram: "Asserts Dashboards", - TitlePhrase: "Asserts Dashboards", + Title: "Asserts Dashboards", }) require.NoError(t, err) err = index.Write(&resource.IndexableDocument{ @@ -127,9 +118,7 @@ func TestCanSearchByTitle(t *testing.T) { Group: key.Group, Resource: key.Resource, }, - Title: "New dashboard 10", - TitleNgram: "New dashboard 10", - TitlePhrase: "New dashboard 10", + Title: "New dashboard 10", }) require.NoError(t, err) @@ -151,9 +140,7 @@ func TestCanSearchByTitle(t *testing.T) { Group: key.Group, Resource: key.Resource, }, - Title: "we want hello pls", - TitleNgram: "we want hello pls", - TitlePhrase: "we want hello pls", + Title: "we want hello pls", }) require.NoError(t, err) err = index.Write(&resource.IndexableDocument{ @@ -165,9 +152,7 @@ func TestCanSearchByTitle(t *testing.T) { Group: key.Group, Resource: key.Resource, }, - Title: "we want hello", - TitleNgram: "we want hello", - TitlePhrase: "we want hello", + Title: "we want hello", }) require.NoError(t, err) @@ -190,8 +175,7 @@ func TestCanSearchByTitle(t *testing.T) { Group: key.Group, Resource: key.Resource, }, - Title: "A123456", - TitleNgram: "A123456", + Title: "A123456", }) require.NoError(t, err) @@ -219,9 +203,7 @@ func TestCanSearchByTitle(t *testing.T) { Group: key.Group, Resource: key.Resource, }, - Title: "I want to say a wonderfully Hello to the WORLD! Hello-world", - TitleNgram: "I want to say a wonderfully Hello to the WORLD! Hello-world", - TitlePhrase: "I want to say a wonderfully Hello to the WORLD! Hello-world", + Title: "I want to say a wonderfully Hello to the WORLD! Hello-world", }) require.NoError(t, err) @@ -279,8 +261,7 @@ func TestCanSearchByTitle(t *testing.T) { Group: key.Group, Resource: key.Resource, }, - Title: "I want to say a wonderful Hello to the WORLD! Hello-world", - TitleNgram: "I want to say a wonderful Hello to the WORLD! Hello-world", + Title: "I want to say a wonderful Hello to the WORLD! Hello-world", }) require.NoError(t, err) err = index.Write(&resource.IndexableDocument{ @@ -292,8 +273,7 @@ func TestCanSearchByTitle(t *testing.T) { Group: key.Group, Resource: key.Resource, }, - Title: "A0456", - TitleNgram: "A0456", + Title: "A0456", }) require.NoError(t, err) err = index.Write(&resource.IndexableDocument{ @@ -305,9 +285,7 @@ func TestCanSearchByTitle(t *testing.T) { Group: key.Group, Resource: key.Resource, }, - Title: "mash-A02382-10", - TitleNgram: "mash-A02382-10", - TitlePhrase: "mash-A02382-10", + Title: "mash-A02382-10", }) require.NoError(t, err) diff --git a/pkg/storage/unified/search/bleve_test.go b/pkg/storage/unified/search/bleve_test.go index fa572536d05..f1d6fec51b6 100644 --- a/pkg/storage/unified/search/bleve_test.go +++ b/pkg/storage/unified/search/bleve_test.go @@ -76,9 +76,8 @@ func TestBleveBackend(t *testing.T) { Group: "dashboard.grafana.app", Resource: "dashboards", }, - Title: "aaa (dash)", - TitlePhrase: "aaa (dash)", - Folder: "xxx", + Title: "aaa (dash)", + Folder: "xxx", Fields: map[string]any{ DASHBOARD_PANEL_TYPES: []string{"timeseries", "table"}, DASHBOARD_ERRORS_TODAY: 25, @@ -107,9 +106,8 @@ func TestBleveBackend(t *testing.T) { Group: "dashboard.grafana.app", Resource: "dashboards", }, - Title: "bbb (dash)", - TitlePhrase: "bbb (dash)", - Folder: "xxx", + Title: "bbb (dash)", + Folder: "xxx", Fields: map[string]any{ DASHBOARD_PANEL_TYPES: []string{"timeseries"}, DASHBOARD_ERRORS_TODAY: 40, @@ -138,10 +136,9 @@ func TestBleveBackend(t *testing.T) { Group: "dashboard.grafana.app", Resource: "dashboards", }, - Name: "ccc", - Title: "ccc (dash)", - TitlePhrase: "ccc (dash)", - Folder: "zzz", + Name: "ccc", + Title: "ccc (dash)", + Folder: "zzz", Manager: &utils.ManagerProperties{ Kind: utils.ManagerKindRepo, Identity: "repo2", @@ -263,8 +260,9 @@ func TestBleveBackend(t *testing.T) { require.Equal(t, 0, len(rsp.Results.Rows)) // Now look for repositories - found, err := index.ListRepositoryObjects(ctx, &resource.ListRepositoryObjectsRequest{ - Name: "repo-1", + found, err := index.ListManagedObjects(ctx, &resource.ListManagedObjectsRequest{ + Kind: "repo", + Id: "repo-1", }) require.NoError(t, err) jj, err := json.MarshalIndent(found, "", " ") @@ -302,20 +300,22 @@ func TestBleveBackend(t *testing.T) { ] }`, string(jj)) - counts, err := index.CountRepositoryObjects(ctx) + counts, err := index.CountManagedObjects(ctx) require.NoError(t, err) jj, err = json.MarshalIndent(counts, "", " ") require.NoError(t, err) fmt.Printf("%s\n", string(jj)) require.JSONEq(t, `[ { - "repository": "repo-1", + "kind": "repo", + "id": "repo-1", "group": "dashboard.grafana.app", "resource": "dashboards", "count": 2 }, { - "repository": "repo2", + "kind": "repo", + "id": "repo2", "group": "dashboard.grafana.app", "resource": "dashboards", "count": 1 @@ -340,8 +340,7 @@ func TestBleveBackend(t *testing.T) { Group: "folder.grafana.app", Resource: "folders", }, - Title: "zzz (folder)", - TitlePhrase: "zzz (folder)", + Title: "zzz (folder)", Manager: &utils.ManagerProperties{ Kind: utils.ManagerKindRepo, Identity: "repo-1", @@ -360,8 +359,7 @@ func TestBleveBackend(t *testing.T) { Group: "folder.grafana.app", Resource: "folders", }, - Title: "yyy (folder)", - TitlePhrase: "yyy (folder)", + Title: "yyy (folder)", Labels: map[string]string{ "region": "west", }, diff --git a/pkg/storage/unified/search/testdata/doc/folder-aaa-out.json b/pkg/storage/unified/search/testdata/doc/folder-aaa-out.json index aff5002f8b6..f3d12b9a6e8 100644 --- a/pkg/storage/unified/search/testdata/doc/folder-aaa-out.json +++ b/pkg/storage/unified/search/testdata/doc/folder-aaa-out.json @@ -15,5 +15,6 @@ "manager": { "kind": "repo", "id": "MyGIT" - } + }, + "managedBy": "repo:MyGIT" } \ No newline at end of file diff --git a/pkg/storage/unified/search/testdata/doc/folder-bbb-out.json b/pkg/storage/unified/search/testdata/doc/folder-bbb-out.json index 5ff5292aa96..adadea669c4 100644 --- a/pkg/storage/unified/search/testdata/doc/folder-bbb-out.json +++ b/pkg/storage/unified/search/testdata/doc/folder-bbb-out.json @@ -15,5 +15,6 @@ "manager": { "kind": "repo", "id": "MyGIT" - } + }, + "managedBy": "repo:MyGIT" } \ No newline at end of file diff --git a/pkg/storage/unified/sql/search.go b/pkg/storage/unified/sql/search.go index 32c29aeda59..8c15be1ae66 100644 --- a/pkg/storage/unified/sql/search.go +++ b/pkg/storage/unified/sql/search.go @@ -53,11 +53,11 @@ func (b *backend) GetStats(ctx context.Context, req *resource.ResourceStatsReque return rsp, nil } -func (b *backend) RepositoryList(ctx context.Context, req *resource.ListRepositoryObjectsRequest) (*resource.ListRepositoryObjectsResponse, error) { +func (b *backend) RepositoryList(ctx context.Context, req *resource.ListManagedObjectsRequest) (*resource.ListManagedObjectsResponse, error) { return nil, fmt.Errorf("SQL backend does not implement RepositoryList") } -func (b *backend) RepositoryStats(context.Context, *resource.CountRepositoryObjectsRequest) (*resource.CountRepositoryObjectsResponse, error) { +func (b *backend) RepositoryStats(context.Context, *resource.CountManagedObjectsRequest) (*resource.CountManagedObjectsResponse, error) { return nil, fmt.Errorf("SQL backend does not implement RepositoryStats") } diff --git a/pkg/storage/unified/sql/service.go b/pkg/storage/unified/sql/service.go index 8decdf96055..e6ad6cd6096 100644 --- a/pkg/storage/unified/sql/service.go +++ b/pkg/storage/unified/sql/service.go @@ -133,7 +133,7 @@ func (s *service) start(ctx context.Context) error { resource.RegisterResourceStoreServer(srv, server) resource.RegisterBulkStoreServer(srv, server) resource.RegisterResourceIndexServer(srv, server) - resource.RegisterRepositoryIndexServer(srv, server) + resource.RegisterManagedObjectIndexServer(srv, server) resource.RegisterBlobStoreServer(srv, server) resource.RegisterDiagnosticsServer(srv, server) grpc_health_v1.RegisterHealthServer(srv, healthService) From 2553f9aea8dcd3288d3e08e4797b832717cae801 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Mon, 10 Mar 2025 20:24:17 +0300 Subject: [PATCH 18/63] merge main --- pkg/apis/provisioning/v0alpha1/types.go | 10 +++++--- .../apis/provisioning/resources/object.go | 25 +++++++++++-------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/pkg/apis/provisioning/v0alpha1/types.go b/pkg/apis/provisioning/v0alpha1/types.go index 8a6f2478636..b14bb2592da 100644 --- a/pkg/apis/provisioning/v0alpha1/types.go +++ b/pkg/apis/provisioning/v0alpha1/types.go @@ -4,6 +4,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" + "github.com/grafana/grafana/pkg/apimachinery/utils" ) // When this code is changed, make sure to update the code generation. @@ -352,10 +353,11 @@ type ResourceStats struct { } type ResourceCount struct { - Repository string `json:"repository,omitempty"` - Group string `json:"group"` - Resource string `json:"resource"` - Count int64 `json:"count"` + Kind utils.ManagerKind `json:"kind,omitempty"` + Identity string `json:"id,omitempty"` + Group string `json:"group"` + Resource string `json:"resource"` + Count int64 `json:"count"` } // HistoryList is a list of versions of a resource diff --git a/pkg/registry/apis/provisioning/resources/object.go b/pkg/registry/apis/provisioning/resources/object.go index 2d511d7090b..38c676eb8da 100644 --- a/pkg/registry/apis/provisioning/resources/object.go +++ b/pkg/registry/apis/provisioning/resources/object.go @@ -3,6 +3,7 @@ package resources import ( "context" + "github.com/grafana/grafana/pkg/apimachinery/utils" provisioning "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1" "github.com/grafana/grafana/pkg/storage/unified/resource" ) @@ -14,10 +15,10 @@ type ResourceLister interface { } type ResourceListerFromSearch struct { - index resource.RepositoryIndexClient + index resource.ManagedObjectIndexClient } -func NewResourceLister(index resource.RepositoryIndexClient) ResourceLister { +func NewResourceLister(index resource.ManagedObjectIndexClient) ResourceLister { return &ResourceListerFromSearch{ index: index, } @@ -25,9 +26,10 @@ func NewResourceLister(index resource.RepositoryIndexClient) ResourceLister { // List implements ResourceLister. func (o *ResourceListerFromSearch) List(ctx context.Context, namespace, repository string) (*provisioning.ResourceList, error) { - objects, err := o.index.ListRepositoryObjects(ctx, &resource.ListRepositoryObjectsRequest{ + objects, err := o.index.ListManagedObjects(ctx, &resource.ListManagedObjectsRequest{ Namespace: namespace, - Name: repository, + Kind: string(utils.ManagerKindRepo), + Id: repository, }) if err != nil { return nil, err @@ -54,9 +56,10 @@ func (o *ResourceListerFromSearch) List(ctx context.Context, namespace, reposito // Stats implements ResourceLister. func (o *ResourceListerFromSearch) Stats(ctx context.Context, namespace, repository string) (*provisioning.ResourceStats, error) { - counts, err := o.index.CountRepositoryObjects(ctx, &resource.CountRepositoryObjectsRequest{ + counts, err := o.index.CountManagedObjects(ctx, &resource.CountManagedObjectsRequest{ Namespace: namespace, - Name: repository, + Kind: string(utils.ManagerKindRepo), + Id: repository, }) if err != nil { return nil, err @@ -68,10 +71,12 @@ func (o *ResourceListerFromSearch) Stats(ctx context.Context, namespace, reposit stats := &provisioning.ResourceStats{} for _, v := range counts.Items { stats.Items = append(stats.Items, provisioning.ResourceCount{ - Repository: v.Repository, - Group: v.Group, - Resource: v.Resource, - Count: v.Count, + Kind: utils.ManagerKind(v.Kind), + Identity: v.Id, + + Group: v.Group, + Resource: v.Resource, + Count: v.Count, }) } return stats, nil From b810696add63808ae6b33a438a7c420909544f73 Mon Sep 17 00:00:00 2001 From: "grafana-pr-automation[bot]" <140550294+grafana-pr-automation[bot]@users.noreply.github.com> Date: Mon, 10 Mar 2025 19:33:25 +0200 Subject: [PATCH 19/63] I18n: Download translations from Crowdin (#101896) New Crowdin translations by GitHub Action Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- public/locales/cs-CZ/grafana.json | 4038 +++++++++++++++++++++++++++ public/locales/de-DE/grafana.json | 28 +- public/locales/es-ES/grafana.json | 28 +- public/locales/fr-FR/grafana.json | 28 +- public/locales/hu-HU/grafana.json | 4010 ++++++++++++++++++++++++++ public/locales/id-ID/grafana.json | 3996 ++++++++++++++++++++++++++ public/locales/it-IT/grafana.json | 4010 ++++++++++++++++++++++++++ public/locales/ja-JP/grafana.json | 3996 ++++++++++++++++++++++++++ public/locales/ko-KR/grafana.json | 3996 ++++++++++++++++++++++++++ public/locales/nl-NL/grafana.json | 4010 ++++++++++++++++++++++++++ public/locales/pl-PL/grafana.json | 4038 +++++++++++++++++++++++++++ public/locales/pt-BR/grafana.json | 28 +- public/locales/pt-PT/grafana.json | 4010 ++++++++++++++++++++++++++ public/locales/ru-RU/grafana.json | 4038 +++++++++++++++++++++++++++ public/locales/sv-SE/grafana.json | 4010 ++++++++++++++++++++++++++ public/locales/tr-TR/grafana.json | 4010 ++++++++++++++++++++++++++ public/locales/zh-Hans/grafana.json | 28 +- public/locales/zh-Hant/grafana.json | 3996 ++++++++++++++++++++++++++ 18 files changed, 52208 insertions(+), 90 deletions(-) create mode 100644 public/locales/cs-CZ/grafana.json create mode 100644 public/locales/hu-HU/grafana.json create mode 100644 public/locales/id-ID/grafana.json create mode 100644 public/locales/it-IT/grafana.json create mode 100644 public/locales/ja-JP/grafana.json create mode 100644 public/locales/ko-KR/grafana.json create mode 100644 public/locales/nl-NL/grafana.json create mode 100644 public/locales/pl-PL/grafana.json create mode 100644 public/locales/pt-PT/grafana.json create mode 100644 public/locales/ru-RU/grafana.json create mode 100644 public/locales/sv-SE/grafana.json create mode 100644 public/locales/tr-TR/grafana.json create mode 100644 public/locales/zh-Hant/grafana.json diff --git a/public/locales/cs-CZ/grafana.json b/public/locales/cs-CZ/grafana.json new file mode 100644 index 00000000000..af5d7e65575 --- /dev/null +++ b/public/locales/cs-CZ/grafana.json @@ -0,0 +1,4038 @@ +{ + "_comment": "", + "access-control": { + "add-permission": { + "role-label": "", + "serviceaccount-label": "", + "team-label": "", + "title": "", + "user-label": "" + }, + "add-permissions": { + "save": "" + }, + "permission-list": { + "permission": "" + }, + "permission-list-item": { + "inherited": "" + }, + "permissions": { + "add-label": "", + "no-permissions": "", + "permissions-change-warning": "", + "role": "", + "serviceaccount": "", + "team": "", + "title": "", + "user": "" + } + }, + "action-editor": { + "modal": { + "cancel-button": "", + "save-button": "" + } + }, + "admin": { + "anon-users": { + "not-found": "" + }, + "edit-org": { + "access-denied": "", + "heading": "", + "update-button": "", + "users-heading": "" + }, + "feature-toggles": { + "sub-title": "" + }, + "get-enterprise": { + "contact-us": "", + "description": "", + "features-heading": "", + "included-description": "", + "included-heading": "", + "service-title": "", + "team-sync-details": "", + "title": "" + }, + "ldap": { + "test-mapping-heading": "", + "test-mapping-run-button": "" + }, + "ldap-permissions": { + "active": "", + "admin": "", + "inactive": "" + }, + "ldap-status": { + "title": "" + }, + "ldap-sync": { + "debug-button": "", + "external-sync-description": "", + "external-sync-label": "", + "next-sync-label": "", + "not-enabled": "", + "sync-button": "", + "title": "" + }, + "ldap-sync-info": { + "title": "" + }, + "ldap-user-groups": { + "no-org-found": "" + }, + "ldap-user-info": { + "no-team": "" + }, + "org-uers": { + "last-seen-never": "" + }, + "org-users": { + "not-editable": "" + }, + "orgs": { + "delete-body": "", + "id-header": "", + "name-header": "", + "new-org-button": "" + }, + "server-settings": { + "alerts-button": "", + "dashboards-button": "", + "data-sources-button": "", + "not-found": "", + "title": "", + "users-button": "" + }, + "settings": { + "info-description": "" + }, + "upgrade-info": { + "title": "" + }, + "user-orgs": { + "add-button": "", + "change-role-button": "", + "external-user-tooltip": "", + "remove-button": "", + "role-not-editable": "", + "title": "" + }, + "user-orgs-modal": { + "add-button": "", + "cancel-button": "" + }, + "user-permissions": { + "change-button": "", + "grafana-admin-key": "", + "grafana-admin-no": "", + "grafana-admin-yes": "", + "title": "" + }, + "user-profile": { + "delete-button": "", + "disable-button": "", + "edit-button": "", + "enable-button": "", + "title": "" + }, + "user-sessions": { + "browser-column": "", + "force-logout-all-button": "", + "force-logout-button": "", + "ip-column": "", + "last-seen-column": "", + "logged-on-column": "", + "title": "" + }, + "users-create": { + "create-button": "" + }, + "users-list": { + "create-button": "" + }, + "users-table": { + "last-seen-never": "", + "no-licensed-roles": "" + } + }, + "alert-labels": { + "button": { + "hide": "", + "show": { + "tooltip": "" + } + } + }, + "alerting": { + "alert": { + "alert-state": "", + "annotations": "", + "evaluation": "", + "evaluation-paused": "", + "evaluation-paused-description": "", + "last-evaluated": "", + "last-evaluation-duration": "", + "last-updated-at": "", + "last-updated-by": "", + "no-annotations": "", + "pending-period": "", + "rule": "", + "rule-identifier": "", + "rule-type": "", + "state-error-timeout": "", + "state-no-data": "", + "target-datasource-uid": "" + }, + "alert-recording-rule-form": { + "evaluation-behaviour": { + "description": { + "text": "" + } + } + }, + "alert-rules": { + "firing-for": "", + "next-evaluation": "", + "next-evaluation-in": "", + "rule-definition": "" + }, + "alertform": { + "labels": { + "alerting": "", + "recording": "" + } + }, + "alertVersionHistory": { + "alerting": "", + "alerting-change-description": "", + "annotations": "", + "compare": "", + "compare-with-latest": "", + "compareVersions": "", + "comparing-versions": "", + "condition": "", + "contactPointRouting": "", + "description": "", + "errorloading": "", + "execErrorState": "", + "intervalSeconds": "", + "labels": "", + "latest": "", + "name": "", + "namespace_uid": "", + "noDataState": "", + "noVersionsFound": "", + "paused": "", + "pendingPeriod": "", + "provisioning": "", + "provisioning-change-description": "", + "queryAndAlertCondition": "", + "restore": "", + "restore-manually": "", + "restore-modal": { + "body": "", + "confirm": "", + "error": "", + "summary": "", + "title": "" + }, + "restore-version": "", + "rule_group": "", + "unknown": "", + "unknown-change-description": "", + "user-id": "", + "warning-restore-manually": "", + "warning-restore-manually-title": "" + }, + "annotations": { + "description": "", + "title": "" + }, + "central-alert-history": { + "details": { + "error": "", + "header": { + "alert-rule": "", + "instance": "", + "state": "", + "timestamp": "" + }, + "loading": "", + "no-recognized-state": "", + "no-values": "", + "not-found": "", + "number-transitions": "", + "state": { + "alerting": "", + "error": "", + "no-data": "", + "normal": "", + "pending": "" + }, + "state-transitions": "", + "unknown-event-state": "", + "unknown-rule": "", + "value-in-transition": "" + }, + "error": "", + "filter": { + "clear": "", + "info": { + "label1": "", + "label2": "", + "label3": "", + "label4": "" + } + }, + "filterBy": "", + "too-many-events": { + "text": "", + "title": "" + } + }, + "common": { + "cancel": "", + "clear-filters": "", + "delete": "", + "edit": "", + "export": "", + "export-all": "", + "loading": "", + "search-by-matchers": "", + "titles": { + "notification-templates": "" + }, + "view": "" + }, + "contact-points": { + "create": "", + "custom-template-value": "", + "delete-reasons": { + "heading": "", + "no-permissions": "", + "policies": "", + "provisioned": "", + "rules": "" + }, + "delivered-to": "", + "delivery-duration": "", + "empty-state": { + "title": "" + }, + "key-value-map": { + "add": "", + "confirm-add": "" + }, + "last-delivery-attempt": "", + "last-delivery-failed": "", + "no-contact-points-found": "", + "no-delivery-attempts": "", + "no-integrations": "", + "only-firing": "", + "receiver-summary": { + "jira": "" + }, + "telegram": { + "parse-mode-warning-body": "", + "parse-mode-warning-title": "" + }, + "used-by_one": "", + "used-by_few": "", + "used-by_many": "", + "used-by_other": "", + "used-by-rules_one": "", + "used-by-rules_few": "", + "used-by-rules_many": "", + "used-by-rules_other": "" + }, + "contactPointFilter": { + "label": "" + }, + "copy-to-clipboard": "", + "dag": { + "missing-reference": "", + "self-reference": "" + }, + "export": { + "subtitle": { + "formats": "", + "one-format": "" + } + }, + "folderAndGroup": { + "evaluation": { + "modal": { + "text": { + "alerting": "", + "recording": "" + } + } + } + }, + "group-actions": { + "actions-trigger": "", + "delete": "", + "edit": "", + "export": "", + "reorder": "" + }, + "list-view": { + "empty": { + "new-alert-rule": "", + "new-recording-rule": "", + "provisioning": "" + }, + "section": { + "dataSourceManaged": { + "title": "" + }, + "grafanaManaged": { + "export-new-rule": "", + "export-rules": "", + "loading": "", + "new-recording-rule": "", + "title": "" + } + } + }, + "manage-permissions": { + "button": "", + "title": "" + }, + "mute_timings": { + "error-loading": { + "description": "", + "title": "" + } + }, + "mute-timings": { + "add-mute-timing": "", + "description": "", + "save": "", + "saving": "" + }, + "notification-preview": { + "alertmanager": "", + "error": "", + "initialized": "", + "preview-routing": "", + "title": "", + "uninitialized": "" + }, + "notification-templates": { + "duplicate": { + "subTitle": "", + "title": "" + }, + "edit": { + "subTitle": "", + "title": "" + }, + "new": { + "subTitle": "", + "title": "" + } + }, + "policies": { + "default-policy": { + "description": "", + "title": "", + "update": "" + }, + "delete": { + "confirm": "", + "warning-1": "", + "warning-2": "" + }, + "filter-description": "", + "generated-policies": "", + "matchers": "", + "metadata": { + "active-time": "", + "delivered-to": "", + "grouped-by": "", + "grouping": { + "none": "", + "single-group": "" + }, + "inherited": "", + "mute-time": "", + "timingOptions": { + "groupInterval": { + "description": "", + "label": "" + }, + "groupWait": { + "description": "", + "label": "" + }, + "repeatInterval": { + "description": "", + "label": "" + } + }, + "n-instances_one": "", + "n-instances_few": "", + "n-instances_many": "", + "n-instances_other": "" + }, + "new-child": "", + "new-policy": "", + "no-matchers": "", + "reload-policies": "", + "save-policy": "", + "update": { + "please-wait": "", + "update-policy": "", + "updating": "" + }, + "update-errors": { + "conflict": "", + "error-code": "", + "fallback": "", + "suffix": "", + "title": "" + }, + "n-more-policies_one": "", + "n-more-policies_few": "", + "n-more-policies_many": "", + "n-more-policies_other": "" + }, + "provisioning": { + "badge-tooltip-provenance": "", + "badge-tooltip-standard": "" + }, + "queryAndExpressionsStep": { + "disableAdvancedOptions": { + "text": "" + }, + "preview": "", + "previewCondition": "" + }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, + "rule-form": { + "evaluation": { + "evaluation-group-and-interval": "", + "group": { + "cancel": "", + "create": "", + "interval": "" + }, + "group-name": "", + "group-text": "", + "new-group": "", + "pause": { + "alerting": "", + "recording": "" + }, + "select-folder-before": "" + }, + "evaluation-behaviour": { + "description": { + "text": "" + }, + "info-help": { + "text": "" + }, + "pending-period": "" + }, + "evaluation-behaviour-description1": "", + "evaluation-behaviour-description2": "", + "evaluation-behaviour-description3": "", + "evaluation-behaviour-for": { + "error-parsing": "", + "validation": "" + }, + "folder": { + "cancel": "", + "create": "", + "create-folder": "", + "creating-new-folder": "", + "label": "", + "name": "", + "new-folder": "", + "new-folder-or": "" + }, + "folder-and-labels": "", + "folders": { + "help-info": "" + }, + "labels": { + "help-info": "" + }, + "pause": { + "label": "" + }, + "threshold": { + "recovery": { + "stop-alerting-above": "", + "stop-alerting-bellow": "", + "stop-alerting-equal": "", + "stop-alerting-inside-range": "", + "stop-alerting-less": "", + "stop-alerting-more": "", + "stop-alerting-not-equal": "", + "stop-alerting-outside-range": "", + "title": "" + } + } + }, + "rule-groups": { + "delete": { + "success": "" + }, + "move": { + "success": "" + }, + "rename": { + "success": "" + }, + "update": { + "success": "" + } + }, + "rule-list": { + "configure-datasource": "", + "ds-error-boundary": { + "description": "", + "title": "" + }, + "filter-view": { + "no-more-results": "", + "no-rules-found": "" + }, + "new-alert-rule": "", + "pagination": { + "next-page": "", + "previous-page": "" + }, + "return-button": { + "title": "" + }, + "rulerrule-loading-error": "" + }, + "rule-state": { + "creating": "", + "deleting": "", + "paused": "", + "recording-rule": "" + }, + "rule-view": { + "query": { + "datasources-na": { + "description": "", + "title": "" + } + } + }, + "rule-viewer": { + "error-loading": "", + "prometheus-consistency-check": { + "alert-message": "", + "alert-title": "" + } + }, + "rules": { + "add-rule": { + "success": "" + }, + "delete-rule": { + "success": "" + }, + "pause-rule": { + "success": "" + }, + "resume-rule": { + "success": "" + }, + "update-rule": { + "success": "" + } + }, + "search": { + "property": { + "data-source": "", + "evaluation-group": "", + "labels": "", + "namespace": "", + "rule-health": "", + "rule-name": "", + "rule-type": "", + "state": "" + }, + "save-query": "" + }, + "silences": { + "affected-instances": "", + "only-firing-instances": "", + "preview-affected-instances": "" + }, + "simpleCondition": { + "alertCondition": "" + }, + "templates": { + "editor": { + "add-example": "", + "auto-complete": "", + "goto-docs": "" + }, + "help": { + "intro": "" + }, + "misconfigured-badge-text": "", + "misconfigured-warning": "", + "misconfigured-warning-details": "" + }, + "threshold": { + "to": "" + } + }, + "annotations": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + } + }, + "api-keys": { + "empty-state": { + "message": "" + } + }, + "app-chrome": { + "skip-content-button": "", + "top-bar": { + "sign-in": "" + } + }, + "app-notification": { + "item": { + "trace-id": "" + } + }, + "bookmarks-page": { + "empty": { + "message": "", + "tip": "" + } + }, + "bouncing-loader": { + "label": "" + }, + "browse-dashboards": { + "action": { + "cancel-button": "", + "cannot-move-folders": "", + "confirmation-text": "", + "delete-button": "", + "delete-modal-invalid-text": "", + "delete-modal-invalid-title": "", + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "delete-modal-title": "", + "deleting": "", + "manage-permissions-button": "", + "move-button": "", + "move-modal-alert": "", + "move-modal-field-label": "", + "move-modal-text": "", + "move-modal-title": "", + "moving": "", + "new-folder-name-required-phrase": "" + }, + "actions": { + "button-to-recently-deleted": "" + }, + "counts": { + "alertRule_one": "", + "alertRule_few": "", + "alertRule_many": "", + "alertRule_other": "", + "dashboard_one": "", + "dashboard_few": "", + "dashboard_many": "", + "dashboard_other": "", + "folder_one": "", + "folder_few": "", + "folder_many": "", + "folder_other": "", + "libraryPanel_one": "", + "libraryPanel_few": "", + "libraryPanel_many": "", + "libraryPanel_other": "", + "total_one": "", + "total_few": "", + "total_many": "", + "total_other": "" + }, + "dashboards-tree": { + "collapse-folder-button": "", + "expand-folder-button": "", + "name-column": "", + "select-all-header-checkbox": "", + "select-checkbox": "", + "tags-column": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "", + "title-folder": "" + }, + "folder-actions-button": { + "delete": "", + "folder-actions": "", + "manage-permissions": "", + "move": "" + }, + "folder-picker": { + "accessible-label": "", + "button-label": "", + "clear-selection": "", + "empty-message": "", + "error-title": "", + "non-folder-item": "", + "search-placeholder": "", + "unknown-error": "" + }, + "hard-delete": { + "success": "" + }, + "manage-folder-nav": { + "alert-rules": "", + "dashboards": "", + "panels": "" + }, + "new-folder-form": { + "cancel-label": "", + "create-label": "", + "name-label": "" + }, + "no-results": { + "clear": "", + "text": "" + }, + "soft-delete": { + "success": "" + } + }, + "clipboard-button": { + "inline-toast": { + "success": "" + } + }, + "combobox": { + "async": { + "error": "" + }, + "clear": { + "title": "" + }, + "custom-value": { + "description": "" + }, + "group": { + "undefined": "" + }, + "options": { + "no-found": "" + } + }, + "command-palette": { + "action": { + "change-theme": "", + "dark-theme": "", + "light-theme": "" + }, + "empty-state": { + "message": "" + }, + "search-box": { + "placeholder": "" + }, + "section": { + "actions": "", + "dashboard-search-results": "", + "folder-search-results": "", + "pages": "", + "preferences": "", + "recent-dashboards": "" + } + }, + "common": { + "apply": "", + "cancel": "", + "clear": "", + "close": "", + "collapse": "", + "edit": "", + "help": "", + "loading": "", + "locale": { + "default": "" + }, + "save": "", + "search": "", + "view": "" + }, + "configuration-tracker": { + "config-card": { + "complete": "" + } + }, + "connections": { + "connect-data": { + "category-header-label": "", + "empty-message": "", + "request-data-source": "", + "roadmap": "" + }, + "search": { + "placeholder": "" + } + }, + "core": { + "versionHistory": { + "comparison": { + "header": { + "hide-json-diff": "", + "show-json-diff": "", + "text": "" + }, + "select": "" + }, + "no-properties-changed": "", + "table": { + "updated": "", + "updatedBy": "", + "version": "" + }, + "view-json-diff": "" + } + }, + "correlations": { + "add-new": "", + "alert": { + "error-message": "", + "title": "" + }, + "basic-info-form": { + "description-description": "", + "description-label": "", + "label-description": "", + "label-label": "", + "label-placeholder": "", + "label-required": "", + "sub-text": "", + "title": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + }, + "list": { + "delete": "", + "label": "", + "loading": "", + "read-only": "", + "source": "", + "target": "" + }, + "navigation-form": { + "add-button": "", + "back-button": "", + "next-button": "", + "save-button": "" + }, + "page-content": "", + "page-heading": "", + "query-editor": { + "control-rules": "", + "data-source-text": "", + "data-source-title": "", + "error-text": "", + "error-title": "", + "loading": "", + "query-description": "", + "query-editor-title": "", + "query-label": "" + }, + "source-form": { + "control-required": "", + "description": "", + "description-external-pre": "", + "description-query-pre": "", + "external-title": "", + "heading-external": "", + "heading-query": "", + "query-title": "", + "results-description": "", + "results-label": "", + "results-required": "", + "source-description": "", + "source-label": "", + "sub-text": "" + }, + "sub-title": "", + "target-form": { + "control-rules": "", + "sub-text": "", + "target-description-external": "", + "target-description-query": "", + "target-label": "", + "target-type-description": "", + "title": "", + "type-label": "" + }, + "trans-details": { + "logfmt-description": "", + "logfmt-label": "", + "regex-description": "", + "regex-expression": "", + "regex-label": "", + "regex-map-values": "" + }, + "transform": { + "add-button": "", + "heading": "", + "no-transform": "" + }, + "transform-row": { + "expression-label": "", + "expression-required": "", + "expression-tooltip": "", + "field-input": "", + "field-label": "", + "field-tooltip": "", + "map-value-label": "", + "map-value-tooltip": "", + "remove-button": "", + "remove-tooltip": "", + "transform-required": "", + "type-label": "", + "type-tooltip": "" + } + }, + "dashboard": { + "add-menu": { + "import": "", + "paste-panel": "", + "row": "", + "visualization": "" + }, + "alert-rules-drawer": { + "redirect-link": "", + "subtitle": "" + }, + "default-layout": { + "description": "", + "item-options": { + "repeat": { + "direction": { + "horizontal": "", + "title": "", + "vertical": "" + }, + "max": "", + "title": "", + "variable": { + "description": "", + "title": "" + } + } + }, + "name": "", + "row-actions": { + "delete": "", + "modal": { + "alt-action": "", + "text": "", + "title": "" + } + }, + "row-options": { + "button": { + "label": "" + }, + "form": { + "cancel": "", + "repeat-for": { + "label": "", + "learn-more": "", + "warning": { + "text": "" + } + }, + "title": "", + "update": "" + }, + "modal": { + "title": "" + }, + "repeat": { + "title": "", + "variable": { + "title": "" + } + }, + "title": "" + } + }, + "edit-pane": { + "elements": { + "dashboard": "", + "objects": "", + "panel": "", + "panels": "", + "row": "", + "rows": "", + "tab": "", + "tabs": "" + }, + "open": "", + "row": { + "header": { + "hide": "", + "title": "" + } + } + }, + "editpane": { + "add": "", + "configure": "", + "outline": "" + }, + "empty": { + "add-library-panel-body": "", + "add-library-panel-button": "", + "add-library-panel-header": "", + "add-visualization-body": "", + "add-visualization-button": "", + "add-visualization-header": "", + "import-a-dashboard-body": "", + "import-a-dashboard-header": "", + "import-dashboard-button": "" + }, + "errors": { + "failed-to-load": "" + }, + "inspect": { + "data-tab": "", + "error-tab": "", + "json-tab": "", + "meta-tab": "", + "query-tab": "", + "stats-tab": "", + "subtitle": "", + "title": "" + }, + "inspect-data": { + "data-options": "", + "dataframe-aria-label": "", + "dataframe-label": "", + "download-csv": "", + "download-excel-description": "", + "download-excel-label": "", + "download-logs": "", + "download-service": "", + "download-traces": "", + "excel-header": "", + "formatted": "", + "formatted-data-description": "", + "formatted-data-label": "", + "panel-transforms": "", + "series-to-columns": "", + "transformation": "", + "transformations-description": "", + "transformations-label": "" + }, + "inspect-json": { + "dataframe-description": "", + "dataframe-label": "", + "panel-data-description": "", + "panel-data-label": "", + "panel-json-description": "", + "panel-json-label": "", + "select-source": "", + "unknown": "" + }, + "inspect-meta": { + "no-inspector": "" + }, + "inspect-stats": { + "data-title": "", + "data-traceids": "", + "processing-time": "", + "queries": "", + "request-time": "", + "rows": "", + "table-title": "" + }, + "layout": { + "common": { + "copy": "", + "copy-or-duplicate": "", + "delete": "", + "duplicate": "", + "layout": "" + } + }, + "options": { + "description": "", + "title-option": "" + }, + "outline": { + "tree": { + "item": { + "collapse": "", + "empty": "", + "expand": "" + } + } + }, + "panel-edit": { + "alerting-tab": { + "dashboard-not-saved": "", + "no-rules": "" + } + }, + "responsive-layout": { + "description": "", + "item-options": { + "hide-no-data": "", + "repeat": { + "variable": { + "description": "", + "title": "" + } + }, + "title": "" + }, + "name": "", + "options": { + "columns": "", + "fixed": "", + "min": "", + "one-column": "", + "rows": "", + "three-columns": "", + "two-columns": "" + } + }, + "rows-layout": { + "description": "", + "name": "", + "option": { + "height": "", + "hide-header": "", + "repeat": "", + "title": "" + }, + "options": { + "height-expand": "", + "height-min": "" + }, + "row": { + "collapse": "", + "expand": "", + "menu": { + "add": "", + "add-panel": "", + "add-row-above": "", + "add-row-below": "", + "move-down": "", + "move-row": "", + "move-up": "" + }, + "new": "", + "repeat": { + "learn-more": "", + "warning": "" + } + }, + "row-options": { + "title-option": "" + } + }, + "tabs-layout": { + "description": "", + "menu": { + "move-tab": "" + }, + "name": "", + "tab": { + "menu": { + "add": "", + "add-panel": "", + "add-tab-above": "", + "add-tab-after": "", + "add-tab-before": "", + "move-left": "", + "move-right": "" + }, + "new": "" + }, + "tab-options": { + "title-option": "" + } + }, + "toolbar": { + "add": "", + "add-panel": "", + "add-panel-description": "", + "add-panel-lib": "", + "add-row": "", + "add-tab": "", + "alert-rules": "", + "back-to-dashboard": "", + "dashboard-settings": { + "label": "", + "tooltip": "" + }, + "discard-library-panel-changes": "", + "discard-panel": "", + "discard-panel-new": "", + "edit": { + "label": "", + "tooltip": "" + }, + "edit-dashboard-v2-schema": "", + "enter-edit-mode": { + "label": "", + "tooltip": "" + }, + "exit-edit-mode": { + "label": "", + "tooltip": "" + }, + "libray-panel-description": "", + "mark-favorite": "", + "more-save-options": "", + "open-original": "", + "playlist-next": "", + "playlist-previous": "", + "playlist-stop": "", + "public-dashboard": "", + "refresh": "", + "row-description": "", + "save": "", + "save-dashboard": { + "label": "", + "tooltip": "" + }, + "save-dashboard-copy": { + "label": "", + "tooltip": "" + }, + "save-dashboard-short": "", + "save-library-panel": "", + "settings": "", + "share": { + "label": "", + "tooltip": "" + }, + "share-button": "", + "show-hidden-elements": "", + "switch-old-dashboard": "", + "tabs-description": "", + "unlink-library-panel": "", + "unmark-favorite": "" + }, + "validation": { + "invalid-dashboard-id": "", + "invalid-json": "", + "tags-expected-array": "", + "tags-expected-strings": "" + }, + "viz-panel": { + "options": { + "description": "", + "open-edit": "", + "plugin-type-image": "", + "title-option": "", + "transparent-background": "" + } + } + }, + "dashboard-import": { + "file-dropzone": { + "primary-text": "", + "secondary-text": "" + }, + "form-actions": { + "cancel": "", + "load": "" + }, + "gcom-field": { + "label": "", + "load-button": "", + "placeholder": "", + "validation-required": "" + }, + "json-field": { + "label": "", + "validation-required": "" + } + }, + "dashboard-links": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "title": "" + } + }, + "dashboard-settings": { + "annotations": { + "title": "" + }, + "dashboard-delete-button": "", + "delete-modal": { + "confirmation-text": "", + "delete-button": "", + "title": "" + }, + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "general": { + "auto-refresh-description": "", + "auto-refresh-label": "", + "description-label": "", + "editable-description": "", + "editable-label": "", + "folder-label": "", + "panel-options-graph-tooltip-description": "", + "panel-options-graph-tooltip-label": "", + "panel-options-label": "", + "panels-preload-description": "", + "panels-preload-label": "", + "tags-label": "", + "title": "", + "title-label": "" + }, + "json-editor": { + "save-button": "", + "subtitle": "", + "title": "" + }, + "links": { + "title": "" + }, + "permissions": { + "title": "" + }, + "provisioned-delete-modal": { + "confirm-button": "", + "text-1": "", + "text-2": "", + "text-3": "", + "text-link": "", + "title": "" + }, + "settings": { + "title": "" + }, + "time-picker": { + "hide-time-picker": "", + "now-delay-description": "", + "now-delay-label": "", + "refresh-live-dashboards-description": "", + "refresh-live-dashboards-label": "", + "time-options-label": "", + "time-zone-label": "", + "week-start-label": "" + }, + "time-regions": { + "advanced-description-cron": "", + "advanced-description-rest": "", + "advanced-description-use": "", + "advanced-label": "" + }, + "variables": { + "title": "" + }, + "versions": { + "title": "" + } + }, + "dashboards": { + "panel-edit": { + "angular-deprecation-button-open-panel-json": "", + "angular-deprecation-description": "", + "angular-deprecation-heading": "" + }, + "panel-queries": { + "add-query-from-library": "" + }, + "settings": { + "variables": { + "dependencies": { + "button": "", + "title": "" + } + } + } + }, + "data-source-list": { + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + } + }, + "data-source-picker": { + "add-new-data-source": "", + "built-in-list": { + "description-dashboard": "", + "description-grafana": "", + "description-mixed": "" + }, + "list": { + "no-data-source-message": "" + }, + "modal": { + "configure-new-data-source": "", + "input-placeholder": "", + "title": "" + }, + "open-advanced-button": "" + }, + "data-source-testing-status-page": { + "error-more-details-link": "", + "success-more-details-links": "" + }, + "data-sources": { + "datasource-add-button": { + "label": "" + }, + "empty-state": { + "message": "" + } + }, + "embed": { + "share": { + "time-range-description": "", + "time-range-label": "" + } + }, + "empty-list-cta": { + "pro-tip": "" + }, + "entity-not-found": { + "description": "" + }, + "errors": { + "dashboard-settings": { + "annotations": { + "datasource": "" + } + } + }, + "explore": { + "add-to-dashboard": "", + "drilldownInfo": { + "action": "", + "description": "", + "title": "" + }, + "logs": { + "logs-volume": { + "add-filters": "", + "decrease-timerange": "", + "much-data": "" + }, + "maximum-pinned-logs": "", + "no-logs-found": "", + "scan-for-older-logs": "", + "stop-scan": "" + }, + "rich-history": { + "close-tooltip": "", + "datasource-a-z": "", + "datasource-z-a": "", + "newest-first": "", + "oldest-first": "", + "query-history": "", + "query-library": "", + "settings": "", + "starred": "" + }, + "rich-history-card": { + "add-comment-form": "", + "add-comment-tooltip": "", + "add-to-library": "", + "cancel": "", + "confirm-delete": "", + "copy-query-tooltip": "", + "copy-shortened-link-tooltip": "", + "datasource-icon-label": "", + "datasource-name-label": "", + "datasource-not-exist": "", + "delete-query-confirmation-title": "", + "delete-query-title": "", + "delete-query-tooltip": "", + "delete-starred-query-confirmation-text": "", + "edit-comment-tooltip": "", + "optional-description": "", + "query-comment-label": "", + "query-text-label": "", + "save-comment": "", + "star-query-tooltip": "", + "unstar-query-tooltip": "", + "update-comment-form": "" + }, + "rich-history-container": { + "loading": "" + }, + "rich-history-notification": { + "query-copied": "", + "query-deleted": "" + }, + "rich-history-queries-tab": { + "displaying-partial-queries": "", + "displaying-queries": "", + "filter-aria-label": "", + "filter-history": "", + "filter-placeholder": "", + "history-local": "", + "loading": "", + "loading-results": "", + "search-placeholder": "", + "showing-queries": "", + "sort-aria-label": "", + "sort-placeholder": "" + }, + "rich-history-settings-tab": { + "alert-info": "", + "change-default-tab": "", + "clear-history-info": "", + "clear-query-history": "", + "clear-query-history-button": "", + "delete-confirm": "", + "delete-confirm-text": "", + "delete-title": "", + "history-time-span": "", + "history-time-span-description": "", + "only-show-active-datasource": "", + "query-history-deleted": "", + "retention-period": { + "1-week": "", + "2-days": "", + "2-weeks": "", + "5-days": "" + } + }, + "rich-history-starred-tab": { + "filter-queries-aria-label": "", + "filter-queries-placeholder": "", + "loading": "", + "loading-results": "", + "local-history-message": "", + "search-queries-placeholder": "", + "showing-queries": "", + "sort-queries-aria-label": "", + "sort-queries-placeholder": "" + }, + "rich-history-utils": { + "a-week-ago": "", + "days-ago": "", + "default-from": "", + "default-to": "", + "today": "", + "two-weeks-ago": "", + "yesterday": "" + }, + "rich-history-utils-notification": { + "saving-failed": "", + "update-failed": "" + }, + "run-query": { + "left-pane": "", + "right-pane": "", + "run-query-button": "", + "switch-datasource-button": "" + }, + "secondary-actions": { + "add-from-query-library": "", + "query-add-button": "", + "query-add-button-aria-label": "", + "query-history-button": "", + "query-history-button-aria-label": "", + "query-inspector-button": "", + "query-inspector-button-aria-label": "" + }, + "table": { + "no-data": "", + "title": "", + "title-with-name": "" + }, + "toolbar": { + "add-to-extensions": "", + "add-to-queryless-extensions": "", + "aria-label": "", + "copy-link": "", + "copy-link-abs-time": "", + "copy-links-absolute-category": "", + "copy-links-normal-category": "", + "copy-shortened-link": "", + "copy-shortened-link-abs-time": "", + "copy-shortened-link-label": "", + "copy-shortened-link-menu": "", + "refresh-picker-cancel": "", + "refresh-picker-run": "", + "split-close": "", + "split-close-tooltip": "", + "split-narrow": "", + "split-title": "", + "split-tooltip": "", + "split-widen": "" + } + }, + "explore-metrics": { + "breakdown": { + "clearFilter": "", + "labelSelect": "", + "missing-otel-labels": "", + "noMatchingValue": "", + "sortBy": "" + }, + "related-logs": { + "LrrDocsLink": "", + "openExploreLogs": "", + "relatedLogsUnavailable": "", + "warnExperimentalFeature": "" + }, + "viewBy": "" + }, + "export": { + "json": { + "cancel-button": "", + "copy-button": "", + "download-button": "", + "download-successful_toast_message": "", + "export-externally-label": "", + "info-text": "", + "title": "" + }, + "menu": { + "export-as-json-label": "", + "export-as-json-tooltip": "" + } + }, + "folder-filter": { + "clear-folder-button": "" + }, + "folder-picker": { + "create-instructions": "", + "loading": "" + }, + "forgot-password": { + "back-button": "", + "change-password": { + "skip-button": "", + "submit-button": "" + }, + "contact-admin": "", + "email-sent": "", + "reset-password-header": "", + "send-email-button": "" + }, + "form-prompt": { + "continue-button": "", + "description": "", + "discard-button": "" + }, + "gen-ai": { + "apply-suggestion": "", + "incomplete-request-error": "", + "send-custom-feedback": "" + }, + "get-enterprise": { + "requires-license": "", + "title": "" + }, + "grafana-ui": { + "action-editor": { + "button": { + "confirm": "", + "confirm-action": "" + }, + "inline": { + "add-action": "", + "edit-action": "" + }, + "modal": { + "action-body": "", + "action-method": "", + "action-query-params": "", + "action-title": "", + "action-title-placeholder": "", + "one-click-description": "" + } + }, + "alert": { + "close-button": "" + }, + "auto-save-field": { + "saved": "", + "saving": "" + }, + "card": { + "option": "" + }, + "cascader": { + "clear-button": "" + }, + "color-picker-popover": { + "palette-tab": "", + "spectrum-tab": "" + }, + "confirm-button": { + "cancel": "" + }, + "confirm-content": { + "placeholder": "" + }, + "data-link-editor": { + "info": "", + "new-tab-label": "", + "title-label": "", + "title-placeholder": "", + "url-label": "" + }, + "data-link-editor-modal": { + "cancel": "", + "one-click-description": "", + "save": "" + }, + "data-link-inline-editor": { + "one-click": "" + }, + "data-links-inline-editor": { + "add-link": "", + "edit-link": "", + "one-click": "", + "one-click-enabled": "", + "title-not-provided": "", + "tooltip-edit": "", + "tooltip-remove": "", + "url-not-provided": "" + }, + "data-source-basic-auth-settings": { + "user-label": "", + "user-placeholder": "" + }, + "data-source-http-proxy-settings": { + "oauth-identity-label": "", + "oauth-identity-tooltip": "", + "skip-tls-verify-label": "", + "ts-client-auth-label": "", + "with-ca-cert-label": "", + "with-ca-cert-tooltip": "" + }, + "data-source-http-settings": { + "access-help": "", + "access-help-details": "", + "access-label": "", + "access-options-browser": "", + "access-options-proxy": "", + "allowed-cookies": "", + "allowed-cookies-tooltip": "", + "auth": "", + "azure-auth-label": "", + "azure-auth-tooltip": "", + "basic-auth": "", + "basic-auth-label": "", + "browser-mode-description": "", + "browser-mode-title": "", + "default-url-access-select": "", + "default-url-tooltip": "", + "direct-url-tooltip": "", + "heading": "", + "proxy-url-tooltip": "", + "server-mode-description": "", + "server-mode-title": "", + "timeout-form-label": "", + "timeout-label": "", + "timeout-tooltip": "", + "url-label": "", + "with-credential-label": "", + "with-credential-tooltip": "" + }, + "data-source-settings": { + "alerting-settings-heading": "", + "alerting-settings-label": "", + "alerting-settings-tooltip": "", + "cert-key-reset": "", + "custom-headers-add": "", + "custom-headers-header": "", + "custom-headers-header-placeholder": "", + "custom-headers-header-remove": "", + "custom-headers-header-value": "", + "custom-headers-title": "", + "secure-socks-heading": "", + "secure-socks-label": "", + "secure-socks-tooltip": "", + "tls-certification-label": "", + "tls-certification-placeholder": "", + "tls-client-certification-label": "", + "tls-client-key-label": "", + "tls-client-key-placeholder": "", + "tls-heading": "", + "tls-server-name-label": "", + "tls-tooltip": "" + }, + "date-time-picker": { + "apply": "", + "calendar-icon-label": "", + "cancel": "", + "next-label": "", + "previous-label": "", + "select-placeholder": "" + }, + "drawer": { + "close": "" + }, + "feature-badge": { + "experimental": "", + "new": "", + "preview": "", + "private-preview": "" + }, + "field-link-list": { + "external-links-heading": "" + }, + "file-dropzone": { + "cancel-upload": "", + "file-too-large": "" + }, + "filter-input": { + "clear": "" + }, + "modal": { + "close-tooltip": "" + }, + "named-colors-palette": { + "text-color-swatch": "", + "transparent-swatch": "" + }, + "page-toolbar": { + "go-back": "", + "search-dashboard-name": "", + "search-links": "", + "search-parent-folder": "" + }, + "pagination": { + "next-page": "", + "previous-page": "" + }, + "secret-form-field": { + "reset": "" + }, + "segment-async": { + "error": "", + "loading": "", + "no-options": "" + }, + "select": { + "default-create-label": "", + "no-options-label": "", + "placeholder": "" + }, + "series-color-picker-popover": { + "y-axis-usage": "" + }, + "spinner": { + "aria-label": "" + }, + "table": { + "copy": "", + "csv-counts": "", + "filter-popup-apply": "", + "filter-popup-cancel": "", + "filter-popup-clear": "", + "filter-popup-heading": "", + "no-values-label": "", + "pagination-summary": "" + }, + "tags-input": { + "add": "" + }, + "user-icon": { + "active-text": "" + }, + "value-pill": { + "remove-button": "" + }, + "viz-legend": { + "right-axis-indicator": "" + }, + "viz-tooltip": { + "actions-confirmation-input-placeholder": "", + "actions-confirmation-label": "", + "actions-confirmation-message": "", + "footer-add-annotation": "", + "footer-click-to-action": "", + "footer-click-to-navigate": "" + } + }, + "graph": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "", + "title": "" + } + }, + "help-modal": { + "column-headers": { + "description": "", + "keys": "" + }, + "shortcuts-category": { + "dashboard": "", + "focused-panel": "", + "global": "", + "time-range": "" + }, + "shortcuts-description": { + "change-theme": "", + "collapse-all-rows": "", + "copy-time-range": "", + "dashboard-settings": "", + "duplicate-panel": "", + "exit-edit/setting-views": "", + "expand-all-rows": "", + "go-to-dashboards": "", + "go-to-explore": "", + "go-to-home-dashboard": "", + "go-to-profile": "", + "make-time-range-permanent": "", + "move-time-range-back": "", + "move-time-range-forward": "", + "open-search": "", + "open-shared-modal": "", + "paste-time-range": "", + "refresh-all-panels": "", + "remove-panel": "", + "save-dashboard": "", + "show-all-shortcuts": "", + "toggle-active-mode": "", + "toggle-all-panel-legends": "", + "toggle-auto-fit": "", + "toggle-exemplars": "", + "toggle-graph-crosshair": "", + "toggle-kiosk": "", + "toggle-panel-edit": "", + "toggle-panel-fullscreen": "", + "toggle-panel-legend": "", + "zoom-out-time-range": "" + }, + "title": "" + }, + "help-wizard": { + "download-snapshot": "", + "github-comment": "", + "support-bundle": "", + "troubleshooting-help": "" + }, + "inspector": { + "query": { + "collapse-all": "", + "copy-to-clipboard": "", + "description": "", + "expand-all": "", + "no-data": "", + "refresh": "" + } + }, + "ldap-drawer": { + "attributes-section": { + "description": "", + "email-label": "", + "label": "", + "member-of-label": "", + "name-label": "", + "surname-label": "", + "username-label": "" + }, + "extra-security-section": { + "client-cert-label": "", + "client-cert-placeholder": "", + "client-cert-value-label": "", + "client-cert-value-placeholder": "", + "client-key-label": "", + "client-key-placeholder": "", + "client-key-value-label": "", + "client-key-value-placeholder": "", + "encryption-provider-base-64": "", + "encryption-provider-description": "", + "encryption-provider-file-path": "", + "encryption-provider-label": "", + "label": "", + "min-tls-version-description": "", + "min-tls-version-label": "", + "root-ca-cert-label": "", + "root-ca-cert-placeholder": "", + "root-ca-cert-value-label": "", + "root-ca-cert-value-placeholder": "", + "start-tls-description": "", + "start-tls-label": "", + "tls-ciphers-label": "", + "tls-ciphers-placeholder": "", + "use-ssl-description": "", + "use-ssl-label": "", + "use-ssl-tooltip": "" + }, + "group-mapping": { + "grafana-admin": { + "description": "", + "label": "" + }, + "group-dn": { + "description": "", + "label": "" + }, + "org-id": { + "description": "", + "label": "" + }, + "org-role": { + "label": "" + }, + "remove": { + "button": "" + } + }, + "group-mapping-section": { + "add": { + "button": "" + }, + "description": "", + "group-search-base-dns-label": "", + "group-search-base-dns-placeholder": "", + "group-search-filter-description": "", + "group-search-filter-label": "", + "group-search-filter-user-attribute-description": "", + "group-search-filter-user-attribute-label": "", + "label": "", + "skip-org-role-sync-description": "", + "skip-org-role-sync-label": "" + }, + "misc-section": { + "allow-sign-up-descrition": "", + "allow-sign-up-label": "", + "label": "", + "port-description": "", + "port-label": "", + "timeout-description": "", + "timeout-label": "" + }, + "title": "" + }, + "ldap-settings-page": { + "advanced-settings-section": { + "edit-button": "", + "subtitle": "", + "title": "" + }, + "alert": { + "discard-success": "", + "error-fetching": "", + "error-saving": "", + "error-validate-form": "", + "feature-flag-disabled": "", + "saved": "" + }, + "bind-dn": { + "description": "", + "label": "", + "placeholder": "" + }, + "bind-password": { + "label": "" + }, + "buttons-section": { + "disable-button": "", + "discard-button": "", + "save-and-enable-button": "", + "save-button": "" + }, + "documentation": "", + "host": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "login-form-alert": { + "description": "", + "title": "" + }, + "search_filter": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "search-base-dns": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "subtitle": "", + "title": "" + }, + "library-panel": { + "add-modal": { + "cancel": "", + "create": "", + "error": "", + "folder": "", + "folder-description": "", + "name": "" + }, + "add-widget": { + "title": "" + }, + "empty-state": { + "message": "", + "more-info": "" + } + }, + "library-panels": { + "empty-state": { + "message": "" + }, + "loading-panel-text": "", + "modal": { + "button-cancel": "", + "button-view-panel1": "", + "button-view-panel2": "", + "panel-not-linked": "", + "select-no-options-message": "", + "select-placeholder": "", + "title": "", + "body_one": "", + "body_few": "", + "body_many": "", + "body_other": "" + }, + "save": { + "error": "", + "success": "" + } + }, + "link": { + "share": { + "config-alert-description": "", + "config-alert-title": "", + "config-description": "", + "copy-link-button": "", + "copy-to-clipboard": "", + "short-url-label": "", + "time-range-description": "", + "time-range-label": "" + }, + "share-panel": { + "config-description": "", + "download-image": "", + "render-image": "", + "render-image-error": "", + "render-image-error-description": "" + } + }, + "lock-icon": "", + "login": { + "divider": { + "connecting-text": "" + }, + "error": { + "blocked": "", + "invalid-user-or-password": "", + "title": "", + "unknown": "" + }, + "forgot-password": "", + "form": { + "confirmation-code": "", + "confirmation-code-label": "", + "confirmation-code-placeholder": "", + "email-label": "", + "email-placeholder": "", + "email-required": "", + "name-label": "", + "name-placeholder": "", + "password-label": "", + "password-placeholder": "", + "password-required": "", + "submit-label": "", + "submit-loading-label": "", + "username-label": "", + "username-placeholder": "", + "username-required": "", + "verify-email-label": "", + "verify-email-loading-label": "" + }, + "layout": { + "update-password": "" + }, + "services": { + "sing-in-with-prefix": "" + }, + "signup": { + "button-label": "", + "new-to-question": "" + } + }, + "logs": { + "infinite-scroll": { + "end-of-range": "", + "load-more": "", + "load-newer": "", + "load-older": "", + "older-logs": "" + }, + "log-details": { + "fields": "", + "links": "", + "log-line": "", + "no-details": "" + }, + "log-line-menu": { + "copy-link": "", + "copy-log": "", + "icon-label": "", + "pin-to-outline": "", + "show-context": "", + "unpin-from-outline": "" + }, + "log-row-message": { + "ellipsis": "", + "more": "", + "see-details": "" + }, + "log-rows": { + "disable-popover": { + "confirm": "", + "message": "", + "title": "" + }, + "disable-popover-message": { + "shortcut": "" + } + }, + "logs-navigation": { + "newer-logs": "", + "older-logs": "", + "scroll-bottom": "", + "scroll-top": "", + "start-of-range": "" + }, + "popover-menu": { + "copy": "", + "disable-menu": "", + "line-contains": "", + "line-contains-not": "" + } + }, + "migrate-to-cloud": { + "build-snapshot": { + "description": "", + "title": "", + "when-complete": "" + }, + "building-snapshot": { + "description": "", + "description-eta": "", + "title": "" + }, + "can-i-move": { + "body": "", + "link-title": "", + "title": "" + }, + "connect-modal": { + "body-cloud-stack": "", + "body-get-started": "", + "body-sign-up": "", + "body-token": "", + "body-token-field": "", + "body-token-field-placeholder": "", + "body-token-instructions": "", + "body-view-stacks": "", + "cancel": "", + "connect": "", + "connecting": "", + "title": "", + "token-error-title": "", + "token-errors": { + "instance-request-error": "", + "instance-unreachable": "", + "migration-disabled": "", + "session-creation-failure": "", + "token-invalid": "", + "token-not-saved": "", + "token-request-error": "", + "token-validation-failure": "" + }, + "token-required-error": "" + }, + "cta": { + "button": "", + "header": "" + }, + "delete-migration-token-confirm": { + "body": "", + "confirm-button": "", + "error-title": "", + "title": "" + }, + "disconnect-modal": { + "body": "", + "cancel": "", + "disconnect": "", + "disconnecting": "", + "error": "", + "title": "" + }, + "get-started": { + "body": "", + "configure-pdc-link": "", + "link-title": "", + "step-1": "", + "step-2": "", + "step-3": "", + "step-4": "", + "step-5": "", + "title": "" + }, + "is-it-secure": { + "body": "", + "link-title": "", + "title": "" + }, + "migrate-to-this-stack": { + "body": "", + "link-title": "", + "title": "" + }, + "migrated-counts": { + "alert_rule_groups": "", + "alert_rules": "", + "contact_points": "", + "dashboards": "", + "datasources": "", + "folders": "", + "library_elements": "", + "mute_timings": "", + "notification_policies": "", + "notification_templates": "", + "plugins": "" + }, + "migration-token": { + "delete-button": "", + "delete-modal-body": "", + "delete-modal-cancel": "", + "delete-modal-confirm": "", + "delete-modal-deleting": "", + "delete-modal-title": "", + "error-body": "", + "error-title": "", + "generate-button": "", + "generate-button-loading": "", + "modal-close": "", + "modal-copy-and-close": "", + "modal-copy-button": "", + "modal-field-description": "", + "modal-field-label": "", + "modal-title": "", + "status": "" + }, + "onprem": { + "cancel-snapshot-error-title": "", + "create-snapshot-error-title": "", + "disconnect-error-title": "", + "error-see-server-logs": "", + "get-session-error-title": "", + "get-snapshot-error-title": "", + "migration-finished-with-caveat-title": "", + "migration-finished-with-errors-body": "", + "migration-finished-with-warnings-body": "", + "snapshot-error-status-body": "", + "snapshot-error-status-title": "", + "success-message": "", + "success-message-generic": "", + "success-title": "", + "upload-snapshot-error-title": "" + }, + "pdc": { + "body": "", + "link-title": "", + "title": "" + }, + "pricing": { + "body": "", + "link-title": "", + "title": "" + }, + "public-preview": { + "button-text": "", + "message": "", + "message-cloud": "", + "title": "" + }, + "resource-details": { + "dismiss-button": "", + "error-messages": { + "dashboard-already-managed": "", + "datasource-already-managed": "", + "datasource-invalid-url": "", + "datasource-name-conflict": "", + "folder-name-conflict": "", + "generic-error": "", + "internal-service-error": "", + "library-element-name-conflict": "", + "resource-conflict": "", + "unexpected-error": "", + "unsupported-data-type": "" + }, + "error-title": "", + "generic-title": "", + "missing-message": "", + "resource-summary": "", + "title": "", + "warning-title": "" + }, + "resource-status": { + "error-details-button": "", + "failed": "", + "migrated": "", + "migrating": "", + "not-migrated": "", + "unknown": "", + "warning": "", + "warning-details-button": "" + }, + "resource-table": { + "dashboard-load-error": "", + "error-library-element-sub": "", + "error-library-element-title": "", + "unknown-datasource-title": "", + "unknown-datasource-type": "" + }, + "resource-type": { + "alert_rule": "", + "alert_rule_group": "", + "contact_point": "", + "dashboard": "", + "datasource": "", + "folder": "", + "library_element": "", + "mute_timing": "", + "notification_policy": "", + "notification_template": "", + "plugin": "", + "unknown": "" + }, + "summary": { + "cancel-snapshot": "", + "disconnect": "", + "errored-resource-count": "", + "page-loading": "", + "rebuild-snapshot": "", + "snapshot-date": "", + "snapshot-not-created": "", + "start-migration": "", + "successful-resource-count": "", + "target-stack-title": "", + "total-resource-count": "", + "upload-migration": "" + }, + "support-types-disclosure": { + "text": "" + }, + "token-status": { + "active": "", + "no-active": "", + "unknown": "", + "unknown-error": "" + }, + "what-is-cloud": { + "body": "", + "link-title": "", + "title": "" + }, + "why-host": { + "body": "", + "link-title": "", + "title": "" + } + }, + "multicombobox": { + "all": { + "title": "", + "title-filtered": "" + }, + "clear": { + "title": "" + } + }, + "nav": { + "add-new-connections": { + "title": "" + }, + "admin": { + "subtitle": "", + "title": "" + }, + "alert-list-legacy": { + "title": "" + }, + "alerting": { + "subtitle": "", + "title": "" + }, + "alerting-admin": { + "subtitle": "", + "title": "" + }, + "alerting-am-routes": { + "subtitle": "", + "title": "" + }, + "alerting-channels": { + "title": "" + }, + "alerting-groups": { + "subtitle": "", + "title": "" + }, + "alerting-home": { + "title": "" + }, + "alerting-legacy": { + "title": "" + }, + "alerting-list": { + "subtitle": "", + "title": "" + }, + "alerting-receivers": { + "subtitle": "", + "title": "" + }, + "alerting-silences": { + "subtitle": "", + "title": "" + }, + "alerting-upgrade": { + "subtitle": "", + "title": "" + }, + "alerts-and-incidents": { + "subtitle": "", + "title": "" + }, + "api-keys": { + "subtitle": "", + "title": "" + }, + "application": { + "title": "" + }, + "apps": { + "subtitle": "", + "title": "" + }, + "authentication": { + "title": "" + }, + "bookmarks": { + "title": "" + }, + "bookmarks-empty": { + "title": "" + }, + "collector": { + "title": "" + }, + "config": { + "title": "" + }, + "config-access": { + "subtitle": "", + "title": "" + }, + "config-general": { + "subtitle": "", + "title": "" + }, + "config-plugins": { + "subtitle": "", + "title": "" + }, + "connect-data": { + "title": "" + }, + "connections": { + "subtitle": "", + "title": "" + }, + "correlations": { + "subtitle": "", + "title": "" + }, + "create": { + "title": "" + }, + "create-alert": { + "title": "" + }, + "create-dashboard": { + "title": "" + }, + "create-folder": { + "title": "" + }, + "create-import": { + "title": "" + }, + "dashboards": { + "subtitle": "", + "title": "" + }, + "data-sources": { + "subtitle": "", + "title": "" + }, + "databases": { + "title": "" + }, + "datasources": { + "subtitle": "", + "title": "" + }, + "detect": { + "title": "" + }, + "drilldown": { + "title": "" + }, + "explore": { + "title": "" + }, + "frontend": { + "subtitle": "", + "title": "" + }, + "frontend-app": { + "title": "" + }, + "global-orgs": { + "subtitle": "", + "title": "" + }, + "global-users": { + "subtitle": "", + "title": "" + }, + "grafana-quaderno": { + "title": "" + }, + "groupsync": { + "subtitle": "" + }, + "help": { + "title": "" + }, + "help/community": "", + "help/documentation": "", + "help/keyboard-shortcuts": "", + "help/support": "", + "history-container": { + "drawer-tittle": "" + }, + "history-wrapper": { + "collapse": "", + "expand": "", + "icon-selected": "", + "icon-unselected": "", + "show-more": "", + "today": "", + "yesterday": "" + }, + "home": { + "title": "" + }, + "incidents": { + "title": "" + }, + "infrastructure": { + "subtitle": "", + "title": "" + }, + "integrations": { + "title": "" + }, + "k6": { + "title": "" + }, + "kubernetes": { + "title": "" + }, + "library-panels": { + "subtitle": "", + "title": "" + }, + "machine-learning": { + "title": "" + }, + "manage-folder": { + "subtitle": "" + }, + "migrate-to-cloud": { + "subtitle": "", + "title": "" + }, + "monitoring": { + "subtitle": "", + "title": "" + }, + "new": { + "title": "" + }, + "new-dashboard": { + "title": "" + }, + "new-folder": { + "title": "" + }, + "oncall": { + "title": "" + }, + "org-settings": { + "subtitle": "", + "title": "" + }, + "playlists": { + "subtitle": "", + "title": "" + }, + "plugins": { + "subtitle": "", + "title": "" + }, + "private-data-source-connections": { + "subtitle": "", + "title": "" + }, + "profile/notifications": { + "title": "" + }, + "profile/password": { + "title": "" + }, + "profile/settings": { + "title": "" + }, + "profiles": { + "title": "" + }, + "public": { + "title": "" + }, + "recently-deleted": { + "subtitle": "", + "title": "" + }, + "recorded-queries": { + "title": "" + }, + "reporting": { + "title": "" + }, + "scenes": { + "title": "" + }, + "search": { + "placeholderCommandPalette": "" + }, + "search-dashboards": { + "title": "" + }, + "server-settings": { + "subtitle": "", + "title": "" + }, + "service-accounts": { + "subtitle": "", + "title": "" + }, + "setup-guide": { + "title": "" + }, + "shared-dashboard": { + "subtitle": "", + "title": "" + }, + "sign-out": { + "title": "" + }, + "slo": { + "title": "" + }, + "snapshots": { + "subtitle": "", + "title": "" + }, + "starred": { + "title": "" + }, + "starred-empty": { + "title": "" + }, + "statistics-and-licensing": { + "title": "" + }, + "storage": { + "subtitle": "", + "title": "" + }, + "support-bundles": { + "subtitle": "", + "title": "" + }, + "synthetics": { + "title": "" + }, + "teams": { + "subtitle": "", + "title": "" + }, + "testing-and-synthetics": { + "subtitle": "", + "title": "" + }, + "upgrading": { + "title": "" + }, + "users": { + "subtitle": "", + "title": "" + } + }, + "navigation": { + "invite-user": { + "invite-button": "", + "invite-tooltip": "" + }, + "item": { + "add-bookmark": "", + "remove-bookmark": "" + }, + "kiosk": { + "tv-alert": "" + }, + "megamenu": { + "close": "", + "dock": "", + "list-label": "", + "open": "", + "undock": "" + }, + "rss-button": "" + }, + "news": { + "drawer": { + "close": "" + }, + "title": "" + }, + "notifications": { + "empty-state": { + "description": "", + "title": "" + }, + "starred-dashboard": "", + "unstarred-dashboard": "" + }, + "oauth": { + "form": { + "server-discovery-action-button": "", + "server-discovery-modal-close": "", + "server-discovery-modal-loading": "", + "server-discovery-modal-submit": "" + }, + "login": { + "error": "" + } + }, + "panel": { + "header-menu": { + "copy": "", + "create-library-panel": "", + "duplicate": "", + "edit": "", + "explore": "", + "get-help": "", + "hide-legend": "", + "inspect": "", + "inspect-data": "", + "inspect-json": "", + "more": "", + "new-alert-rule": "", + "query": "", + "remove": "", + "replace-library-panel": "", + "share": "", + "show-legend": "", + "unlink-library-panel": "", + "view": "" + } + }, + "panel-search": { + "no-matches": "", + "unsupported-layout": "" + }, + "panel-type-filter": { + "clear-button": "" + }, + "playlist-edit": { + "error-prefix": "", + "form": { + "add-tag-label": "", + "add-tag-placeholder": "", + "add-title-label": "", + "cancel": "", + "heading": "", + "interval-label": "", + "interval-placeholder": "", + "interval-required": "", + "name-label": "", + "name-placeholder": "", + "name-required": "", + "save": "", + "table-delete": "", + "table-drag": "", + "table-empty": "", + "table-heading": "" + }, + "sub-title": "", + "title": "" + }, + "playlist-page": { + "card": { + "delete": "", + "edit": "", + "start": "", + "tooltip": "" + }, + "create-button": { + "title": "" + }, + "delete-modal": { + "body": "", + "confirm-text": "" + }, + "empty": { + "button": "", + "pro-tip": "", + "title": "" + } + }, + "playlists": { + "empty-state": { + "message": "" + } + }, + "plugins": { + "catalog": { + "no-updates-available": "", + "update-all": { + "all-plugins-updated": "", + "available-header": "", + "button": "", + "cloud-update-message": "", + "error": "", + "error-status-text": "", + "header": "", + "installed-header": "", + "modal-confirmation": "", + "modal-dismiss": "", + "modal-in-progress": "", + "modal-title": "", + "name-header": "", + "update-header": "", + "update-status-text": "" + }, + "versions": { + "confirmation-text-1": "", + "confirmation-text-2": "", + "downgrade-confirm": "", + "downgrade-title": "" + } + }, + "details": { + "connections-tab": { + "description": "" + }, + "labels": { + "contactGrafanaLabs": "", + "customLinks": "", + "customLinksTooltip": "", + "dependencies": "", + "documentation": "", + "downloads": "", + "from": "", + "installedVersion": "", + "lastCommitDate": "", + "latestVersion": "", + "license": "", + "raiseAnIssue": "", + "reportAbuse": "", + "reportAbuseTooltip": "", + "repository": "", + "signature": "", + "status": "", + "updatedAt": "" + }, + "modal": { + "cancel": "", + "copyEmail": "", + "description": "", + "node": "", + "title": "" + } + }, + "empty-state": { + "message": "" + }, + "filter": { + "disabled": "", + "sort": "", + "sort-list": "", + "state": "" + }, + "plugin-help": { + "error": "", + "not-found": "" + } + }, + "profile": { + "change-password": { + "cancel-button": "", + "cannot-change-password-message": "", + "change-password-button": "", + "confirm-password-label": "", + "confirm-password-required": "", + "ldap-auth-proxy-message": "", + "new-password-label": "", + "new-password-required": "", + "new-password-same-as-old": "", + "old-password-label": "", + "old-password-required": "", + "passwords-must-match": "", + "strong-password-validation-register": "" + } + }, + "public-dashboard": { + "acknowledgment-checkboxes": { + "ack-title": "", + "data-src-ack-desc": "", + "data-src-ack-tooltip": "", + "public-ack-desc": "", + "public-ack-tooltip": "", + "usage-ack-desc": "", + "usage-ack-desc-tooltip": "" + }, + "config": { + "can-view-dashboard-radio-button-label": "", + "copy-button": "", + "dashboard-url-field-label": "", + "email-share-type-option-label": "", + "pause-sharing-dashboard-label": "", + "public-share-type-option-label": "", + "revoke-public-URL-button": "", + "revoke-public-URL-button-title": "", + "settings-title": "" + }, + "configuration": { + "display-annotations-description": "", + "display-annotations-label": "", + "enable-time-range-description": "", + "enable-time-range-label": "", + "settings-label": "", + "success-pause": "", + "success-resume": "", + "success-update": "", + "success-update-old": "", + "time-range-label": "", + "time-range-tooltip": "" + }, + "create-page": { + "generate-public-url-button": "", + "unsupported-features-desc": "", + "welcome-title": "" + }, + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "email-sharing": { + "accept-button": "", + "alert-text": "", + "bill-ack": "", + "cancel-button": "", + "input-invalid-email-text": "", + "input-required-email-text": "", + "invite-button": "", + "invite-field-desc": "", + "invite-field-label": "", + "learn-more-button": "", + "recipient-email-placeholder": "", + "recipient-invalid-email-text": "", + "recipient-invitation-button": "", + "recipient-invitation-description": "", + "recipient-invitation-tooltip": "", + "recipient-list-description": "", + "recipient-list-title": "", + "recipient-required-email-text": "", + "resend-button": "", + "resend-button-title": "", + "resend-invite-label": "", + "revoke-access-label": "", + "revoke-button": "", + "revoke-button-title": "", + "success-creation": "", + "success-share-type-change": "" + }, + "modal-alerts": { + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "save-dashboard-changes-alert-title": "", + "unsupport-data-source-alert-readmore-link": "", + "unsupported-data-source-alert-desc": "", + "unsupported-data-source-alert-title": "", + "unsupported-template-variable-alert-desc": "", + "unsupported-template-variable-alert-title": "" + }, + "public-sharing": { + "accept-button": "", + "alert-text": "", + "cancel-button": "", + "learn-more-button": "", + "public-ack": "", + "success-creation": "", + "success-share-type-change": "" + }, + "settings-bar-header": { + "collapse-settings-tooltip": "", + "expand-settings-tooltip": "" + }, + "settings-configuration": { + "default-time-range-label": "", + "default-time-range-label-desc": "", + "show-annotations-label": "", + "show-annotations-label-desc": "", + "time-range-picker-label": "", + "time-range-picker-label-desc": "" + }, + "settings-summary": { + "annotations-hide-text": "", + "annotations-show-text": "", + "time-range-picker-disabled-text": "", + "time-range-picker-enabled-text": "", + "time-range-text": "" + }, + "share": { + "success-delete": "", + "success-delete-old": "" + }, + "share-configuration": { + "share-type-label": "" + }, + "share-externally": { + "copy-link-button": "", + "email-share-type-option-description": "", + "email-share-type-option-label": "", + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "pause-access-button": "", + "pause-access-tooltip": "", + "public-share-type-option-description": "", + "public-share-type-option-label": "", + "resume-access-button": "", + "revoke-access-button": "", + "revoke-access-description": "", + "unsupported-data-source-alert-desc": "" + }, + "sharing": { + "success-creation": "" + } + }, + "public-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "public-dashboard-users-access-list": { + "dashboard-modal": { + "external-link": "", + "loading-text": "", + "open-dashboard-list-text": "", + "public-dashboard-link": "", + "public-dashboard-setting": "", + "sharing-setting": "" + }, + "delete-user-modal": { + "delete-user-button-text": "", + "delete-user-cancel-button": "", + "delete-user-revoke-access-button": "", + "revoke-access-title": "", + "revoke-user-access-modal-desc-line1": "", + "revoke-user-access-modal-desc-line2": "" + }, + "delete-user-shared-dashboards-modal": { + "revoke-user-access-modal-desc-line2": "" + }, + "modal": { + "dashboard-modal-title": "", + "shared-dashboard-modal-title": "" + }, + "table-body": { + "dashboard-count_one": "", + "dashboard-count_few": "", + "dashboard-count_many": "", + "dashboard-count_other": "" + }, + "table-header": { + "activated-label": "", + "activated-tooltip": "", + "email-label": "", + "last-active-label": "", + "origin-label": "", + "role-label": "" + } + }, + "query-operation": { + "header": { + "collapse-row": "", + "datasource-help": "", + "drag-and-drop": "", + "duplicate-query": "", + "expand-row": "", + "hide-response": "", + "remove-query": "", + "show-response": "", + "toggle-edit-mode": "" + }, + "query-editor-not-exported": "" + }, + "recently-deleted": { + "buttons": { + "delete": "", + "restore": "" + }, + "page": { + "no-deleted-dashboards": "", + "no-deleted-dashboards-text": "", + "no-search-result": "" + }, + "permanently-delete-modal": { + "confirm-text": "", + "delete-button": "", + "delete-loading": "", + "title": "", + "text_one": "", + "text_few": "", + "text_many": "", + "text_other": "" + }, + "restore-modal": { + "restore-button": "", + "restore-loading": "", + "title": "", + "folder-picker-text_one": "", + "folder-picker-text_few": "", + "folder-picker-text_many": "", + "folder-picker-text_other": "", + "text_one": "", + "text_few": "", + "text_many": "", + "text_other": "" + } + }, + "recentlyDeleted": { + "filter": { + "placeholder": "" + } + }, + "reduce": { + "strictMode": { + "description": "", + "title": "" + } + }, + "refresh-picker": { + "aria-label": { + "choose-interval": "", + "duration-selected": "" + }, + "auto-option": { + "aria-label": "", + "label": "" + }, + "live-option": { + "aria-label": "", + "label": "" + }, + "off-option": { + "aria-label": "", + "label": "" + }, + "tooltip": { + "interval-selected": "", + "turned-off": "" + } + }, + "return-to-previous": { + "button": { + "label": "" + }, + "dismissable-button": "" + }, + "role-picker": { + "built-in": { + "basic-roles": "" + }, + "input": { + "no-roles": "" + }, + "menu": { + "clear-button": "", + "tooltip": "" + }, + "sub-menu": { + "clear-button": "" + }, + "title": { + "description": "" + } + }, + "role-picker-drawer": { + "basic-roles": { + "label": "" + } + }, + "route-error": { + "description": "", + "reload-button": "", + "title": "" + }, + "save-dashboards": { + "message-length": { + "info": "", + "title": "" + }, + "name-exists": { + "message-info": "", + "message-suggestion": "", + "title": "" + } + }, + "scopes": { + "dashboards": { + "collapse": "", + "expand": "", + "loading": "", + "noResultsForFilter": "", + "noResultsForFilterClear": "", + "noResultsForScopes": "", + "noResultsNoScopes": "", + "search": "", + "toggle": { + "collapse": "", + "disabled": "", + "expand": "" + } + }, + "selector": { + "apply": "", + "cancel": "", + "input": { + "placeholder": "", + "removeAll": "" + }, + "title": "" + }, + "tree": { + "collapse": "", + "expand": "", + "headline": { + "noResults": "", + "recommended": "", + "results": "" + }, + "search": "" + } + }, + "search": { + "actions": { + "include-panels": "", + "remove-datasource-filter": "", + "sort-placeholder": "", + "starred": "", + "view-as-folders": "", + "view-as-list": "" + }, + "dashboard-actions": { + "import": "", + "new": "", + "new-dashboard": "", + "new-folder": "" + }, + "results-table": { + "datasource-header": "", + "deleted-less-than-1-min": "", + "deleted-remaining-header": "", + "location-header": "", + "name-header": "", + "tags-header": "", + "type-dashboard": "", + "type-folder": "", + "type-header": "" + }, + "search-input": { + "include-panels-placeholder": "", + "placeholder": "" + } + }, + "select": { + "select-menu": { + "selected-count": "" + } + }, + "service-account-create-page": { + "create": { + "button": "" + }, + "name": { + "label": "", + "required-error": "" + }, + "page-nav": { + "label": "" + }, + "role": { + "label": "" + } + }, + "service-accounts": { + "empty-state": { + "button-title": "", + "message": "", + "more-info": "", + "title": "" + } + }, + "share-dashboard": { + "menu": { + "export-json-title": "", + "share-externally-title": "", + "share-internally-title": "", + "share-snapshot-title": "" + }, + "share-button": "", + "share-button-tooltip": "" + }, + "share-drawer": { + "confirm-action": { + "back-arrow-button": "", + "cancel-button": "" + } + }, + "share-modal": { + "dashboard": { + "title": "" + }, + "embed": { + "copy": "", + "html": "", + "html-description": "", + "info": "", + "time-range": "" + }, + "export": { + "back-button": "", + "cancel-button": "", + "info-text": "", + "loading": "", + "save-button": "", + "share-externally-label": "", + "view-button": "" + }, + "library": { + "info": "" + }, + "link": { + "copy-link-button": "", + "info-text": "", + "link-url": "", + "render-alert": "", + "render-instructions": "", + "rendered-image": "", + "save-alert": "", + "save-dashboard": "", + "shorten-url": "", + "time-range-description": "", + "time-range-label": "" + }, + "panel": { + "title": "" + }, + "snapshot": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "deleted-message": "", + "expire": "", + "expire-day": "", + "expire-hour": "", + "expire-never": "", + "expire-week": "", + "info-text-1": "", + "info-text-2": "", + "local-button": "", + "mistake-message": "", + "name": "", + "timeout": "", + "timeout-description": "", + "url-label": "" + }, + "tab-title": { + "embed": "", + "export": "", + "library-panel": "", + "link": "", + "panel-embed": "", + "public-dashboard": "", + "public-dashboard-title": "", + "snapshot": "" + }, + "theme-picker": { + "current": "", + "dark": "", + "field-name": "", + "light": "" + }, + "view-json": { + "copy-button": "" + } + }, + "share-panel": { + "drawer": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "" + }, + "menu": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "", + "share-snapshot-title": "" + }, + "new-library-panel": { + "cancel-button": "", + "create-button": "" + } + }, + "share-panel-image": { + "preview": { + "title": "" + }, + "settings": { + "height-label": "", + "height-min": "", + "height-placeholder": "", + "height-required": "", + "max-warning": "", + "scale-factor-label": "", + "scale-factor-min": "", + "scale-factor-placeholder": "", + "scale-factor-required": "", + "title": "", + "width-label": "", + "width-min": "", + "width-placeholder": "", + "width-required": "" + } + }, + "share-playlist": { + "checkbox-description": "", + "checkbox-label": "", + "copy-link-button": "", + "link-url-label": "", + "mode": "", + "mode-kiosk": "", + "mode-normal": "", + "title": "" + }, + "shared": { + "preferences": { + "theme": { + "dark-label": "", + "light-label": "", + "system-label": "" + } + } + }, + "shared-dashboard": { + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "fields": { + "timezone-label": "" + } + }, + "shared-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "shared-preferences": { + "fields": { + "home-dashboard-label": "", + "home-dashboard-placeholder": "", + "locale-label": "", + "locale-placeholder": "", + "theme-description": "", + "theme-label": "", + "week-start-label": "" + }, + "theme": { + "default-label": "" + }, + "title": "" + }, + "sign-up": { + "back-button": "", + "submit-button": "", + "verify": { + "back-button": "", + "complete-button": "", + "header": "", + "info": "", + "send-button": "" + } + }, + "silences": { + "empty-state": { + "button-title": "", + "title": "" + }, + "table": { + "add-silence-button": "", + "edit-button": "", + "expired-silences": "", + "no-matching-silences": "", + "noConfig": "", + "recreate-button": "", + "unsilence-button": "" + } + }, + "silences-table": { + "header": { + "alert-name": "", + "state": "" + } + }, + "snapshot": { + "empty-state": { + "message": "", + "more-info": "" + }, + "external-badge": "", + "name-column-header": "", + "share": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "delete-description": "", + "delete-permission-tooltip": "", + "delete-title": "", + "deleted-alert": "", + "expiration-label": "", + "info-alert": "", + "learn-more-button": "", + "local-button": "", + "name-label": "", + "new-snapshot-button": "", + "success-creation": "", + "success-delete": "", + "view-all-button": "" + }, + "share-panel": { + "info-alert": "" + }, + "url-column-header": "", + "view-button": "" + }, + "table": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "" + } + }, + "tag-filter": { + "clear-button": "", + "loading": "", + "no-tags": "", + "placeholder": "" + }, + "teams": { + "empty-state": { + "button-title": "", + "message": "", + "pro-tip": "", + "title": "" + } + }, + "theme-preview": { + "breadcrumbs": { + "dashboards": "", + "home": "" + }, + "panel": { + "form-label": "", + "title": "" + } + }, + "time-picker": { + "absolute": { + "recent-title": "", + "title": "" + }, + "calendar": { + "apply-button": "", + "cancel-button": "", + "close": "", + "next-month": "", + "previous-month": "", + "select-time": "" + }, + "content": { + "empty-recent-list-docs": "", + "empty-recent-list-info": "", + "filter-placeholder": "" + }, + "copy-paste": { + "copy-success-message": "", + "default-error-message": "", + "default-error-title": "", + "tooltip-copy": "", + "tooltip-paste": "" + }, + "footer": { + "change-settings-button": "", + "fiscal-year-option": "", + "fiscal-year-start": "", + "time-zone-option": "", + "time-zone-selection": "" + }, + "range-content": { + "apply-button": "", + "default-error": "", + "fiscal-year": "", + "from-input": "", + "open-input-calendar": "", + "range-error": "", + "to-input": "" + }, + "range-picker": { + "backwards-time-aria-label": "", + "current-time-selected": "", + "forwards-time-aria-label": "", + "to": "", + "zoom-out-button": "", + "zoom-out-tooltip": "" + }, + "time-range": { + "apply": "", + "aria-role": "", + "default-title": "", + "example": "", + "example-details": "", + "example-title": "", + "from-label": "", + "from-to": "", + "more-info": "", + "specify": "", + "submit-button-label": "", + "supported-formats": "", + "to-label": "" + }, + "zone": { + "select-aria-label": "", + "select-search-input": "" + } + }, + "trails": { + "bookmarks": { + "or-view-bookmarks": "" + }, + "card": { + "date-created": "" + }, + "home": { + "learn-more": "", + "lets-start": "", + "start-your-metrics-exploration": "", + "subtitle": "" + }, + "metric-select": { + "filter-by": "", + "native-histogram": "", + "new-badge": "", + "otel-switch": "" + }, + "native-histogram-banner": { + "ch-heatmap": "", + "ch-histogram": "", + "click-histogram": "", + "hide-examples": "", + "learn-more": "", + "metric-examples": "", + "nh-heatmap": "", + "nh-histogram": "", + "now": "", + "previously": "", + "see-examples": "", + "sentence": "" + }, + "recent-metrics": { + "or-view-a-recent-exploration": "" + }, + "settings": { + "always-keep-selected-metric-graph-in-view": "", + "show-previews-of-metric-graphs": "" + } + }, + "transformations": { + "empty": { + "add-transformation-body": "", + "add-transformation-header": "" + } + }, + "upgrade-box": { + "discovery-text": "", + "discovery-text-continued": "", + "get-started": "", + "learn-more": "", + "upgrade-button": "" + }, + "user-orgs": { + "current-org-button": "", + "name-column": "", + "role-column": "", + "select-org-button": "", + "title": "" + }, + "user-profile": { + "fields": { + "email-error": "", + "email-label": "", + "name-error": "", + "name-label": "", + "username-label": "" + }, + "tabs": { + "general": "" + } + }, + "user-session": { + "auth-module-column": "", + "browser-column": "", + "created-at-column": "", + "identity-provider-column": "", + "ip-column": "", + "revoke": "", + "seen-at-column": "" + }, + "user-sessions": { + "loading": "" + }, + "users": { + "empty-state": { + "message": "" + } + }, + "users-access-list": { + "tabs": { + "public-dashboard-users-tab-title": "", + "shared-dashboard-users-tab-title": "" + } + }, + "variable": { + "adhoc": { + "placeholder": "" + }, + "dropdown": { + "placeholder": "" + }, + "picker": { + "link-all": "", + "option-all": "", + "option-selected-values": "", + "option-tooltip": "" + }, + "textbox": { + "placeholder": "" + } + }, + "variables": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + }, + "unknown-table": { + "loading": "", + "no-unknowns": "", + "renamed-or-missing-variables": "", + "variable": "" + } + } +} \ No newline at end of file diff --git a/public/locales/de-DE/grafana.json b/public/locales/de-DE/grafana.json index f19fca1d4f4..f58adc0d513 100644 --- a/public/locales/de-DE/grafana.json +++ b/public/locales/de-DE/grafana.json @@ -184,7 +184,8 @@ "rule-identifier": "", "rule-type": "", "state-error-timeout": "", - "state-no-data": "" + "state-no-data": "", + "target-datasource-uid": "" }, "alert-recording-rule-form": { "evaluation-behaviour": { @@ -504,6 +505,10 @@ "preview": "", "previewCondition": "" }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, "rule-form": { "evaluation": { "evaluation-group-and-interval": "", @@ -1068,23 +1073,18 @@ "elements": { "dashboard": "", "objects": "", + "panel": "", "panels": "", + "row": "", "rows": "", + "tab": "", "tabs": "" }, - "objects": { - "multi-select": { - "selection-number": "" - } - }, "open": "", "row": { "header": { "hide": "", "title": "" - }, - "multi-select": { - "title": "" } } }, @@ -1165,13 +1165,11 @@ "copy-or-duplicate": "", "delete": "", "duplicate": "", - "layout": "", - "panels-title": "" + "layout": "" } }, "options": { "description": "", - "title": "", "title-option": "" }, "outline": { @@ -1214,7 +1212,6 @@ }, "rows-layout": { "description": "", - "item-name": "", "name": "", "option": { "height": "", @@ -1253,9 +1250,6 @@ "menu": { "move-tab": "" }, - "multi-select": { - "title": "" - }, "name": "", "tab": { "menu": { @@ -1270,7 +1264,6 @@ "new": "" }, "tab-options": { - "title": "", "title-option": "" } }, @@ -1347,7 +1340,6 @@ "description": "", "open-edit": "", "plugin-type-image": "", - "title": "", "title-option": "", "transparent-background": "" } diff --git a/public/locales/es-ES/grafana.json b/public/locales/es-ES/grafana.json index deb63c2a931..ca06ff0f505 100644 --- a/public/locales/es-ES/grafana.json +++ b/public/locales/es-ES/grafana.json @@ -184,7 +184,8 @@ "rule-identifier": "", "rule-type": "", "state-error-timeout": "", - "state-no-data": "" + "state-no-data": "", + "target-datasource-uid": "" }, "alert-recording-rule-form": { "evaluation-behaviour": { @@ -504,6 +505,10 @@ "preview": "", "previewCondition": "" }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, "rule-form": { "evaluation": { "evaluation-group-and-interval": "", @@ -1068,23 +1073,18 @@ "elements": { "dashboard": "", "objects": "", + "panel": "", "panels": "", + "row": "", "rows": "", + "tab": "", "tabs": "" }, - "objects": { - "multi-select": { - "selection-number": "" - } - }, "open": "", "row": { "header": { "hide": "", "title": "" - }, - "multi-select": { - "title": "" } } }, @@ -1165,13 +1165,11 @@ "copy-or-duplicate": "", "delete": "", "duplicate": "", - "layout": "", - "panels-title": "" + "layout": "" } }, "options": { "description": "", - "title": "", "title-option": "" }, "outline": { @@ -1214,7 +1212,6 @@ }, "rows-layout": { "description": "", - "item-name": "", "name": "", "option": { "height": "", @@ -1253,9 +1250,6 @@ "menu": { "move-tab": "" }, - "multi-select": { - "title": "" - }, "name": "", "tab": { "menu": { @@ -1270,7 +1264,6 @@ "new": "" }, "tab-options": { - "title": "", "title-option": "" } }, @@ -1347,7 +1340,6 @@ "description": "", "open-edit": "", "plugin-type-image": "", - "title": "", "title-option": "", "transparent-background": "" } diff --git a/public/locales/fr-FR/grafana.json b/public/locales/fr-FR/grafana.json index 7e32cde652b..cec4d85c830 100644 --- a/public/locales/fr-FR/grafana.json +++ b/public/locales/fr-FR/grafana.json @@ -184,7 +184,8 @@ "rule-identifier": "", "rule-type": "", "state-error-timeout": "", - "state-no-data": "" + "state-no-data": "", + "target-datasource-uid": "" }, "alert-recording-rule-form": { "evaluation-behaviour": { @@ -504,6 +505,10 @@ "preview": "", "previewCondition": "" }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, "rule-form": { "evaluation": { "evaluation-group-and-interval": "", @@ -1068,23 +1073,18 @@ "elements": { "dashboard": "", "objects": "", + "panel": "", "panels": "", + "row": "", "rows": "", + "tab": "", "tabs": "" }, - "objects": { - "multi-select": { - "selection-number": "" - } - }, "open": "", "row": { "header": { "hide": "", "title": "" - }, - "multi-select": { - "title": "" } } }, @@ -1165,13 +1165,11 @@ "copy-or-duplicate": "", "delete": "", "duplicate": "", - "layout": "", - "panels-title": "" + "layout": "" } }, "options": { "description": "", - "title": "", "title-option": "" }, "outline": { @@ -1214,7 +1212,6 @@ }, "rows-layout": { "description": "", - "item-name": "", "name": "", "option": { "height": "", @@ -1253,9 +1250,6 @@ "menu": { "move-tab": "" }, - "multi-select": { - "title": "" - }, "name": "", "tab": { "menu": { @@ -1270,7 +1264,6 @@ "new": "" }, "tab-options": { - "title": "", "title-option": "" } }, @@ -1347,7 +1340,6 @@ "description": "", "open-edit": "", "plugin-type-image": "", - "title": "", "title-option": "", "transparent-background": "" } diff --git a/public/locales/hu-HU/grafana.json b/public/locales/hu-HU/grafana.json new file mode 100644 index 00000000000..f3a7ee625b6 --- /dev/null +++ b/public/locales/hu-HU/grafana.json @@ -0,0 +1,4010 @@ +{ + "_comment": "", + "access-control": { + "add-permission": { + "role-label": "", + "serviceaccount-label": "", + "team-label": "", + "title": "", + "user-label": "" + }, + "add-permissions": { + "save": "" + }, + "permission-list": { + "permission": "" + }, + "permission-list-item": { + "inherited": "" + }, + "permissions": { + "add-label": "", + "no-permissions": "", + "permissions-change-warning": "", + "role": "", + "serviceaccount": "", + "team": "", + "title": "", + "user": "" + } + }, + "action-editor": { + "modal": { + "cancel-button": "", + "save-button": "" + } + }, + "admin": { + "anon-users": { + "not-found": "" + }, + "edit-org": { + "access-denied": "", + "heading": "", + "update-button": "", + "users-heading": "" + }, + "feature-toggles": { + "sub-title": "" + }, + "get-enterprise": { + "contact-us": "", + "description": "", + "features-heading": "", + "included-description": "", + "included-heading": "", + "service-title": "", + "team-sync-details": "", + "title": "" + }, + "ldap": { + "test-mapping-heading": "", + "test-mapping-run-button": "" + }, + "ldap-permissions": { + "active": "", + "admin": "", + "inactive": "" + }, + "ldap-status": { + "title": "" + }, + "ldap-sync": { + "debug-button": "", + "external-sync-description": "", + "external-sync-label": "", + "next-sync-label": "", + "not-enabled": "", + "sync-button": "", + "title": "" + }, + "ldap-sync-info": { + "title": "" + }, + "ldap-user-groups": { + "no-org-found": "" + }, + "ldap-user-info": { + "no-team": "" + }, + "org-uers": { + "last-seen-never": "" + }, + "org-users": { + "not-editable": "" + }, + "orgs": { + "delete-body": "", + "id-header": "", + "name-header": "", + "new-org-button": "" + }, + "server-settings": { + "alerts-button": "", + "dashboards-button": "", + "data-sources-button": "", + "not-found": "", + "title": "", + "users-button": "" + }, + "settings": { + "info-description": "" + }, + "upgrade-info": { + "title": "" + }, + "user-orgs": { + "add-button": "", + "change-role-button": "", + "external-user-tooltip": "", + "remove-button": "", + "role-not-editable": "", + "title": "" + }, + "user-orgs-modal": { + "add-button": "", + "cancel-button": "" + }, + "user-permissions": { + "change-button": "", + "grafana-admin-key": "", + "grafana-admin-no": "", + "grafana-admin-yes": "", + "title": "" + }, + "user-profile": { + "delete-button": "", + "disable-button": "", + "edit-button": "", + "enable-button": "", + "title": "" + }, + "user-sessions": { + "browser-column": "", + "force-logout-all-button": "", + "force-logout-button": "", + "ip-column": "", + "last-seen-column": "", + "logged-on-column": "", + "title": "" + }, + "users-create": { + "create-button": "" + }, + "users-list": { + "create-button": "" + }, + "users-table": { + "last-seen-never": "", + "no-licensed-roles": "" + } + }, + "alert-labels": { + "button": { + "hide": "", + "show": { + "tooltip": "" + } + } + }, + "alerting": { + "alert": { + "alert-state": "", + "annotations": "", + "evaluation": "", + "evaluation-paused": "", + "evaluation-paused-description": "", + "last-evaluated": "", + "last-evaluation-duration": "", + "last-updated-at": "", + "last-updated-by": "", + "no-annotations": "", + "pending-period": "", + "rule": "", + "rule-identifier": "", + "rule-type": "", + "state-error-timeout": "", + "state-no-data": "", + "target-datasource-uid": "" + }, + "alert-recording-rule-form": { + "evaluation-behaviour": { + "description": { + "text": "" + } + } + }, + "alert-rules": { + "firing-for": "", + "next-evaluation": "", + "next-evaluation-in": "", + "rule-definition": "" + }, + "alertform": { + "labels": { + "alerting": "", + "recording": "" + } + }, + "alertVersionHistory": { + "alerting": "", + "alerting-change-description": "", + "annotations": "", + "compare": "", + "compare-with-latest": "", + "compareVersions": "", + "comparing-versions": "", + "condition": "", + "contactPointRouting": "", + "description": "", + "errorloading": "", + "execErrorState": "", + "intervalSeconds": "", + "labels": "", + "latest": "", + "name": "", + "namespace_uid": "", + "noDataState": "", + "noVersionsFound": "", + "paused": "", + "pendingPeriod": "", + "provisioning": "", + "provisioning-change-description": "", + "queryAndAlertCondition": "", + "restore": "", + "restore-manually": "", + "restore-modal": { + "body": "", + "confirm": "", + "error": "", + "summary": "", + "title": "" + }, + "restore-version": "", + "rule_group": "", + "unknown": "", + "unknown-change-description": "", + "user-id": "", + "warning-restore-manually": "", + "warning-restore-manually-title": "" + }, + "annotations": { + "description": "", + "title": "" + }, + "central-alert-history": { + "details": { + "error": "", + "header": { + "alert-rule": "", + "instance": "", + "state": "", + "timestamp": "" + }, + "loading": "", + "no-recognized-state": "", + "no-values": "", + "not-found": "", + "number-transitions": "", + "state": { + "alerting": "", + "error": "", + "no-data": "", + "normal": "", + "pending": "" + }, + "state-transitions": "", + "unknown-event-state": "", + "unknown-rule": "", + "value-in-transition": "" + }, + "error": "", + "filter": { + "clear": "", + "info": { + "label1": "", + "label2": "", + "label3": "", + "label4": "" + } + }, + "filterBy": "", + "too-many-events": { + "text": "", + "title": "" + } + }, + "common": { + "cancel": "", + "clear-filters": "", + "delete": "", + "edit": "", + "export": "", + "export-all": "", + "loading": "", + "search-by-matchers": "", + "titles": { + "notification-templates": "" + }, + "view": "" + }, + "contact-points": { + "create": "", + "custom-template-value": "", + "delete-reasons": { + "heading": "", + "no-permissions": "", + "policies": "", + "provisioned": "", + "rules": "" + }, + "delivered-to": "", + "delivery-duration": "", + "empty-state": { + "title": "" + }, + "key-value-map": { + "add": "", + "confirm-add": "" + }, + "last-delivery-attempt": "", + "last-delivery-failed": "", + "no-contact-points-found": "", + "no-delivery-attempts": "", + "no-integrations": "", + "only-firing": "", + "receiver-summary": { + "jira": "" + }, + "telegram": { + "parse-mode-warning-body": "", + "parse-mode-warning-title": "" + }, + "used-by_one": "", + "used-by_other": "", + "used-by-rules_one": "", + "used-by-rules_other": "" + }, + "contactPointFilter": { + "label": "" + }, + "copy-to-clipboard": "", + "dag": { + "missing-reference": "", + "self-reference": "" + }, + "export": { + "subtitle": { + "formats": "", + "one-format": "" + } + }, + "folderAndGroup": { + "evaluation": { + "modal": { + "text": { + "alerting": "", + "recording": "" + } + } + } + }, + "group-actions": { + "actions-trigger": "", + "delete": "", + "edit": "", + "export": "", + "reorder": "" + }, + "list-view": { + "empty": { + "new-alert-rule": "", + "new-recording-rule": "", + "provisioning": "" + }, + "section": { + "dataSourceManaged": { + "title": "" + }, + "grafanaManaged": { + "export-new-rule": "", + "export-rules": "", + "loading": "", + "new-recording-rule": "", + "title": "" + } + } + }, + "manage-permissions": { + "button": "", + "title": "" + }, + "mute_timings": { + "error-loading": { + "description": "", + "title": "" + } + }, + "mute-timings": { + "add-mute-timing": "", + "description": "", + "save": "", + "saving": "" + }, + "notification-preview": { + "alertmanager": "", + "error": "", + "initialized": "", + "preview-routing": "", + "title": "", + "uninitialized": "" + }, + "notification-templates": { + "duplicate": { + "subTitle": "", + "title": "" + }, + "edit": { + "subTitle": "", + "title": "" + }, + "new": { + "subTitle": "", + "title": "" + } + }, + "policies": { + "default-policy": { + "description": "", + "title": "", + "update": "" + }, + "delete": { + "confirm": "", + "warning-1": "", + "warning-2": "" + }, + "filter-description": "", + "generated-policies": "", + "matchers": "", + "metadata": { + "active-time": "", + "delivered-to": "", + "grouped-by": "", + "grouping": { + "none": "", + "single-group": "" + }, + "inherited": "", + "mute-time": "", + "timingOptions": { + "groupInterval": { + "description": "", + "label": "" + }, + "groupWait": { + "description": "", + "label": "" + }, + "repeatInterval": { + "description": "", + "label": "" + } + }, + "n-instances_one": "", + "n-instances_other": "" + }, + "new-child": "", + "new-policy": "", + "no-matchers": "", + "reload-policies": "", + "save-policy": "", + "update": { + "please-wait": "", + "update-policy": "", + "updating": "" + }, + "update-errors": { + "conflict": "", + "error-code": "", + "fallback": "", + "suffix": "", + "title": "" + }, + "n-more-policies_one": "", + "n-more-policies_other": "" + }, + "provisioning": { + "badge-tooltip-provenance": "", + "badge-tooltip-standard": "" + }, + "queryAndExpressionsStep": { + "disableAdvancedOptions": { + "text": "" + }, + "preview": "", + "previewCondition": "" + }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, + "rule-form": { + "evaluation": { + "evaluation-group-and-interval": "", + "group": { + "cancel": "", + "create": "", + "interval": "" + }, + "group-name": "", + "group-text": "", + "new-group": "", + "pause": { + "alerting": "", + "recording": "" + }, + "select-folder-before": "" + }, + "evaluation-behaviour": { + "description": { + "text": "" + }, + "info-help": { + "text": "" + }, + "pending-period": "" + }, + "evaluation-behaviour-description1": "", + "evaluation-behaviour-description2": "", + "evaluation-behaviour-description3": "", + "evaluation-behaviour-for": { + "error-parsing": "", + "validation": "" + }, + "folder": { + "cancel": "", + "create": "", + "create-folder": "", + "creating-new-folder": "", + "label": "", + "name": "", + "new-folder": "", + "new-folder-or": "" + }, + "folder-and-labels": "", + "folders": { + "help-info": "" + }, + "labels": { + "help-info": "" + }, + "pause": { + "label": "" + }, + "threshold": { + "recovery": { + "stop-alerting-above": "", + "stop-alerting-bellow": "", + "stop-alerting-equal": "", + "stop-alerting-inside-range": "", + "stop-alerting-less": "", + "stop-alerting-more": "", + "stop-alerting-not-equal": "", + "stop-alerting-outside-range": "", + "title": "" + } + } + }, + "rule-groups": { + "delete": { + "success": "" + }, + "move": { + "success": "" + }, + "rename": { + "success": "" + }, + "update": { + "success": "" + } + }, + "rule-list": { + "configure-datasource": "", + "ds-error-boundary": { + "description": "", + "title": "" + }, + "filter-view": { + "no-more-results": "", + "no-rules-found": "" + }, + "new-alert-rule": "", + "pagination": { + "next-page": "", + "previous-page": "" + }, + "return-button": { + "title": "" + }, + "rulerrule-loading-error": "" + }, + "rule-state": { + "creating": "", + "deleting": "", + "paused": "", + "recording-rule": "" + }, + "rule-view": { + "query": { + "datasources-na": { + "description": "", + "title": "" + } + } + }, + "rule-viewer": { + "error-loading": "", + "prometheus-consistency-check": { + "alert-message": "", + "alert-title": "" + } + }, + "rules": { + "add-rule": { + "success": "" + }, + "delete-rule": { + "success": "" + }, + "pause-rule": { + "success": "" + }, + "resume-rule": { + "success": "" + }, + "update-rule": { + "success": "" + } + }, + "search": { + "property": { + "data-source": "", + "evaluation-group": "", + "labels": "", + "namespace": "", + "rule-health": "", + "rule-name": "", + "rule-type": "", + "state": "" + }, + "save-query": "" + }, + "silences": { + "affected-instances": "", + "only-firing-instances": "", + "preview-affected-instances": "" + }, + "simpleCondition": { + "alertCondition": "" + }, + "templates": { + "editor": { + "add-example": "", + "auto-complete": "", + "goto-docs": "" + }, + "help": { + "intro": "" + }, + "misconfigured-badge-text": "", + "misconfigured-warning": "", + "misconfigured-warning-details": "" + }, + "threshold": { + "to": "" + } + }, + "annotations": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + } + }, + "api-keys": { + "empty-state": { + "message": "" + } + }, + "app-chrome": { + "skip-content-button": "", + "top-bar": { + "sign-in": "" + } + }, + "app-notification": { + "item": { + "trace-id": "" + } + }, + "bookmarks-page": { + "empty": { + "message": "", + "tip": "" + } + }, + "bouncing-loader": { + "label": "" + }, + "browse-dashboards": { + "action": { + "cancel-button": "", + "cannot-move-folders": "", + "confirmation-text": "", + "delete-button": "", + "delete-modal-invalid-text": "", + "delete-modal-invalid-title": "", + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "delete-modal-title": "", + "deleting": "", + "manage-permissions-button": "", + "move-button": "", + "move-modal-alert": "", + "move-modal-field-label": "", + "move-modal-text": "", + "move-modal-title": "", + "moving": "", + "new-folder-name-required-phrase": "" + }, + "actions": { + "button-to-recently-deleted": "" + }, + "counts": { + "alertRule_one": "", + "alertRule_other": "", + "dashboard_one": "", + "dashboard_other": "", + "folder_one": "", + "folder_other": "", + "libraryPanel_one": "", + "libraryPanel_other": "", + "total_one": "", + "total_other": "" + }, + "dashboards-tree": { + "collapse-folder-button": "", + "expand-folder-button": "", + "name-column": "", + "select-all-header-checkbox": "", + "select-checkbox": "", + "tags-column": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "", + "title-folder": "" + }, + "folder-actions-button": { + "delete": "", + "folder-actions": "", + "manage-permissions": "", + "move": "" + }, + "folder-picker": { + "accessible-label": "", + "button-label": "", + "clear-selection": "", + "empty-message": "", + "error-title": "", + "non-folder-item": "", + "search-placeholder": "", + "unknown-error": "" + }, + "hard-delete": { + "success": "" + }, + "manage-folder-nav": { + "alert-rules": "", + "dashboards": "", + "panels": "" + }, + "new-folder-form": { + "cancel-label": "", + "create-label": "", + "name-label": "" + }, + "no-results": { + "clear": "", + "text": "" + }, + "soft-delete": { + "success": "" + } + }, + "clipboard-button": { + "inline-toast": { + "success": "" + } + }, + "combobox": { + "async": { + "error": "" + }, + "clear": { + "title": "" + }, + "custom-value": { + "description": "" + }, + "group": { + "undefined": "" + }, + "options": { + "no-found": "" + } + }, + "command-palette": { + "action": { + "change-theme": "", + "dark-theme": "", + "light-theme": "" + }, + "empty-state": { + "message": "" + }, + "search-box": { + "placeholder": "" + }, + "section": { + "actions": "", + "dashboard-search-results": "", + "folder-search-results": "", + "pages": "", + "preferences": "", + "recent-dashboards": "" + } + }, + "common": { + "apply": "", + "cancel": "", + "clear": "", + "close": "", + "collapse": "", + "edit": "", + "help": "", + "loading": "", + "locale": { + "default": "" + }, + "save": "", + "search": "", + "view": "" + }, + "configuration-tracker": { + "config-card": { + "complete": "" + } + }, + "connections": { + "connect-data": { + "category-header-label": "", + "empty-message": "", + "request-data-source": "", + "roadmap": "" + }, + "search": { + "placeholder": "" + } + }, + "core": { + "versionHistory": { + "comparison": { + "header": { + "hide-json-diff": "", + "show-json-diff": "", + "text": "" + }, + "select": "" + }, + "no-properties-changed": "", + "table": { + "updated": "", + "updatedBy": "", + "version": "" + }, + "view-json-diff": "" + } + }, + "correlations": { + "add-new": "", + "alert": { + "error-message": "", + "title": "" + }, + "basic-info-form": { + "description-description": "", + "description-label": "", + "label-description": "", + "label-label": "", + "label-placeholder": "", + "label-required": "", + "sub-text": "", + "title": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + }, + "list": { + "delete": "", + "label": "", + "loading": "", + "read-only": "", + "source": "", + "target": "" + }, + "navigation-form": { + "add-button": "", + "back-button": "", + "next-button": "", + "save-button": "" + }, + "page-content": "", + "page-heading": "", + "query-editor": { + "control-rules": "", + "data-source-text": "", + "data-source-title": "", + "error-text": "", + "error-title": "", + "loading": "", + "query-description": "", + "query-editor-title": "", + "query-label": "" + }, + "source-form": { + "control-required": "", + "description": "", + "description-external-pre": "", + "description-query-pre": "", + "external-title": "", + "heading-external": "", + "heading-query": "", + "query-title": "", + "results-description": "", + "results-label": "", + "results-required": "", + "source-description": "", + "source-label": "", + "sub-text": "" + }, + "sub-title": "", + "target-form": { + "control-rules": "", + "sub-text": "", + "target-description-external": "", + "target-description-query": "", + "target-label": "", + "target-type-description": "", + "title": "", + "type-label": "" + }, + "trans-details": { + "logfmt-description": "", + "logfmt-label": "", + "regex-description": "", + "regex-expression": "", + "regex-label": "", + "regex-map-values": "" + }, + "transform": { + "add-button": "", + "heading": "", + "no-transform": "" + }, + "transform-row": { + "expression-label": "", + "expression-required": "", + "expression-tooltip": "", + "field-input": "", + "field-label": "", + "field-tooltip": "", + "map-value-label": "", + "map-value-tooltip": "", + "remove-button": "", + "remove-tooltip": "", + "transform-required": "", + "type-label": "", + "type-tooltip": "" + } + }, + "dashboard": { + "add-menu": { + "import": "", + "paste-panel": "", + "row": "", + "visualization": "" + }, + "alert-rules-drawer": { + "redirect-link": "", + "subtitle": "" + }, + "default-layout": { + "description": "", + "item-options": { + "repeat": { + "direction": { + "horizontal": "", + "title": "", + "vertical": "" + }, + "max": "", + "title": "", + "variable": { + "description": "", + "title": "" + } + } + }, + "name": "", + "row-actions": { + "delete": "", + "modal": { + "alt-action": "", + "text": "", + "title": "" + } + }, + "row-options": { + "button": { + "label": "" + }, + "form": { + "cancel": "", + "repeat-for": { + "label": "", + "learn-more": "", + "warning": { + "text": "" + } + }, + "title": "", + "update": "" + }, + "modal": { + "title": "" + }, + "repeat": { + "title": "", + "variable": { + "title": "" + } + }, + "title": "" + } + }, + "edit-pane": { + "elements": { + "dashboard": "", + "objects": "", + "panel": "", + "panels": "", + "row": "", + "rows": "", + "tab": "", + "tabs": "" + }, + "open": "", + "row": { + "header": { + "hide": "", + "title": "" + } + } + }, + "editpane": { + "add": "", + "configure": "", + "outline": "" + }, + "empty": { + "add-library-panel-body": "", + "add-library-panel-button": "", + "add-library-panel-header": "", + "add-visualization-body": "", + "add-visualization-button": "", + "add-visualization-header": "", + "import-a-dashboard-body": "", + "import-a-dashboard-header": "", + "import-dashboard-button": "" + }, + "errors": { + "failed-to-load": "" + }, + "inspect": { + "data-tab": "", + "error-tab": "", + "json-tab": "", + "meta-tab": "", + "query-tab": "", + "stats-tab": "", + "subtitle": "", + "title": "" + }, + "inspect-data": { + "data-options": "", + "dataframe-aria-label": "", + "dataframe-label": "", + "download-csv": "", + "download-excel-description": "", + "download-excel-label": "", + "download-logs": "", + "download-service": "", + "download-traces": "", + "excel-header": "", + "formatted": "", + "formatted-data-description": "", + "formatted-data-label": "", + "panel-transforms": "", + "series-to-columns": "", + "transformation": "", + "transformations-description": "", + "transformations-label": "" + }, + "inspect-json": { + "dataframe-description": "", + "dataframe-label": "", + "panel-data-description": "", + "panel-data-label": "", + "panel-json-description": "", + "panel-json-label": "", + "select-source": "", + "unknown": "" + }, + "inspect-meta": { + "no-inspector": "" + }, + "inspect-stats": { + "data-title": "", + "data-traceids": "", + "processing-time": "", + "queries": "", + "request-time": "", + "rows": "", + "table-title": "" + }, + "layout": { + "common": { + "copy": "", + "copy-or-duplicate": "", + "delete": "", + "duplicate": "", + "layout": "" + } + }, + "options": { + "description": "", + "title-option": "" + }, + "outline": { + "tree": { + "item": { + "collapse": "", + "empty": "", + "expand": "" + } + } + }, + "panel-edit": { + "alerting-tab": { + "dashboard-not-saved": "", + "no-rules": "" + } + }, + "responsive-layout": { + "description": "", + "item-options": { + "hide-no-data": "", + "repeat": { + "variable": { + "description": "", + "title": "" + } + }, + "title": "" + }, + "name": "", + "options": { + "columns": "", + "fixed": "", + "min": "", + "one-column": "", + "rows": "", + "three-columns": "", + "two-columns": "" + } + }, + "rows-layout": { + "description": "", + "name": "", + "option": { + "height": "", + "hide-header": "", + "repeat": "", + "title": "" + }, + "options": { + "height-expand": "", + "height-min": "" + }, + "row": { + "collapse": "", + "expand": "", + "menu": { + "add": "", + "add-panel": "", + "add-row-above": "", + "add-row-below": "", + "move-down": "", + "move-row": "", + "move-up": "" + }, + "new": "", + "repeat": { + "learn-more": "", + "warning": "" + } + }, + "row-options": { + "title-option": "" + } + }, + "tabs-layout": { + "description": "", + "menu": { + "move-tab": "" + }, + "name": "", + "tab": { + "menu": { + "add": "", + "add-panel": "", + "add-tab-above": "", + "add-tab-after": "", + "add-tab-before": "", + "move-left": "", + "move-right": "" + }, + "new": "" + }, + "tab-options": { + "title-option": "" + } + }, + "toolbar": { + "add": "", + "add-panel": "", + "add-panel-description": "", + "add-panel-lib": "", + "add-row": "", + "add-tab": "", + "alert-rules": "", + "back-to-dashboard": "", + "dashboard-settings": { + "label": "", + "tooltip": "" + }, + "discard-library-panel-changes": "", + "discard-panel": "", + "discard-panel-new": "", + "edit": { + "label": "", + "tooltip": "" + }, + "edit-dashboard-v2-schema": "", + "enter-edit-mode": { + "label": "", + "tooltip": "" + }, + "exit-edit-mode": { + "label": "", + "tooltip": "" + }, + "libray-panel-description": "", + "mark-favorite": "", + "more-save-options": "", + "open-original": "", + "playlist-next": "", + "playlist-previous": "", + "playlist-stop": "", + "public-dashboard": "", + "refresh": "", + "row-description": "", + "save": "", + "save-dashboard": { + "label": "", + "tooltip": "" + }, + "save-dashboard-copy": { + "label": "", + "tooltip": "" + }, + "save-dashboard-short": "", + "save-library-panel": "", + "settings": "", + "share": { + "label": "", + "tooltip": "" + }, + "share-button": "", + "show-hidden-elements": "", + "switch-old-dashboard": "", + "tabs-description": "", + "unlink-library-panel": "", + "unmark-favorite": "" + }, + "validation": { + "invalid-dashboard-id": "", + "invalid-json": "", + "tags-expected-array": "", + "tags-expected-strings": "" + }, + "viz-panel": { + "options": { + "description": "", + "open-edit": "", + "plugin-type-image": "", + "title-option": "", + "transparent-background": "" + } + } + }, + "dashboard-import": { + "file-dropzone": { + "primary-text": "", + "secondary-text": "" + }, + "form-actions": { + "cancel": "", + "load": "" + }, + "gcom-field": { + "label": "", + "load-button": "", + "placeholder": "", + "validation-required": "" + }, + "json-field": { + "label": "", + "validation-required": "" + } + }, + "dashboard-links": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "title": "" + } + }, + "dashboard-settings": { + "annotations": { + "title": "" + }, + "dashboard-delete-button": "", + "delete-modal": { + "confirmation-text": "", + "delete-button": "", + "title": "" + }, + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "general": { + "auto-refresh-description": "", + "auto-refresh-label": "", + "description-label": "", + "editable-description": "", + "editable-label": "", + "folder-label": "", + "panel-options-graph-tooltip-description": "", + "panel-options-graph-tooltip-label": "", + "panel-options-label": "", + "panels-preload-description": "", + "panels-preload-label": "", + "tags-label": "", + "title": "", + "title-label": "" + }, + "json-editor": { + "save-button": "", + "subtitle": "", + "title": "" + }, + "links": { + "title": "" + }, + "permissions": { + "title": "" + }, + "provisioned-delete-modal": { + "confirm-button": "", + "text-1": "", + "text-2": "", + "text-3": "", + "text-link": "", + "title": "" + }, + "settings": { + "title": "" + }, + "time-picker": { + "hide-time-picker": "", + "now-delay-description": "", + "now-delay-label": "", + "refresh-live-dashboards-description": "", + "refresh-live-dashboards-label": "", + "time-options-label": "", + "time-zone-label": "", + "week-start-label": "" + }, + "time-regions": { + "advanced-description-cron": "", + "advanced-description-rest": "", + "advanced-description-use": "", + "advanced-label": "" + }, + "variables": { + "title": "" + }, + "versions": { + "title": "" + } + }, + "dashboards": { + "panel-edit": { + "angular-deprecation-button-open-panel-json": "", + "angular-deprecation-description": "", + "angular-deprecation-heading": "" + }, + "panel-queries": { + "add-query-from-library": "" + }, + "settings": { + "variables": { + "dependencies": { + "button": "", + "title": "" + } + } + } + }, + "data-source-list": { + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + } + }, + "data-source-picker": { + "add-new-data-source": "", + "built-in-list": { + "description-dashboard": "", + "description-grafana": "", + "description-mixed": "" + }, + "list": { + "no-data-source-message": "" + }, + "modal": { + "configure-new-data-source": "", + "input-placeholder": "", + "title": "" + }, + "open-advanced-button": "" + }, + "data-source-testing-status-page": { + "error-more-details-link": "", + "success-more-details-links": "" + }, + "data-sources": { + "datasource-add-button": { + "label": "" + }, + "empty-state": { + "message": "" + } + }, + "embed": { + "share": { + "time-range-description": "", + "time-range-label": "" + } + }, + "empty-list-cta": { + "pro-tip": "" + }, + "entity-not-found": { + "description": "" + }, + "errors": { + "dashboard-settings": { + "annotations": { + "datasource": "" + } + } + }, + "explore": { + "add-to-dashboard": "", + "drilldownInfo": { + "action": "", + "description": "", + "title": "" + }, + "logs": { + "logs-volume": { + "add-filters": "", + "decrease-timerange": "", + "much-data": "" + }, + "maximum-pinned-logs": "", + "no-logs-found": "", + "scan-for-older-logs": "", + "stop-scan": "" + }, + "rich-history": { + "close-tooltip": "", + "datasource-a-z": "", + "datasource-z-a": "", + "newest-first": "", + "oldest-first": "", + "query-history": "", + "query-library": "", + "settings": "", + "starred": "" + }, + "rich-history-card": { + "add-comment-form": "", + "add-comment-tooltip": "", + "add-to-library": "", + "cancel": "", + "confirm-delete": "", + "copy-query-tooltip": "", + "copy-shortened-link-tooltip": "", + "datasource-icon-label": "", + "datasource-name-label": "", + "datasource-not-exist": "", + "delete-query-confirmation-title": "", + "delete-query-title": "", + "delete-query-tooltip": "", + "delete-starred-query-confirmation-text": "", + "edit-comment-tooltip": "", + "optional-description": "", + "query-comment-label": "", + "query-text-label": "", + "save-comment": "", + "star-query-tooltip": "", + "unstar-query-tooltip": "", + "update-comment-form": "" + }, + "rich-history-container": { + "loading": "" + }, + "rich-history-notification": { + "query-copied": "", + "query-deleted": "" + }, + "rich-history-queries-tab": { + "displaying-partial-queries": "", + "displaying-queries": "", + "filter-aria-label": "", + "filter-history": "", + "filter-placeholder": "", + "history-local": "", + "loading": "", + "loading-results": "", + "search-placeholder": "", + "showing-queries": "", + "sort-aria-label": "", + "sort-placeholder": "" + }, + "rich-history-settings-tab": { + "alert-info": "", + "change-default-tab": "", + "clear-history-info": "", + "clear-query-history": "", + "clear-query-history-button": "", + "delete-confirm": "", + "delete-confirm-text": "", + "delete-title": "", + "history-time-span": "", + "history-time-span-description": "", + "only-show-active-datasource": "", + "query-history-deleted": "", + "retention-period": { + "1-week": "", + "2-days": "", + "2-weeks": "", + "5-days": "" + } + }, + "rich-history-starred-tab": { + "filter-queries-aria-label": "", + "filter-queries-placeholder": "", + "loading": "", + "loading-results": "", + "local-history-message": "", + "search-queries-placeholder": "", + "showing-queries": "", + "sort-queries-aria-label": "", + "sort-queries-placeholder": "" + }, + "rich-history-utils": { + "a-week-ago": "", + "days-ago": "", + "default-from": "", + "default-to": "", + "today": "", + "two-weeks-ago": "", + "yesterday": "" + }, + "rich-history-utils-notification": { + "saving-failed": "", + "update-failed": "" + }, + "run-query": { + "left-pane": "", + "right-pane": "", + "run-query-button": "", + "switch-datasource-button": "" + }, + "secondary-actions": { + "add-from-query-library": "", + "query-add-button": "", + "query-add-button-aria-label": "", + "query-history-button": "", + "query-history-button-aria-label": "", + "query-inspector-button": "", + "query-inspector-button-aria-label": "" + }, + "table": { + "no-data": "", + "title": "", + "title-with-name": "" + }, + "toolbar": { + "add-to-extensions": "", + "add-to-queryless-extensions": "", + "aria-label": "", + "copy-link": "", + "copy-link-abs-time": "", + "copy-links-absolute-category": "", + "copy-links-normal-category": "", + "copy-shortened-link": "", + "copy-shortened-link-abs-time": "", + "copy-shortened-link-label": "", + "copy-shortened-link-menu": "", + "refresh-picker-cancel": "", + "refresh-picker-run": "", + "split-close": "", + "split-close-tooltip": "", + "split-narrow": "", + "split-title": "", + "split-tooltip": "", + "split-widen": "" + } + }, + "explore-metrics": { + "breakdown": { + "clearFilter": "", + "labelSelect": "", + "missing-otel-labels": "", + "noMatchingValue": "", + "sortBy": "" + }, + "related-logs": { + "LrrDocsLink": "", + "openExploreLogs": "", + "relatedLogsUnavailable": "", + "warnExperimentalFeature": "" + }, + "viewBy": "" + }, + "export": { + "json": { + "cancel-button": "", + "copy-button": "", + "download-button": "", + "download-successful_toast_message": "", + "export-externally-label": "", + "info-text": "", + "title": "" + }, + "menu": { + "export-as-json-label": "", + "export-as-json-tooltip": "" + } + }, + "folder-filter": { + "clear-folder-button": "" + }, + "folder-picker": { + "create-instructions": "", + "loading": "" + }, + "forgot-password": { + "back-button": "", + "change-password": { + "skip-button": "", + "submit-button": "" + }, + "contact-admin": "", + "email-sent": "", + "reset-password-header": "", + "send-email-button": "" + }, + "form-prompt": { + "continue-button": "", + "description": "", + "discard-button": "" + }, + "gen-ai": { + "apply-suggestion": "", + "incomplete-request-error": "", + "send-custom-feedback": "" + }, + "get-enterprise": { + "requires-license": "", + "title": "" + }, + "grafana-ui": { + "action-editor": { + "button": { + "confirm": "", + "confirm-action": "" + }, + "inline": { + "add-action": "", + "edit-action": "" + }, + "modal": { + "action-body": "", + "action-method": "", + "action-query-params": "", + "action-title": "", + "action-title-placeholder": "", + "one-click-description": "" + } + }, + "alert": { + "close-button": "" + }, + "auto-save-field": { + "saved": "", + "saving": "" + }, + "card": { + "option": "" + }, + "cascader": { + "clear-button": "" + }, + "color-picker-popover": { + "palette-tab": "", + "spectrum-tab": "" + }, + "confirm-button": { + "cancel": "" + }, + "confirm-content": { + "placeholder": "" + }, + "data-link-editor": { + "info": "", + "new-tab-label": "", + "title-label": "", + "title-placeholder": "", + "url-label": "" + }, + "data-link-editor-modal": { + "cancel": "", + "one-click-description": "", + "save": "" + }, + "data-link-inline-editor": { + "one-click": "" + }, + "data-links-inline-editor": { + "add-link": "", + "edit-link": "", + "one-click": "", + "one-click-enabled": "", + "title-not-provided": "", + "tooltip-edit": "", + "tooltip-remove": "", + "url-not-provided": "" + }, + "data-source-basic-auth-settings": { + "user-label": "", + "user-placeholder": "" + }, + "data-source-http-proxy-settings": { + "oauth-identity-label": "", + "oauth-identity-tooltip": "", + "skip-tls-verify-label": "", + "ts-client-auth-label": "", + "with-ca-cert-label": "", + "with-ca-cert-tooltip": "" + }, + "data-source-http-settings": { + "access-help": "", + "access-help-details": "", + "access-label": "", + "access-options-browser": "", + "access-options-proxy": "", + "allowed-cookies": "", + "allowed-cookies-tooltip": "", + "auth": "", + "azure-auth-label": "", + "azure-auth-tooltip": "", + "basic-auth": "", + "basic-auth-label": "", + "browser-mode-description": "", + "browser-mode-title": "", + "default-url-access-select": "", + "default-url-tooltip": "", + "direct-url-tooltip": "", + "heading": "", + "proxy-url-tooltip": "", + "server-mode-description": "", + "server-mode-title": "", + "timeout-form-label": "", + "timeout-label": "", + "timeout-tooltip": "", + "url-label": "", + "with-credential-label": "", + "with-credential-tooltip": "" + }, + "data-source-settings": { + "alerting-settings-heading": "", + "alerting-settings-label": "", + "alerting-settings-tooltip": "", + "cert-key-reset": "", + "custom-headers-add": "", + "custom-headers-header": "", + "custom-headers-header-placeholder": "", + "custom-headers-header-remove": "", + "custom-headers-header-value": "", + "custom-headers-title": "", + "secure-socks-heading": "", + "secure-socks-label": "", + "secure-socks-tooltip": "", + "tls-certification-label": "", + "tls-certification-placeholder": "", + "tls-client-certification-label": "", + "tls-client-key-label": "", + "tls-client-key-placeholder": "", + "tls-heading": "", + "tls-server-name-label": "", + "tls-tooltip": "" + }, + "date-time-picker": { + "apply": "", + "calendar-icon-label": "", + "cancel": "", + "next-label": "", + "previous-label": "", + "select-placeholder": "" + }, + "drawer": { + "close": "" + }, + "feature-badge": { + "experimental": "", + "new": "", + "preview": "", + "private-preview": "" + }, + "field-link-list": { + "external-links-heading": "" + }, + "file-dropzone": { + "cancel-upload": "", + "file-too-large": "" + }, + "filter-input": { + "clear": "" + }, + "modal": { + "close-tooltip": "" + }, + "named-colors-palette": { + "text-color-swatch": "", + "transparent-swatch": "" + }, + "page-toolbar": { + "go-back": "", + "search-dashboard-name": "", + "search-links": "", + "search-parent-folder": "" + }, + "pagination": { + "next-page": "", + "previous-page": "" + }, + "secret-form-field": { + "reset": "" + }, + "segment-async": { + "error": "", + "loading": "", + "no-options": "" + }, + "select": { + "default-create-label": "", + "no-options-label": "", + "placeholder": "" + }, + "series-color-picker-popover": { + "y-axis-usage": "" + }, + "spinner": { + "aria-label": "" + }, + "table": { + "copy": "", + "csv-counts": "", + "filter-popup-apply": "", + "filter-popup-cancel": "", + "filter-popup-clear": "", + "filter-popup-heading": "", + "no-values-label": "", + "pagination-summary": "" + }, + "tags-input": { + "add": "" + }, + "user-icon": { + "active-text": "" + }, + "value-pill": { + "remove-button": "" + }, + "viz-legend": { + "right-axis-indicator": "" + }, + "viz-tooltip": { + "actions-confirmation-input-placeholder": "", + "actions-confirmation-label": "", + "actions-confirmation-message": "", + "footer-add-annotation": "", + "footer-click-to-action": "", + "footer-click-to-navigate": "" + } + }, + "graph": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "", + "title": "" + } + }, + "help-modal": { + "column-headers": { + "description": "", + "keys": "" + }, + "shortcuts-category": { + "dashboard": "", + "focused-panel": "", + "global": "", + "time-range": "" + }, + "shortcuts-description": { + "change-theme": "", + "collapse-all-rows": "", + "copy-time-range": "", + "dashboard-settings": "", + "duplicate-panel": "", + "exit-edit/setting-views": "", + "expand-all-rows": "", + "go-to-dashboards": "", + "go-to-explore": "", + "go-to-home-dashboard": "", + "go-to-profile": "", + "make-time-range-permanent": "", + "move-time-range-back": "", + "move-time-range-forward": "", + "open-search": "", + "open-shared-modal": "", + "paste-time-range": "", + "refresh-all-panels": "", + "remove-panel": "", + "save-dashboard": "", + "show-all-shortcuts": "", + "toggle-active-mode": "", + "toggle-all-panel-legends": "", + "toggle-auto-fit": "", + "toggle-exemplars": "", + "toggle-graph-crosshair": "", + "toggle-kiosk": "", + "toggle-panel-edit": "", + "toggle-panel-fullscreen": "", + "toggle-panel-legend": "", + "zoom-out-time-range": "" + }, + "title": "" + }, + "help-wizard": { + "download-snapshot": "", + "github-comment": "", + "support-bundle": "", + "troubleshooting-help": "" + }, + "inspector": { + "query": { + "collapse-all": "", + "copy-to-clipboard": "", + "description": "", + "expand-all": "", + "no-data": "", + "refresh": "" + } + }, + "ldap-drawer": { + "attributes-section": { + "description": "", + "email-label": "", + "label": "", + "member-of-label": "", + "name-label": "", + "surname-label": "", + "username-label": "" + }, + "extra-security-section": { + "client-cert-label": "", + "client-cert-placeholder": "", + "client-cert-value-label": "", + "client-cert-value-placeholder": "", + "client-key-label": "", + "client-key-placeholder": "", + "client-key-value-label": "", + "client-key-value-placeholder": "", + "encryption-provider-base-64": "", + "encryption-provider-description": "", + "encryption-provider-file-path": "", + "encryption-provider-label": "", + "label": "", + "min-tls-version-description": "", + "min-tls-version-label": "", + "root-ca-cert-label": "", + "root-ca-cert-placeholder": "", + "root-ca-cert-value-label": "", + "root-ca-cert-value-placeholder": "", + "start-tls-description": "", + "start-tls-label": "", + "tls-ciphers-label": "", + "tls-ciphers-placeholder": "", + "use-ssl-description": "", + "use-ssl-label": "", + "use-ssl-tooltip": "" + }, + "group-mapping": { + "grafana-admin": { + "description": "", + "label": "" + }, + "group-dn": { + "description": "", + "label": "" + }, + "org-id": { + "description": "", + "label": "" + }, + "org-role": { + "label": "" + }, + "remove": { + "button": "" + } + }, + "group-mapping-section": { + "add": { + "button": "" + }, + "description": "", + "group-search-base-dns-label": "", + "group-search-base-dns-placeholder": "", + "group-search-filter-description": "", + "group-search-filter-label": "", + "group-search-filter-user-attribute-description": "", + "group-search-filter-user-attribute-label": "", + "label": "", + "skip-org-role-sync-description": "", + "skip-org-role-sync-label": "" + }, + "misc-section": { + "allow-sign-up-descrition": "", + "allow-sign-up-label": "", + "label": "", + "port-description": "", + "port-label": "", + "timeout-description": "", + "timeout-label": "" + }, + "title": "" + }, + "ldap-settings-page": { + "advanced-settings-section": { + "edit-button": "", + "subtitle": "", + "title": "" + }, + "alert": { + "discard-success": "", + "error-fetching": "", + "error-saving": "", + "error-validate-form": "", + "feature-flag-disabled": "", + "saved": "" + }, + "bind-dn": { + "description": "", + "label": "", + "placeholder": "" + }, + "bind-password": { + "label": "" + }, + "buttons-section": { + "disable-button": "", + "discard-button": "", + "save-and-enable-button": "", + "save-button": "" + }, + "documentation": "", + "host": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "login-form-alert": { + "description": "", + "title": "" + }, + "search_filter": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "search-base-dns": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "subtitle": "", + "title": "" + }, + "library-panel": { + "add-modal": { + "cancel": "", + "create": "", + "error": "", + "folder": "", + "folder-description": "", + "name": "" + }, + "add-widget": { + "title": "" + }, + "empty-state": { + "message": "", + "more-info": "" + } + }, + "library-panels": { + "empty-state": { + "message": "" + }, + "loading-panel-text": "", + "modal": { + "button-cancel": "", + "button-view-panel1": "", + "button-view-panel2": "", + "panel-not-linked": "", + "select-no-options-message": "", + "select-placeholder": "", + "title": "", + "body_one": "", + "body_other": "" + }, + "save": { + "error": "", + "success": "" + } + }, + "link": { + "share": { + "config-alert-description": "", + "config-alert-title": "", + "config-description": "", + "copy-link-button": "", + "copy-to-clipboard": "", + "short-url-label": "", + "time-range-description": "", + "time-range-label": "" + }, + "share-panel": { + "config-description": "", + "download-image": "", + "render-image": "", + "render-image-error": "", + "render-image-error-description": "" + } + }, + "lock-icon": "", + "login": { + "divider": { + "connecting-text": "" + }, + "error": { + "blocked": "", + "invalid-user-or-password": "", + "title": "", + "unknown": "" + }, + "forgot-password": "", + "form": { + "confirmation-code": "", + "confirmation-code-label": "", + "confirmation-code-placeholder": "", + "email-label": "", + "email-placeholder": "", + "email-required": "", + "name-label": "", + "name-placeholder": "", + "password-label": "", + "password-placeholder": "", + "password-required": "", + "submit-label": "", + "submit-loading-label": "", + "username-label": "", + "username-placeholder": "", + "username-required": "", + "verify-email-label": "", + "verify-email-loading-label": "" + }, + "layout": { + "update-password": "" + }, + "services": { + "sing-in-with-prefix": "" + }, + "signup": { + "button-label": "", + "new-to-question": "" + } + }, + "logs": { + "infinite-scroll": { + "end-of-range": "", + "load-more": "", + "load-newer": "", + "load-older": "", + "older-logs": "" + }, + "log-details": { + "fields": "", + "links": "", + "log-line": "", + "no-details": "" + }, + "log-line-menu": { + "copy-link": "", + "copy-log": "", + "icon-label": "", + "pin-to-outline": "", + "show-context": "", + "unpin-from-outline": "" + }, + "log-row-message": { + "ellipsis": "", + "more": "", + "see-details": "" + }, + "log-rows": { + "disable-popover": { + "confirm": "", + "message": "", + "title": "" + }, + "disable-popover-message": { + "shortcut": "" + } + }, + "logs-navigation": { + "newer-logs": "", + "older-logs": "", + "scroll-bottom": "", + "scroll-top": "", + "start-of-range": "" + }, + "popover-menu": { + "copy": "", + "disable-menu": "", + "line-contains": "", + "line-contains-not": "" + } + }, + "migrate-to-cloud": { + "build-snapshot": { + "description": "", + "title": "", + "when-complete": "" + }, + "building-snapshot": { + "description": "", + "description-eta": "", + "title": "" + }, + "can-i-move": { + "body": "", + "link-title": "", + "title": "" + }, + "connect-modal": { + "body-cloud-stack": "", + "body-get-started": "", + "body-sign-up": "", + "body-token": "", + "body-token-field": "", + "body-token-field-placeholder": "", + "body-token-instructions": "", + "body-view-stacks": "", + "cancel": "", + "connect": "", + "connecting": "", + "title": "", + "token-error-title": "", + "token-errors": { + "instance-request-error": "", + "instance-unreachable": "", + "migration-disabled": "", + "session-creation-failure": "", + "token-invalid": "", + "token-not-saved": "", + "token-request-error": "", + "token-validation-failure": "" + }, + "token-required-error": "" + }, + "cta": { + "button": "", + "header": "" + }, + "delete-migration-token-confirm": { + "body": "", + "confirm-button": "", + "error-title": "", + "title": "" + }, + "disconnect-modal": { + "body": "", + "cancel": "", + "disconnect": "", + "disconnecting": "", + "error": "", + "title": "" + }, + "get-started": { + "body": "", + "configure-pdc-link": "", + "link-title": "", + "step-1": "", + "step-2": "", + "step-3": "", + "step-4": "", + "step-5": "", + "title": "" + }, + "is-it-secure": { + "body": "", + "link-title": "", + "title": "" + }, + "migrate-to-this-stack": { + "body": "", + "link-title": "", + "title": "" + }, + "migrated-counts": { + "alert_rule_groups": "", + "alert_rules": "", + "contact_points": "", + "dashboards": "", + "datasources": "", + "folders": "", + "library_elements": "", + "mute_timings": "", + "notification_policies": "", + "notification_templates": "", + "plugins": "" + }, + "migration-token": { + "delete-button": "", + "delete-modal-body": "", + "delete-modal-cancel": "", + "delete-modal-confirm": "", + "delete-modal-deleting": "", + "delete-modal-title": "", + "error-body": "", + "error-title": "", + "generate-button": "", + "generate-button-loading": "", + "modal-close": "", + "modal-copy-and-close": "", + "modal-copy-button": "", + "modal-field-description": "", + "modal-field-label": "", + "modal-title": "", + "status": "" + }, + "onprem": { + "cancel-snapshot-error-title": "", + "create-snapshot-error-title": "", + "disconnect-error-title": "", + "error-see-server-logs": "", + "get-session-error-title": "", + "get-snapshot-error-title": "", + "migration-finished-with-caveat-title": "", + "migration-finished-with-errors-body": "", + "migration-finished-with-warnings-body": "", + "snapshot-error-status-body": "", + "snapshot-error-status-title": "", + "success-message": "", + "success-message-generic": "", + "success-title": "", + "upload-snapshot-error-title": "" + }, + "pdc": { + "body": "", + "link-title": "", + "title": "" + }, + "pricing": { + "body": "", + "link-title": "", + "title": "" + }, + "public-preview": { + "button-text": "", + "message": "", + "message-cloud": "", + "title": "" + }, + "resource-details": { + "dismiss-button": "", + "error-messages": { + "dashboard-already-managed": "", + "datasource-already-managed": "", + "datasource-invalid-url": "", + "datasource-name-conflict": "", + "folder-name-conflict": "", + "generic-error": "", + "internal-service-error": "", + "library-element-name-conflict": "", + "resource-conflict": "", + "unexpected-error": "", + "unsupported-data-type": "" + }, + "error-title": "", + "generic-title": "", + "missing-message": "", + "resource-summary": "", + "title": "", + "warning-title": "" + }, + "resource-status": { + "error-details-button": "", + "failed": "", + "migrated": "", + "migrating": "", + "not-migrated": "", + "unknown": "", + "warning": "", + "warning-details-button": "" + }, + "resource-table": { + "dashboard-load-error": "", + "error-library-element-sub": "", + "error-library-element-title": "", + "unknown-datasource-title": "", + "unknown-datasource-type": "" + }, + "resource-type": { + "alert_rule": "", + "alert_rule_group": "", + "contact_point": "", + "dashboard": "", + "datasource": "", + "folder": "", + "library_element": "", + "mute_timing": "", + "notification_policy": "", + "notification_template": "", + "plugin": "", + "unknown": "" + }, + "summary": { + "cancel-snapshot": "", + "disconnect": "", + "errored-resource-count": "", + "page-loading": "", + "rebuild-snapshot": "", + "snapshot-date": "", + "snapshot-not-created": "", + "start-migration": "", + "successful-resource-count": "", + "target-stack-title": "", + "total-resource-count": "", + "upload-migration": "" + }, + "support-types-disclosure": { + "text": "" + }, + "token-status": { + "active": "", + "no-active": "", + "unknown": "", + "unknown-error": "" + }, + "what-is-cloud": { + "body": "", + "link-title": "", + "title": "" + }, + "why-host": { + "body": "", + "link-title": "", + "title": "" + } + }, + "multicombobox": { + "all": { + "title": "", + "title-filtered": "" + }, + "clear": { + "title": "" + } + }, + "nav": { + "add-new-connections": { + "title": "" + }, + "admin": { + "subtitle": "", + "title": "" + }, + "alert-list-legacy": { + "title": "" + }, + "alerting": { + "subtitle": "", + "title": "" + }, + "alerting-admin": { + "subtitle": "", + "title": "" + }, + "alerting-am-routes": { + "subtitle": "", + "title": "" + }, + "alerting-channels": { + "title": "" + }, + "alerting-groups": { + "subtitle": "", + "title": "" + }, + "alerting-home": { + "title": "" + }, + "alerting-legacy": { + "title": "" + }, + "alerting-list": { + "subtitle": "", + "title": "" + }, + "alerting-receivers": { + "subtitle": "", + "title": "" + }, + "alerting-silences": { + "subtitle": "", + "title": "" + }, + "alerting-upgrade": { + "subtitle": "", + "title": "" + }, + "alerts-and-incidents": { + "subtitle": "", + "title": "" + }, + "api-keys": { + "subtitle": "", + "title": "" + }, + "application": { + "title": "" + }, + "apps": { + "subtitle": "", + "title": "" + }, + "authentication": { + "title": "" + }, + "bookmarks": { + "title": "" + }, + "bookmarks-empty": { + "title": "" + }, + "collector": { + "title": "" + }, + "config": { + "title": "" + }, + "config-access": { + "subtitle": "", + "title": "" + }, + "config-general": { + "subtitle": "", + "title": "" + }, + "config-plugins": { + "subtitle": "", + "title": "" + }, + "connect-data": { + "title": "" + }, + "connections": { + "subtitle": "", + "title": "" + }, + "correlations": { + "subtitle": "", + "title": "" + }, + "create": { + "title": "" + }, + "create-alert": { + "title": "" + }, + "create-dashboard": { + "title": "" + }, + "create-folder": { + "title": "" + }, + "create-import": { + "title": "" + }, + "dashboards": { + "subtitle": "", + "title": "" + }, + "data-sources": { + "subtitle": "", + "title": "" + }, + "databases": { + "title": "" + }, + "datasources": { + "subtitle": "", + "title": "" + }, + "detect": { + "title": "" + }, + "drilldown": { + "title": "" + }, + "explore": { + "title": "" + }, + "frontend": { + "subtitle": "", + "title": "" + }, + "frontend-app": { + "title": "" + }, + "global-orgs": { + "subtitle": "", + "title": "" + }, + "global-users": { + "subtitle": "", + "title": "" + }, + "grafana-quaderno": { + "title": "" + }, + "groupsync": { + "subtitle": "" + }, + "help": { + "title": "" + }, + "help/community": "", + "help/documentation": "", + "help/keyboard-shortcuts": "", + "help/support": "", + "history-container": { + "drawer-tittle": "" + }, + "history-wrapper": { + "collapse": "", + "expand": "", + "icon-selected": "", + "icon-unselected": "", + "show-more": "", + "today": "", + "yesterday": "" + }, + "home": { + "title": "" + }, + "incidents": { + "title": "" + }, + "infrastructure": { + "subtitle": "", + "title": "" + }, + "integrations": { + "title": "" + }, + "k6": { + "title": "" + }, + "kubernetes": { + "title": "" + }, + "library-panels": { + "subtitle": "", + "title": "" + }, + "machine-learning": { + "title": "" + }, + "manage-folder": { + "subtitle": "" + }, + "migrate-to-cloud": { + "subtitle": "", + "title": "" + }, + "monitoring": { + "subtitle": "", + "title": "" + }, + "new": { + "title": "" + }, + "new-dashboard": { + "title": "" + }, + "new-folder": { + "title": "" + }, + "oncall": { + "title": "" + }, + "org-settings": { + "subtitle": "", + "title": "" + }, + "playlists": { + "subtitle": "", + "title": "" + }, + "plugins": { + "subtitle": "", + "title": "" + }, + "private-data-source-connections": { + "subtitle": "", + "title": "" + }, + "profile/notifications": { + "title": "" + }, + "profile/password": { + "title": "" + }, + "profile/settings": { + "title": "" + }, + "profiles": { + "title": "" + }, + "public": { + "title": "" + }, + "recently-deleted": { + "subtitle": "", + "title": "" + }, + "recorded-queries": { + "title": "" + }, + "reporting": { + "title": "" + }, + "scenes": { + "title": "" + }, + "search": { + "placeholderCommandPalette": "" + }, + "search-dashboards": { + "title": "" + }, + "server-settings": { + "subtitle": "", + "title": "" + }, + "service-accounts": { + "subtitle": "", + "title": "" + }, + "setup-guide": { + "title": "" + }, + "shared-dashboard": { + "subtitle": "", + "title": "" + }, + "sign-out": { + "title": "" + }, + "slo": { + "title": "" + }, + "snapshots": { + "subtitle": "", + "title": "" + }, + "starred": { + "title": "" + }, + "starred-empty": { + "title": "" + }, + "statistics-and-licensing": { + "title": "" + }, + "storage": { + "subtitle": "", + "title": "" + }, + "support-bundles": { + "subtitle": "", + "title": "" + }, + "synthetics": { + "title": "" + }, + "teams": { + "subtitle": "", + "title": "" + }, + "testing-and-synthetics": { + "subtitle": "", + "title": "" + }, + "upgrading": { + "title": "" + }, + "users": { + "subtitle": "", + "title": "" + } + }, + "navigation": { + "invite-user": { + "invite-button": "", + "invite-tooltip": "" + }, + "item": { + "add-bookmark": "", + "remove-bookmark": "" + }, + "kiosk": { + "tv-alert": "" + }, + "megamenu": { + "close": "", + "dock": "", + "list-label": "", + "open": "", + "undock": "" + }, + "rss-button": "" + }, + "news": { + "drawer": { + "close": "" + }, + "title": "" + }, + "notifications": { + "empty-state": { + "description": "", + "title": "" + }, + "starred-dashboard": "", + "unstarred-dashboard": "" + }, + "oauth": { + "form": { + "server-discovery-action-button": "", + "server-discovery-modal-close": "", + "server-discovery-modal-loading": "", + "server-discovery-modal-submit": "" + }, + "login": { + "error": "" + } + }, + "panel": { + "header-menu": { + "copy": "", + "create-library-panel": "", + "duplicate": "", + "edit": "", + "explore": "", + "get-help": "", + "hide-legend": "", + "inspect": "", + "inspect-data": "", + "inspect-json": "", + "more": "", + "new-alert-rule": "", + "query": "", + "remove": "", + "replace-library-panel": "", + "share": "", + "show-legend": "", + "unlink-library-panel": "", + "view": "" + } + }, + "panel-search": { + "no-matches": "", + "unsupported-layout": "" + }, + "panel-type-filter": { + "clear-button": "" + }, + "playlist-edit": { + "error-prefix": "", + "form": { + "add-tag-label": "", + "add-tag-placeholder": "", + "add-title-label": "", + "cancel": "", + "heading": "", + "interval-label": "", + "interval-placeholder": "", + "interval-required": "", + "name-label": "", + "name-placeholder": "", + "name-required": "", + "save": "", + "table-delete": "", + "table-drag": "", + "table-empty": "", + "table-heading": "" + }, + "sub-title": "", + "title": "" + }, + "playlist-page": { + "card": { + "delete": "", + "edit": "", + "start": "", + "tooltip": "" + }, + "create-button": { + "title": "" + }, + "delete-modal": { + "body": "", + "confirm-text": "" + }, + "empty": { + "button": "", + "pro-tip": "", + "title": "" + } + }, + "playlists": { + "empty-state": { + "message": "" + } + }, + "plugins": { + "catalog": { + "no-updates-available": "", + "update-all": { + "all-plugins-updated": "", + "available-header": "", + "button": "", + "cloud-update-message": "", + "error": "", + "error-status-text": "", + "header": "", + "installed-header": "", + "modal-confirmation": "", + "modal-dismiss": "", + "modal-in-progress": "", + "modal-title": "", + "name-header": "", + "update-header": "", + "update-status-text": "" + }, + "versions": { + "confirmation-text-1": "", + "confirmation-text-2": "", + "downgrade-confirm": "", + "downgrade-title": "" + } + }, + "details": { + "connections-tab": { + "description": "" + }, + "labels": { + "contactGrafanaLabs": "", + "customLinks": "", + "customLinksTooltip": "", + "dependencies": "", + "documentation": "", + "downloads": "", + "from": "", + "installedVersion": "", + "lastCommitDate": "", + "latestVersion": "", + "license": "", + "raiseAnIssue": "", + "reportAbuse": "", + "reportAbuseTooltip": "", + "repository": "", + "signature": "", + "status": "", + "updatedAt": "" + }, + "modal": { + "cancel": "", + "copyEmail": "", + "description": "", + "node": "", + "title": "" + } + }, + "empty-state": { + "message": "" + }, + "filter": { + "disabled": "", + "sort": "", + "sort-list": "", + "state": "" + }, + "plugin-help": { + "error": "", + "not-found": "" + } + }, + "profile": { + "change-password": { + "cancel-button": "", + "cannot-change-password-message": "", + "change-password-button": "", + "confirm-password-label": "", + "confirm-password-required": "", + "ldap-auth-proxy-message": "", + "new-password-label": "", + "new-password-required": "", + "new-password-same-as-old": "", + "old-password-label": "", + "old-password-required": "", + "passwords-must-match": "", + "strong-password-validation-register": "" + } + }, + "public-dashboard": { + "acknowledgment-checkboxes": { + "ack-title": "", + "data-src-ack-desc": "", + "data-src-ack-tooltip": "", + "public-ack-desc": "", + "public-ack-tooltip": "", + "usage-ack-desc": "", + "usage-ack-desc-tooltip": "" + }, + "config": { + "can-view-dashboard-radio-button-label": "", + "copy-button": "", + "dashboard-url-field-label": "", + "email-share-type-option-label": "", + "pause-sharing-dashboard-label": "", + "public-share-type-option-label": "", + "revoke-public-URL-button": "", + "revoke-public-URL-button-title": "", + "settings-title": "" + }, + "configuration": { + "display-annotations-description": "", + "display-annotations-label": "", + "enable-time-range-description": "", + "enable-time-range-label": "", + "settings-label": "", + "success-pause": "", + "success-resume": "", + "success-update": "", + "success-update-old": "", + "time-range-label": "", + "time-range-tooltip": "" + }, + "create-page": { + "generate-public-url-button": "", + "unsupported-features-desc": "", + "welcome-title": "" + }, + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "email-sharing": { + "accept-button": "", + "alert-text": "", + "bill-ack": "", + "cancel-button": "", + "input-invalid-email-text": "", + "input-required-email-text": "", + "invite-button": "", + "invite-field-desc": "", + "invite-field-label": "", + "learn-more-button": "", + "recipient-email-placeholder": "", + "recipient-invalid-email-text": "", + "recipient-invitation-button": "", + "recipient-invitation-description": "", + "recipient-invitation-tooltip": "", + "recipient-list-description": "", + "recipient-list-title": "", + "recipient-required-email-text": "", + "resend-button": "", + "resend-button-title": "", + "resend-invite-label": "", + "revoke-access-label": "", + "revoke-button": "", + "revoke-button-title": "", + "success-creation": "", + "success-share-type-change": "" + }, + "modal-alerts": { + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "save-dashboard-changes-alert-title": "", + "unsupport-data-source-alert-readmore-link": "", + "unsupported-data-source-alert-desc": "", + "unsupported-data-source-alert-title": "", + "unsupported-template-variable-alert-desc": "", + "unsupported-template-variable-alert-title": "" + }, + "public-sharing": { + "accept-button": "", + "alert-text": "", + "cancel-button": "", + "learn-more-button": "", + "public-ack": "", + "success-creation": "", + "success-share-type-change": "" + }, + "settings-bar-header": { + "collapse-settings-tooltip": "", + "expand-settings-tooltip": "" + }, + "settings-configuration": { + "default-time-range-label": "", + "default-time-range-label-desc": "", + "show-annotations-label": "", + "show-annotations-label-desc": "", + "time-range-picker-label": "", + "time-range-picker-label-desc": "" + }, + "settings-summary": { + "annotations-hide-text": "", + "annotations-show-text": "", + "time-range-picker-disabled-text": "", + "time-range-picker-enabled-text": "", + "time-range-text": "" + }, + "share": { + "success-delete": "", + "success-delete-old": "" + }, + "share-configuration": { + "share-type-label": "" + }, + "share-externally": { + "copy-link-button": "", + "email-share-type-option-description": "", + "email-share-type-option-label": "", + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "pause-access-button": "", + "pause-access-tooltip": "", + "public-share-type-option-description": "", + "public-share-type-option-label": "", + "resume-access-button": "", + "revoke-access-button": "", + "revoke-access-description": "", + "unsupported-data-source-alert-desc": "" + }, + "sharing": { + "success-creation": "" + } + }, + "public-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "public-dashboard-users-access-list": { + "dashboard-modal": { + "external-link": "", + "loading-text": "", + "open-dashboard-list-text": "", + "public-dashboard-link": "", + "public-dashboard-setting": "", + "sharing-setting": "" + }, + "delete-user-modal": { + "delete-user-button-text": "", + "delete-user-cancel-button": "", + "delete-user-revoke-access-button": "", + "revoke-access-title": "", + "revoke-user-access-modal-desc-line1": "", + "revoke-user-access-modal-desc-line2": "" + }, + "delete-user-shared-dashboards-modal": { + "revoke-user-access-modal-desc-line2": "" + }, + "modal": { + "dashboard-modal-title": "", + "shared-dashboard-modal-title": "" + }, + "table-body": { + "dashboard-count_one": "", + "dashboard-count_other": "" + }, + "table-header": { + "activated-label": "", + "activated-tooltip": "", + "email-label": "", + "last-active-label": "", + "origin-label": "", + "role-label": "" + } + }, + "query-operation": { + "header": { + "collapse-row": "", + "datasource-help": "", + "drag-and-drop": "", + "duplicate-query": "", + "expand-row": "", + "hide-response": "", + "remove-query": "", + "show-response": "", + "toggle-edit-mode": "" + }, + "query-editor-not-exported": "" + }, + "recently-deleted": { + "buttons": { + "delete": "", + "restore": "" + }, + "page": { + "no-deleted-dashboards": "", + "no-deleted-dashboards-text": "", + "no-search-result": "" + }, + "permanently-delete-modal": { + "confirm-text": "", + "delete-button": "", + "delete-loading": "", + "title": "", + "text_one": "", + "text_other": "" + }, + "restore-modal": { + "restore-button": "", + "restore-loading": "", + "title": "", + "folder-picker-text_one": "", + "folder-picker-text_other": "", + "text_one": "", + "text_other": "" + } + }, + "recentlyDeleted": { + "filter": { + "placeholder": "" + } + }, + "reduce": { + "strictMode": { + "description": "", + "title": "" + } + }, + "refresh-picker": { + "aria-label": { + "choose-interval": "", + "duration-selected": "" + }, + "auto-option": { + "aria-label": "", + "label": "" + }, + "live-option": { + "aria-label": "", + "label": "" + }, + "off-option": { + "aria-label": "", + "label": "" + }, + "tooltip": { + "interval-selected": "", + "turned-off": "" + } + }, + "return-to-previous": { + "button": { + "label": "" + }, + "dismissable-button": "" + }, + "role-picker": { + "built-in": { + "basic-roles": "" + }, + "input": { + "no-roles": "" + }, + "menu": { + "clear-button": "", + "tooltip": "" + }, + "sub-menu": { + "clear-button": "" + }, + "title": { + "description": "" + } + }, + "role-picker-drawer": { + "basic-roles": { + "label": "" + } + }, + "route-error": { + "description": "", + "reload-button": "", + "title": "" + }, + "save-dashboards": { + "message-length": { + "info": "", + "title": "" + }, + "name-exists": { + "message-info": "", + "message-suggestion": "", + "title": "" + } + }, + "scopes": { + "dashboards": { + "collapse": "", + "expand": "", + "loading": "", + "noResultsForFilter": "", + "noResultsForFilterClear": "", + "noResultsForScopes": "", + "noResultsNoScopes": "", + "search": "", + "toggle": { + "collapse": "", + "disabled": "", + "expand": "" + } + }, + "selector": { + "apply": "", + "cancel": "", + "input": { + "placeholder": "", + "removeAll": "" + }, + "title": "" + }, + "tree": { + "collapse": "", + "expand": "", + "headline": { + "noResults": "", + "recommended": "", + "results": "" + }, + "search": "" + } + }, + "search": { + "actions": { + "include-panels": "", + "remove-datasource-filter": "", + "sort-placeholder": "", + "starred": "", + "view-as-folders": "", + "view-as-list": "" + }, + "dashboard-actions": { + "import": "", + "new": "", + "new-dashboard": "", + "new-folder": "" + }, + "results-table": { + "datasource-header": "", + "deleted-less-than-1-min": "", + "deleted-remaining-header": "", + "location-header": "", + "name-header": "", + "tags-header": "", + "type-dashboard": "", + "type-folder": "", + "type-header": "" + }, + "search-input": { + "include-panels-placeholder": "", + "placeholder": "" + } + }, + "select": { + "select-menu": { + "selected-count": "" + } + }, + "service-account-create-page": { + "create": { + "button": "" + }, + "name": { + "label": "", + "required-error": "" + }, + "page-nav": { + "label": "" + }, + "role": { + "label": "" + } + }, + "service-accounts": { + "empty-state": { + "button-title": "", + "message": "", + "more-info": "", + "title": "" + } + }, + "share-dashboard": { + "menu": { + "export-json-title": "", + "share-externally-title": "", + "share-internally-title": "", + "share-snapshot-title": "" + }, + "share-button": "", + "share-button-tooltip": "" + }, + "share-drawer": { + "confirm-action": { + "back-arrow-button": "", + "cancel-button": "" + } + }, + "share-modal": { + "dashboard": { + "title": "" + }, + "embed": { + "copy": "", + "html": "", + "html-description": "", + "info": "", + "time-range": "" + }, + "export": { + "back-button": "", + "cancel-button": "", + "info-text": "", + "loading": "", + "save-button": "", + "share-externally-label": "", + "view-button": "" + }, + "library": { + "info": "" + }, + "link": { + "copy-link-button": "", + "info-text": "", + "link-url": "", + "render-alert": "", + "render-instructions": "", + "rendered-image": "", + "save-alert": "", + "save-dashboard": "", + "shorten-url": "", + "time-range-description": "", + "time-range-label": "" + }, + "panel": { + "title": "" + }, + "snapshot": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "deleted-message": "", + "expire": "", + "expire-day": "", + "expire-hour": "", + "expire-never": "", + "expire-week": "", + "info-text-1": "", + "info-text-2": "", + "local-button": "", + "mistake-message": "", + "name": "", + "timeout": "", + "timeout-description": "", + "url-label": "" + }, + "tab-title": { + "embed": "", + "export": "", + "library-panel": "", + "link": "", + "panel-embed": "", + "public-dashboard": "", + "public-dashboard-title": "", + "snapshot": "" + }, + "theme-picker": { + "current": "", + "dark": "", + "field-name": "", + "light": "" + }, + "view-json": { + "copy-button": "" + } + }, + "share-panel": { + "drawer": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "" + }, + "menu": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "", + "share-snapshot-title": "" + }, + "new-library-panel": { + "cancel-button": "", + "create-button": "" + } + }, + "share-panel-image": { + "preview": { + "title": "" + }, + "settings": { + "height-label": "", + "height-min": "", + "height-placeholder": "", + "height-required": "", + "max-warning": "", + "scale-factor-label": "", + "scale-factor-min": "", + "scale-factor-placeholder": "", + "scale-factor-required": "", + "title": "", + "width-label": "", + "width-min": "", + "width-placeholder": "", + "width-required": "" + } + }, + "share-playlist": { + "checkbox-description": "", + "checkbox-label": "", + "copy-link-button": "", + "link-url-label": "", + "mode": "", + "mode-kiosk": "", + "mode-normal": "", + "title": "" + }, + "shared": { + "preferences": { + "theme": { + "dark-label": "", + "light-label": "", + "system-label": "" + } + } + }, + "shared-dashboard": { + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "fields": { + "timezone-label": "" + } + }, + "shared-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "shared-preferences": { + "fields": { + "home-dashboard-label": "", + "home-dashboard-placeholder": "", + "locale-label": "", + "locale-placeholder": "", + "theme-description": "", + "theme-label": "", + "week-start-label": "" + }, + "theme": { + "default-label": "" + }, + "title": "" + }, + "sign-up": { + "back-button": "", + "submit-button": "", + "verify": { + "back-button": "", + "complete-button": "", + "header": "", + "info": "", + "send-button": "" + } + }, + "silences": { + "empty-state": { + "button-title": "", + "title": "" + }, + "table": { + "add-silence-button": "", + "edit-button": "", + "expired-silences": "", + "no-matching-silences": "", + "noConfig": "", + "recreate-button": "", + "unsilence-button": "" + } + }, + "silences-table": { + "header": { + "alert-name": "", + "state": "" + } + }, + "snapshot": { + "empty-state": { + "message": "", + "more-info": "" + }, + "external-badge": "", + "name-column-header": "", + "share": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "delete-description": "", + "delete-permission-tooltip": "", + "delete-title": "", + "deleted-alert": "", + "expiration-label": "", + "info-alert": "", + "learn-more-button": "", + "local-button": "", + "name-label": "", + "new-snapshot-button": "", + "success-creation": "", + "success-delete": "", + "view-all-button": "" + }, + "share-panel": { + "info-alert": "" + }, + "url-column-header": "", + "view-button": "" + }, + "table": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "" + } + }, + "tag-filter": { + "clear-button": "", + "loading": "", + "no-tags": "", + "placeholder": "" + }, + "teams": { + "empty-state": { + "button-title": "", + "message": "", + "pro-tip": "", + "title": "" + } + }, + "theme-preview": { + "breadcrumbs": { + "dashboards": "", + "home": "" + }, + "panel": { + "form-label": "", + "title": "" + } + }, + "time-picker": { + "absolute": { + "recent-title": "", + "title": "" + }, + "calendar": { + "apply-button": "", + "cancel-button": "", + "close": "", + "next-month": "", + "previous-month": "", + "select-time": "" + }, + "content": { + "empty-recent-list-docs": "", + "empty-recent-list-info": "", + "filter-placeholder": "" + }, + "copy-paste": { + "copy-success-message": "", + "default-error-message": "", + "default-error-title": "", + "tooltip-copy": "", + "tooltip-paste": "" + }, + "footer": { + "change-settings-button": "", + "fiscal-year-option": "", + "fiscal-year-start": "", + "time-zone-option": "", + "time-zone-selection": "" + }, + "range-content": { + "apply-button": "", + "default-error": "", + "fiscal-year": "", + "from-input": "", + "open-input-calendar": "", + "range-error": "", + "to-input": "" + }, + "range-picker": { + "backwards-time-aria-label": "", + "current-time-selected": "", + "forwards-time-aria-label": "", + "to": "", + "zoom-out-button": "", + "zoom-out-tooltip": "" + }, + "time-range": { + "apply": "", + "aria-role": "", + "default-title": "", + "example": "", + "example-details": "", + "example-title": "", + "from-label": "", + "from-to": "", + "more-info": "", + "specify": "", + "submit-button-label": "", + "supported-formats": "", + "to-label": "" + }, + "zone": { + "select-aria-label": "", + "select-search-input": "" + } + }, + "trails": { + "bookmarks": { + "or-view-bookmarks": "" + }, + "card": { + "date-created": "" + }, + "home": { + "learn-more": "", + "lets-start": "", + "start-your-metrics-exploration": "", + "subtitle": "" + }, + "metric-select": { + "filter-by": "", + "native-histogram": "", + "new-badge": "", + "otel-switch": "" + }, + "native-histogram-banner": { + "ch-heatmap": "", + "ch-histogram": "", + "click-histogram": "", + "hide-examples": "", + "learn-more": "", + "metric-examples": "", + "nh-heatmap": "", + "nh-histogram": "", + "now": "", + "previously": "", + "see-examples": "", + "sentence": "" + }, + "recent-metrics": { + "or-view-a-recent-exploration": "" + }, + "settings": { + "always-keep-selected-metric-graph-in-view": "", + "show-previews-of-metric-graphs": "" + } + }, + "transformations": { + "empty": { + "add-transformation-body": "", + "add-transformation-header": "" + } + }, + "upgrade-box": { + "discovery-text": "", + "discovery-text-continued": "", + "get-started": "", + "learn-more": "", + "upgrade-button": "" + }, + "user-orgs": { + "current-org-button": "", + "name-column": "", + "role-column": "", + "select-org-button": "", + "title": "" + }, + "user-profile": { + "fields": { + "email-error": "", + "email-label": "", + "name-error": "", + "name-label": "", + "username-label": "" + }, + "tabs": { + "general": "" + } + }, + "user-session": { + "auth-module-column": "", + "browser-column": "", + "created-at-column": "", + "identity-provider-column": "", + "ip-column": "", + "revoke": "", + "seen-at-column": "" + }, + "user-sessions": { + "loading": "" + }, + "users": { + "empty-state": { + "message": "" + } + }, + "users-access-list": { + "tabs": { + "public-dashboard-users-tab-title": "", + "shared-dashboard-users-tab-title": "" + } + }, + "variable": { + "adhoc": { + "placeholder": "" + }, + "dropdown": { + "placeholder": "" + }, + "picker": { + "link-all": "", + "option-all": "", + "option-selected-values": "", + "option-tooltip": "" + }, + "textbox": { + "placeholder": "" + } + }, + "variables": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + }, + "unknown-table": { + "loading": "", + "no-unknowns": "", + "renamed-or-missing-variables": "", + "variable": "" + } + } +} \ No newline at end of file diff --git a/public/locales/id-ID/grafana.json b/public/locales/id-ID/grafana.json new file mode 100644 index 00000000000..7d47740aff8 --- /dev/null +++ b/public/locales/id-ID/grafana.json @@ -0,0 +1,3996 @@ +{ + "_comment": "", + "access-control": { + "add-permission": { + "role-label": "", + "serviceaccount-label": "", + "team-label": "", + "title": "", + "user-label": "" + }, + "add-permissions": { + "save": "" + }, + "permission-list": { + "permission": "" + }, + "permission-list-item": { + "inherited": "" + }, + "permissions": { + "add-label": "", + "no-permissions": "", + "permissions-change-warning": "", + "role": "", + "serviceaccount": "", + "team": "", + "title": "", + "user": "" + } + }, + "action-editor": { + "modal": { + "cancel-button": "", + "save-button": "" + } + }, + "admin": { + "anon-users": { + "not-found": "" + }, + "edit-org": { + "access-denied": "", + "heading": "", + "update-button": "", + "users-heading": "" + }, + "feature-toggles": { + "sub-title": "" + }, + "get-enterprise": { + "contact-us": "", + "description": "", + "features-heading": "", + "included-description": "", + "included-heading": "", + "service-title": "", + "team-sync-details": "", + "title": "" + }, + "ldap": { + "test-mapping-heading": "", + "test-mapping-run-button": "" + }, + "ldap-permissions": { + "active": "", + "admin": "", + "inactive": "" + }, + "ldap-status": { + "title": "" + }, + "ldap-sync": { + "debug-button": "", + "external-sync-description": "", + "external-sync-label": "", + "next-sync-label": "", + "not-enabled": "", + "sync-button": "", + "title": "" + }, + "ldap-sync-info": { + "title": "" + }, + "ldap-user-groups": { + "no-org-found": "" + }, + "ldap-user-info": { + "no-team": "" + }, + "org-uers": { + "last-seen-never": "" + }, + "org-users": { + "not-editable": "" + }, + "orgs": { + "delete-body": "", + "id-header": "", + "name-header": "", + "new-org-button": "" + }, + "server-settings": { + "alerts-button": "", + "dashboards-button": "", + "data-sources-button": "", + "not-found": "", + "title": "", + "users-button": "" + }, + "settings": { + "info-description": "" + }, + "upgrade-info": { + "title": "" + }, + "user-orgs": { + "add-button": "", + "change-role-button": "", + "external-user-tooltip": "", + "remove-button": "", + "role-not-editable": "", + "title": "" + }, + "user-orgs-modal": { + "add-button": "", + "cancel-button": "" + }, + "user-permissions": { + "change-button": "", + "grafana-admin-key": "", + "grafana-admin-no": "", + "grafana-admin-yes": "", + "title": "" + }, + "user-profile": { + "delete-button": "", + "disable-button": "", + "edit-button": "", + "enable-button": "", + "title": "" + }, + "user-sessions": { + "browser-column": "", + "force-logout-all-button": "", + "force-logout-button": "", + "ip-column": "", + "last-seen-column": "", + "logged-on-column": "", + "title": "" + }, + "users-create": { + "create-button": "" + }, + "users-list": { + "create-button": "" + }, + "users-table": { + "last-seen-never": "", + "no-licensed-roles": "" + } + }, + "alert-labels": { + "button": { + "hide": "", + "show": { + "tooltip": "" + } + } + }, + "alerting": { + "alert": { + "alert-state": "", + "annotations": "", + "evaluation": "", + "evaluation-paused": "", + "evaluation-paused-description": "", + "last-evaluated": "", + "last-evaluation-duration": "", + "last-updated-at": "", + "last-updated-by": "", + "no-annotations": "", + "pending-period": "", + "rule": "", + "rule-identifier": "", + "rule-type": "", + "state-error-timeout": "", + "state-no-data": "", + "target-datasource-uid": "" + }, + "alert-recording-rule-form": { + "evaluation-behaviour": { + "description": { + "text": "" + } + } + }, + "alert-rules": { + "firing-for": "", + "next-evaluation": "", + "next-evaluation-in": "", + "rule-definition": "" + }, + "alertform": { + "labels": { + "alerting": "", + "recording": "" + } + }, + "alertVersionHistory": { + "alerting": "", + "alerting-change-description": "", + "annotations": "", + "compare": "", + "compare-with-latest": "", + "compareVersions": "", + "comparing-versions": "", + "condition": "", + "contactPointRouting": "", + "description": "", + "errorloading": "", + "execErrorState": "", + "intervalSeconds": "", + "labels": "", + "latest": "", + "name": "", + "namespace_uid": "", + "noDataState": "", + "noVersionsFound": "", + "paused": "", + "pendingPeriod": "", + "provisioning": "", + "provisioning-change-description": "", + "queryAndAlertCondition": "", + "restore": "", + "restore-manually": "", + "restore-modal": { + "body": "", + "confirm": "", + "error": "", + "summary": "", + "title": "" + }, + "restore-version": "", + "rule_group": "", + "unknown": "", + "unknown-change-description": "", + "user-id": "", + "warning-restore-manually": "", + "warning-restore-manually-title": "" + }, + "annotations": { + "description": "", + "title": "" + }, + "central-alert-history": { + "details": { + "error": "", + "header": { + "alert-rule": "", + "instance": "", + "state": "", + "timestamp": "" + }, + "loading": "", + "no-recognized-state": "", + "no-values": "", + "not-found": "", + "number-transitions": "", + "state": { + "alerting": "", + "error": "", + "no-data": "", + "normal": "", + "pending": "" + }, + "state-transitions": "", + "unknown-event-state": "", + "unknown-rule": "", + "value-in-transition": "" + }, + "error": "", + "filter": { + "clear": "", + "info": { + "label1": "", + "label2": "", + "label3": "", + "label4": "" + } + }, + "filterBy": "", + "too-many-events": { + "text": "", + "title": "" + } + }, + "common": { + "cancel": "", + "clear-filters": "", + "delete": "", + "edit": "", + "export": "", + "export-all": "", + "loading": "", + "search-by-matchers": "", + "titles": { + "notification-templates": "" + }, + "view": "" + }, + "contact-points": { + "create": "", + "custom-template-value": "", + "delete-reasons": { + "heading": "", + "no-permissions": "", + "policies": "", + "provisioned": "", + "rules": "" + }, + "delivered-to": "", + "delivery-duration": "", + "empty-state": { + "title": "" + }, + "key-value-map": { + "add": "", + "confirm-add": "" + }, + "last-delivery-attempt": "", + "last-delivery-failed": "", + "no-contact-points-found": "", + "no-delivery-attempts": "", + "no-integrations": "", + "only-firing": "", + "receiver-summary": { + "jira": "" + }, + "telegram": { + "parse-mode-warning-body": "", + "parse-mode-warning-title": "" + }, + "used-by_other": "", + "used-by-rules_other": "" + }, + "contactPointFilter": { + "label": "" + }, + "copy-to-clipboard": "", + "dag": { + "missing-reference": "", + "self-reference": "" + }, + "export": { + "subtitle": { + "formats": "", + "one-format": "" + } + }, + "folderAndGroup": { + "evaluation": { + "modal": { + "text": { + "alerting": "", + "recording": "" + } + } + } + }, + "group-actions": { + "actions-trigger": "", + "delete": "", + "edit": "", + "export": "", + "reorder": "" + }, + "list-view": { + "empty": { + "new-alert-rule": "", + "new-recording-rule": "", + "provisioning": "" + }, + "section": { + "dataSourceManaged": { + "title": "" + }, + "grafanaManaged": { + "export-new-rule": "", + "export-rules": "", + "loading": "", + "new-recording-rule": "", + "title": "" + } + } + }, + "manage-permissions": { + "button": "", + "title": "" + }, + "mute_timings": { + "error-loading": { + "description": "", + "title": "" + } + }, + "mute-timings": { + "add-mute-timing": "", + "description": "", + "save": "", + "saving": "" + }, + "notification-preview": { + "alertmanager": "", + "error": "", + "initialized": "", + "preview-routing": "", + "title": "", + "uninitialized": "" + }, + "notification-templates": { + "duplicate": { + "subTitle": "", + "title": "" + }, + "edit": { + "subTitle": "", + "title": "" + }, + "new": { + "subTitle": "", + "title": "" + } + }, + "policies": { + "default-policy": { + "description": "", + "title": "", + "update": "" + }, + "delete": { + "confirm": "", + "warning-1": "", + "warning-2": "" + }, + "filter-description": "", + "generated-policies": "", + "matchers": "", + "metadata": { + "active-time": "", + "delivered-to": "", + "grouped-by": "", + "grouping": { + "none": "", + "single-group": "" + }, + "inherited": "", + "mute-time": "", + "timingOptions": { + "groupInterval": { + "description": "", + "label": "" + }, + "groupWait": { + "description": "", + "label": "" + }, + "repeatInterval": { + "description": "", + "label": "" + } + }, + "n-instances_other": "" + }, + "new-child": "", + "new-policy": "", + "no-matchers": "", + "reload-policies": "", + "save-policy": "", + "update": { + "please-wait": "", + "update-policy": "", + "updating": "" + }, + "update-errors": { + "conflict": "", + "error-code": "", + "fallback": "", + "suffix": "", + "title": "" + }, + "n-more-policies_other": "" + }, + "provisioning": { + "badge-tooltip-provenance": "", + "badge-tooltip-standard": "" + }, + "queryAndExpressionsStep": { + "disableAdvancedOptions": { + "text": "" + }, + "preview": "", + "previewCondition": "" + }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, + "rule-form": { + "evaluation": { + "evaluation-group-and-interval": "", + "group": { + "cancel": "", + "create": "", + "interval": "" + }, + "group-name": "", + "group-text": "", + "new-group": "", + "pause": { + "alerting": "", + "recording": "" + }, + "select-folder-before": "" + }, + "evaluation-behaviour": { + "description": { + "text": "" + }, + "info-help": { + "text": "" + }, + "pending-period": "" + }, + "evaluation-behaviour-description1": "", + "evaluation-behaviour-description2": "", + "evaluation-behaviour-description3": "", + "evaluation-behaviour-for": { + "error-parsing": "", + "validation": "" + }, + "folder": { + "cancel": "", + "create": "", + "create-folder": "", + "creating-new-folder": "", + "label": "", + "name": "", + "new-folder": "", + "new-folder-or": "" + }, + "folder-and-labels": "", + "folders": { + "help-info": "" + }, + "labels": { + "help-info": "" + }, + "pause": { + "label": "" + }, + "threshold": { + "recovery": { + "stop-alerting-above": "", + "stop-alerting-bellow": "", + "stop-alerting-equal": "", + "stop-alerting-inside-range": "", + "stop-alerting-less": "", + "stop-alerting-more": "", + "stop-alerting-not-equal": "", + "stop-alerting-outside-range": "", + "title": "" + } + } + }, + "rule-groups": { + "delete": { + "success": "" + }, + "move": { + "success": "" + }, + "rename": { + "success": "" + }, + "update": { + "success": "" + } + }, + "rule-list": { + "configure-datasource": "", + "ds-error-boundary": { + "description": "", + "title": "" + }, + "filter-view": { + "no-more-results": "", + "no-rules-found": "" + }, + "new-alert-rule": "", + "pagination": { + "next-page": "", + "previous-page": "" + }, + "return-button": { + "title": "" + }, + "rulerrule-loading-error": "" + }, + "rule-state": { + "creating": "", + "deleting": "", + "paused": "", + "recording-rule": "" + }, + "rule-view": { + "query": { + "datasources-na": { + "description": "", + "title": "" + } + } + }, + "rule-viewer": { + "error-loading": "", + "prometheus-consistency-check": { + "alert-message": "", + "alert-title": "" + } + }, + "rules": { + "add-rule": { + "success": "" + }, + "delete-rule": { + "success": "" + }, + "pause-rule": { + "success": "" + }, + "resume-rule": { + "success": "" + }, + "update-rule": { + "success": "" + } + }, + "search": { + "property": { + "data-source": "", + "evaluation-group": "", + "labels": "", + "namespace": "", + "rule-health": "", + "rule-name": "", + "rule-type": "", + "state": "" + }, + "save-query": "" + }, + "silences": { + "affected-instances": "", + "only-firing-instances": "", + "preview-affected-instances": "" + }, + "simpleCondition": { + "alertCondition": "" + }, + "templates": { + "editor": { + "add-example": "", + "auto-complete": "", + "goto-docs": "" + }, + "help": { + "intro": "" + }, + "misconfigured-badge-text": "", + "misconfigured-warning": "", + "misconfigured-warning-details": "" + }, + "threshold": { + "to": "" + } + }, + "annotations": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + } + }, + "api-keys": { + "empty-state": { + "message": "" + } + }, + "app-chrome": { + "skip-content-button": "", + "top-bar": { + "sign-in": "" + } + }, + "app-notification": { + "item": { + "trace-id": "" + } + }, + "bookmarks-page": { + "empty": { + "message": "", + "tip": "" + } + }, + "bouncing-loader": { + "label": "" + }, + "browse-dashboards": { + "action": { + "cancel-button": "", + "cannot-move-folders": "", + "confirmation-text": "", + "delete-button": "", + "delete-modal-invalid-text": "", + "delete-modal-invalid-title": "", + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "delete-modal-title": "", + "deleting": "", + "manage-permissions-button": "", + "move-button": "", + "move-modal-alert": "", + "move-modal-field-label": "", + "move-modal-text": "", + "move-modal-title": "", + "moving": "", + "new-folder-name-required-phrase": "" + }, + "actions": { + "button-to-recently-deleted": "" + }, + "counts": { + "alertRule_other": "", + "dashboard_other": "", + "folder_other": "", + "libraryPanel_other": "", + "total_other": "" + }, + "dashboards-tree": { + "collapse-folder-button": "", + "expand-folder-button": "", + "name-column": "", + "select-all-header-checkbox": "", + "select-checkbox": "", + "tags-column": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "", + "title-folder": "" + }, + "folder-actions-button": { + "delete": "", + "folder-actions": "", + "manage-permissions": "", + "move": "" + }, + "folder-picker": { + "accessible-label": "", + "button-label": "", + "clear-selection": "", + "empty-message": "", + "error-title": "", + "non-folder-item": "", + "search-placeholder": "", + "unknown-error": "" + }, + "hard-delete": { + "success": "" + }, + "manage-folder-nav": { + "alert-rules": "", + "dashboards": "", + "panels": "" + }, + "new-folder-form": { + "cancel-label": "", + "create-label": "", + "name-label": "" + }, + "no-results": { + "clear": "", + "text": "" + }, + "soft-delete": { + "success": "" + } + }, + "clipboard-button": { + "inline-toast": { + "success": "" + } + }, + "combobox": { + "async": { + "error": "" + }, + "clear": { + "title": "" + }, + "custom-value": { + "description": "" + }, + "group": { + "undefined": "" + }, + "options": { + "no-found": "" + } + }, + "command-palette": { + "action": { + "change-theme": "", + "dark-theme": "", + "light-theme": "" + }, + "empty-state": { + "message": "" + }, + "search-box": { + "placeholder": "" + }, + "section": { + "actions": "", + "dashboard-search-results": "", + "folder-search-results": "", + "pages": "", + "preferences": "", + "recent-dashboards": "" + } + }, + "common": { + "apply": "", + "cancel": "", + "clear": "", + "close": "", + "collapse": "", + "edit": "", + "help": "", + "loading": "", + "locale": { + "default": "" + }, + "save": "", + "search": "", + "view": "" + }, + "configuration-tracker": { + "config-card": { + "complete": "" + } + }, + "connections": { + "connect-data": { + "category-header-label": "", + "empty-message": "", + "request-data-source": "", + "roadmap": "" + }, + "search": { + "placeholder": "" + } + }, + "core": { + "versionHistory": { + "comparison": { + "header": { + "hide-json-diff": "", + "show-json-diff": "", + "text": "" + }, + "select": "" + }, + "no-properties-changed": "", + "table": { + "updated": "", + "updatedBy": "", + "version": "" + }, + "view-json-diff": "" + } + }, + "correlations": { + "add-new": "", + "alert": { + "error-message": "", + "title": "" + }, + "basic-info-form": { + "description-description": "", + "description-label": "", + "label-description": "", + "label-label": "", + "label-placeholder": "", + "label-required": "", + "sub-text": "", + "title": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + }, + "list": { + "delete": "", + "label": "", + "loading": "", + "read-only": "", + "source": "", + "target": "" + }, + "navigation-form": { + "add-button": "", + "back-button": "", + "next-button": "", + "save-button": "" + }, + "page-content": "", + "page-heading": "", + "query-editor": { + "control-rules": "", + "data-source-text": "", + "data-source-title": "", + "error-text": "", + "error-title": "", + "loading": "", + "query-description": "", + "query-editor-title": "", + "query-label": "" + }, + "source-form": { + "control-required": "", + "description": "", + "description-external-pre": "", + "description-query-pre": "", + "external-title": "", + "heading-external": "", + "heading-query": "", + "query-title": "", + "results-description": "", + "results-label": "", + "results-required": "", + "source-description": "", + "source-label": "", + "sub-text": "" + }, + "sub-title": "", + "target-form": { + "control-rules": "", + "sub-text": "", + "target-description-external": "", + "target-description-query": "", + "target-label": "", + "target-type-description": "", + "title": "", + "type-label": "" + }, + "trans-details": { + "logfmt-description": "", + "logfmt-label": "", + "regex-description": "", + "regex-expression": "", + "regex-label": "", + "regex-map-values": "" + }, + "transform": { + "add-button": "", + "heading": "", + "no-transform": "" + }, + "transform-row": { + "expression-label": "", + "expression-required": "", + "expression-tooltip": "", + "field-input": "", + "field-label": "", + "field-tooltip": "", + "map-value-label": "", + "map-value-tooltip": "", + "remove-button": "", + "remove-tooltip": "", + "transform-required": "", + "type-label": "", + "type-tooltip": "" + } + }, + "dashboard": { + "add-menu": { + "import": "", + "paste-panel": "", + "row": "", + "visualization": "" + }, + "alert-rules-drawer": { + "redirect-link": "", + "subtitle": "" + }, + "default-layout": { + "description": "", + "item-options": { + "repeat": { + "direction": { + "horizontal": "", + "title": "", + "vertical": "" + }, + "max": "", + "title": "", + "variable": { + "description": "", + "title": "" + } + } + }, + "name": "", + "row-actions": { + "delete": "", + "modal": { + "alt-action": "", + "text": "", + "title": "" + } + }, + "row-options": { + "button": { + "label": "" + }, + "form": { + "cancel": "", + "repeat-for": { + "label": "", + "learn-more": "", + "warning": { + "text": "" + } + }, + "title": "", + "update": "" + }, + "modal": { + "title": "" + }, + "repeat": { + "title": "", + "variable": { + "title": "" + } + }, + "title": "" + } + }, + "edit-pane": { + "elements": { + "dashboard": "", + "objects": "", + "panel": "", + "panels": "", + "row": "", + "rows": "", + "tab": "", + "tabs": "" + }, + "open": "", + "row": { + "header": { + "hide": "", + "title": "" + } + } + }, + "editpane": { + "add": "", + "configure": "", + "outline": "" + }, + "empty": { + "add-library-panel-body": "", + "add-library-panel-button": "", + "add-library-panel-header": "", + "add-visualization-body": "", + "add-visualization-button": "", + "add-visualization-header": "", + "import-a-dashboard-body": "", + "import-a-dashboard-header": "", + "import-dashboard-button": "" + }, + "errors": { + "failed-to-load": "" + }, + "inspect": { + "data-tab": "", + "error-tab": "", + "json-tab": "", + "meta-tab": "", + "query-tab": "", + "stats-tab": "", + "subtitle": "", + "title": "" + }, + "inspect-data": { + "data-options": "", + "dataframe-aria-label": "", + "dataframe-label": "", + "download-csv": "", + "download-excel-description": "", + "download-excel-label": "", + "download-logs": "", + "download-service": "", + "download-traces": "", + "excel-header": "", + "formatted": "", + "formatted-data-description": "", + "formatted-data-label": "", + "panel-transforms": "", + "series-to-columns": "", + "transformation": "", + "transformations-description": "", + "transformations-label": "" + }, + "inspect-json": { + "dataframe-description": "", + "dataframe-label": "", + "panel-data-description": "", + "panel-data-label": "", + "panel-json-description": "", + "panel-json-label": "", + "select-source": "", + "unknown": "" + }, + "inspect-meta": { + "no-inspector": "" + }, + "inspect-stats": { + "data-title": "", + "data-traceids": "", + "processing-time": "", + "queries": "", + "request-time": "", + "rows": "", + "table-title": "" + }, + "layout": { + "common": { + "copy": "", + "copy-or-duplicate": "", + "delete": "", + "duplicate": "", + "layout": "" + } + }, + "options": { + "description": "", + "title-option": "" + }, + "outline": { + "tree": { + "item": { + "collapse": "", + "empty": "", + "expand": "" + } + } + }, + "panel-edit": { + "alerting-tab": { + "dashboard-not-saved": "", + "no-rules": "" + } + }, + "responsive-layout": { + "description": "", + "item-options": { + "hide-no-data": "", + "repeat": { + "variable": { + "description": "", + "title": "" + } + }, + "title": "" + }, + "name": "", + "options": { + "columns": "", + "fixed": "", + "min": "", + "one-column": "", + "rows": "", + "three-columns": "", + "two-columns": "" + } + }, + "rows-layout": { + "description": "", + "name": "", + "option": { + "height": "", + "hide-header": "", + "repeat": "", + "title": "" + }, + "options": { + "height-expand": "", + "height-min": "" + }, + "row": { + "collapse": "", + "expand": "", + "menu": { + "add": "", + "add-panel": "", + "add-row-above": "", + "add-row-below": "", + "move-down": "", + "move-row": "", + "move-up": "" + }, + "new": "", + "repeat": { + "learn-more": "", + "warning": "" + } + }, + "row-options": { + "title-option": "" + } + }, + "tabs-layout": { + "description": "", + "menu": { + "move-tab": "" + }, + "name": "", + "tab": { + "menu": { + "add": "", + "add-panel": "", + "add-tab-above": "", + "add-tab-after": "", + "add-tab-before": "", + "move-left": "", + "move-right": "" + }, + "new": "" + }, + "tab-options": { + "title-option": "" + } + }, + "toolbar": { + "add": "", + "add-panel": "", + "add-panel-description": "", + "add-panel-lib": "", + "add-row": "", + "add-tab": "", + "alert-rules": "", + "back-to-dashboard": "", + "dashboard-settings": { + "label": "", + "tooltip": "" + }, + "discard-library-panel-changes": "", + "discard-panel": "", + "discard-panel-new": "", + "edit": { + "label": "", + "tooltip": "" + }, + "edit-dashboard-v2-schema": "", + "enter-edit-mode": { + "label": "", + "tooltip": "" + }, + "exit-edit-mode": { + "label": "", + "tooltip": "" + }, + "libray-panel-description": "", + "mark-favorite": "", + "more-save-options": "", + "open-original": "", + "playlist-next": "", + "playlist-previous": "", + "playlist-stop": "", + "public-dashboard": "", + "refresh": "", + "row-description": "", + "save": "", + "save-dashboard": { + "label": "", + "tooltip": "" + }, + "save-dashboard-copy": { + "label": "", + "tooltip": "" + }, + "save-dashboard-short": "", + "save-library-panel": "", + "settings": "", + "share": { + "label": "", + "tooltip": "" + }, + "share-button": "", + "show-hidden-elements": "", + "switch-old-dashboard": "", + "tabs-description": "", + "unlink-library-panel": "", + "unmark-favorite": "" + }, + "validation": { + "invalid-dashboard-id": "", + "invalid-json": "", + "tags-expected-array": "", + "tags-expected-strings": "" + }, + "viz-panel": { + "options": { + "description": "", + "open-edit": "", + "plugin-type-image": "", + "title-option": "", + "transparent-background": "" + } + } + }, + "dashboard-import": { + "file-dropzone": { + "primary-text": "", + "secondary-text": "" + }, + "form-actions": { + "cancel": "", + "load": "" + }, + "gcom-field": { + "label": "", + "load-button": "", + "placeholder": "", + "validation-required": "" + }, + "json-field": { + "label": "", + "validation-required": "" + } + }, + "dashboard-links": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "title": "" + } + }, + "dashboard-settings": { + "annotations": { + "title": "" + }, + "dashboard-delete-button": "", + "delete-modal": { + "confirmation-text": "", + "delete-button": "", + "title": "" + }, + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "general": { + "auto-refresh-description": "", + "auto-refresh-label": "", + "description-label": "", + "editable-description": "", + "editable-label": "", + "folder-label": "", + "panel-options-graph-tooltip-description": "", + "panel-options-graph-tooltip-label": "", + "panel-options-label": "", + "panels-preload-description": "", + "panels-preload-label": "", + "tags-label": "", + "title": "", + "title-label": "" + }, + "json-editor": { + "save-button": "", + "subtitle": "", + "title": "" + }, + "links": { + "title": "" + }, + "permissions": { + "title": "" + }, + "provisioned-delete-modal": { + "confirm-button": "", + "text-1": "", + "text-2": "", + "text-3": "", + "text-link": "", + "title": "" + }, + "settings": { + "title": "" + }, + "time-picker": { + "hide-time-picker": "", + "now-delay-description": "", + "now-delay-label": "", + "refresh-live-dashboards-description": "", + "refresh-live-dashboards-label": "", + "time-options-label": "", + "time-zone-label": "", + "week-start-label": "" + }, + "time-regions": { + "advanced-description-cron": "", + "advanced-description-rest": "", + "advanced-description-use": "", + "advanced-label": "" + }, + "variables": { + "title": "" + }, + "versions": { + "title": "" + } + }, + "dashboards": { + "panel-edit": { + "angular-deprecation-button-open-panel-json": "", + "angular-deprecation-description": "", + "angular-deprecation-heading": "" + }, + "panel-queries": { + "add-query-from-library": "" + }, + "settings": { + "variables": { + "dependencies": { + "button": "", + "title": "" + } + } + } + }, + "data-source-list": { + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + } + }, + "data-source-picker": { + "add-new-data-source": "", + "built-in-list": { + "description-dashboard": "", + "description-grafana": "", + "description-mixed": "" + }, + "list": { + "no-data-source-message": "" + }, + "modal": { + "configure-new-data-source": "", + "input-placeholder": "", + "title": "" + }, + "open-advanced-button": "" + }, + "data-source-testing-status-page": { + "error-more-details-link": "", + "success-more-details-links": "" + }, + "data-sources": { + "datasource-add-button": { + "label": "" + }, + "empty-state": { + "message": "" + } + }, + "embed": { + "share": { + "time-range-description": "", + "time-range-label": "" + } + }, + "empty-list-cta": { + "pro-tip": "" + }, + "entity-not-found": { + "description": "" + }, + "errors": { + "dashboard-settings": { + "annotations": { + "datasource": "" + } + } + }, + "explore": { + "add-to-dashboard": "", + "drilldownInfo": { + "action": "", + "description": "", + "title": "" + }, + "logs": { + "logs-volume": { + "add-filters": "", + "decrease-timerange": "", + "much-data": "" + }, + "maximum-pinned-logs": "", + "no-logs-found": "", + "scan-for-older-logs": "", + "stop-scan": "" + }, + "rich-history": { + "close-tooltip": "", + "datasource-a-z": "", + "datasource-z-a": "", + "newest-first": "", + "oldest-first": "", + "query-history": "", + "query-library": "", + "settings": "", + "starred": "" + }, + "rich-history-card": { + "add-comment-form": "", + "add-comment-tooltip": "", + "add-to-library": "", + "cancel": "", + "confirm-delete": "", + "copy-query-tooltip": "", + "copy-shortened-link-tooltip": "", + "datasource-icon-label": "", + "datasource-name-label": "", + "datasource-not-exist": "", + "delete-query-confirmation-title": "", + "delete-query-title": "", + "delete-query-tooltip": "", + "delete-starred-query-confirmation-text": "", + "edit-comment-tooltip": "", + "optional-description": "", + "query-comment-label": "", + "query-text-label": "", + "save-comment": "", + "star-query-tooltip": "", + "unstar-query-tooltip": "", + "update-comment-form": "" + }, + "rich-history-container": { + "loading": "" + }, + "rich-history-notification": { + "query-copied": "", + "query-deleted": "" + }, + "rich-history-queries-tab": { + "displaying-partial-queries": "", + "displaying-queries": "", + "filter-aria-label": "", + "filter-history": "", + "filter-placeholder": "", + "history-local": "", + "loading": "", + "loading-results": "", + "search-placeholder": "", + "showing-queries": "", + "sort-aria-label": "", + "sort-placeholder": "" + }, + "rich-history-settings-tab": { + "alert-info": "", + "change-default-tab": "", + "clear-history-info": "", + "clear-query-history": "", + "clear-query-history-button": "", + "delete-confirm": "", + "delete-confirm-text": "", + "delete-title": "", + "history-time-span": "", + "history-time-span-description": "", + "only-show-active-datasource": "", + "query-history-deleted": "", + "retention-period": { + "1-week": "", + "2-days": "", + "2-weeks": "", + "5-days": "" + } + }, + "rich-history-starred-tab": { + "filter-queries-aria-label": "", + "filter-queries-placeholder": "", + "loading": "", + "loading-results": "", + "local-history-message": "", + "search-queries-placeholder": "", + "showing-queries": "", + "sort-queries-aria-label": "", + "sort-queries-placeholder": "" + }, + "rich-history-utils": { + "a-week-ago": "", + "days-ago": "", + "default-from": "", + "default-to": "", + "today": "", + "two-weeks-ago": "", + "yesterday": "" + }, + "rich-history-utils-notification": { + "saving-failed": "", + "update-failed": "" + }, + "run-query": { + "left-pane": "", + "right-pane": "", + "run-query-button": "", + "switch-datasource-button": "" + }, + "secondary-actions": { + "add-from-query-library": "", + "query-add-button": "", + "query-add-button-aria-label": "", + "query-history-button": "", + "query-history-button-aria-label": "", + "query-inspector-button": "", + "query-inspector-button-aria-label": "" + }, + "table": { + "no-data": "", + "title": "", + "title-with-name": "" + }, + "toolbar": { + "add-to-extensions": "", + "add-to-queryless-extensions": "", + "aria-label": "", + "copy-link": "", + "copy-link-abs-time": "", + "copy-links-absolute-category": "", + "copy-links-normal-category": "", + "copy-shortened-link": "", + "copy-shortened-link-abs-time": "", + "copy-shortened-link-label": "", + "copy-shortened-link-menu": "", + "refresh-picker-cancel": "", + "refresh-picker-run": "", + "split-close": "", + "split-close-tooltip": "", + "split-narrow": "", + "split-title": "", + "split-tooltip": "", + "split-widen": "" + } + }, + "explore-metrics": { + "breakdown": { + "clearFilter": "", + "labelSelect": "", + "missing-otel-labels": "", + "noMatchingValue": "", + "sortBy": "" + }, + "related-logs": { + "LrrDocsLink": "", + "openExploreLogs": "", + "relatedLogsUnavailable": "", + "warnExperimentalFeature": "" + }, + "viewBy": "" + }, + "export": { + "json": { + "cancel-button": "", + "copy-button": "", + "download-button": "", + "download-successful_toast_message": "", + "export-externally-label": "", + "info-text": "", + "title": "" + }, + "menu": { + "export-as-json-label": "", + "export-as-json-tooltip": "" + } + }, + "folder-filter": { + "clear-folder-button": "" + }, + "folder-picker": { + "create-instructions": "", + "loading": "" + }, + "forgot-password": { + "back-button": "", + "change-password": { + "skip-button": "", + "submit-button": "" + }, + "contact-admin": "", + "email-sent": "", + "reset-password-header": "", + "send-email-button": "" + }, + "form-prompt": { + "continue-button": "", + "description": "", + "discard-button": "" + }, + "gen-ai": { + "apply-suggestion": "", + "incomplete-request-error": "", + "send-custom-feedback": "" + }, + "get-enterprise": { + "requires-license": "", + "title": "" + }, + "grafana-ui": { + "action-editor": { + "button": { + "confirm": "", + "confirm-action": "" + }, + "inline": { + "add-action": "", + "edit-action": "" + }, + "modal": { + "action-body": "", + "action-method": "", + "action-query-params": "", + "action-title": "", + "action-title-placeholder": "", + "one-click-description": "" + } + }, + "alert": { + "close-button": "" + }, + "auto-save-field": { + "saved": "", + "saving": "" + }, + "card": { + "option": "" + }, + "cascader": { + "clear-button": "" + }, + "color-picker-popover": { + "palette-tab": "", + "spectrum-tab": "" + }, + "confirm-button": { + "cancel": "" + }, + "confirm-content": { + "placeholder": "" + }, + "data-link-editor": { + "info": "", + "new-tab-label": "", + "title-label": "", + "title-placeholder": "", + "url-label": "" + }, + "data-link-editor-modal": { + "cancel": "", + "one-click-description": "", + "save": "" + }, + "data-link-inline-editor": { + "one-click": "" + }, + "data-links-inline-editor": { + "add-link": "", + "edit-link": "", + "one-click": "", + "one-click-enabled": "", + "title-not-provided": "", + "tooltip-edit": "", + "tooltip-remove": "", + "url-not-provided": "" + }, + "data-source-basic-auth-settings": { + "user-label": "", + "user-placeholder": "" + }, + "data-source-http-proxy-settings": { + "oauth-identity-label": "", + "oauth-identity-tooltip": "", + "skip-tls-verify-label": "", + "ts-client-auth-label": "", + "with-ca-cert-label": "", + "with-ca-cert-tooltip": "" + }, + "data-source-http-settings": { + "access-help": "", + "access-help-details": "", + "access-label": "", + "access-options-browser": "", + "access-options-proxy": "", + "allowed-cookies": "", + "allowed-cookies-tooltip": "", + "auth": "", + "azure-auth-label": "", + "azure-auth-tooltip": "", + "basic-auth": "", + "basic-auth-label": "", + "browser-mode-description": "", + "browser-mode-title": "", + "default-url-access-select": "", + "default-url-tooltip": "", + "direct-url-tooltip": "", + "heading": "", + "proxy-url-tooltip": "", + "server-mode-description": "", + "server-mode-title": "", + "timeout-form-label": "", + "timeout-label": "", + "timeout-tooltip": "", + "url-label": "", + "with-credential-label": "", + "with-credential-tooltip": "" + }, + "data-source-settings": { + "alerting-settings-heading": "", + "alerting-settings-label": "", + "alerting-settings-tooltip": "", + "cert-key-reset": "", + "custom-headers-add": "", + "custom-headers-header": "", + "custom-headers-header-placeholder": "", + "custom-headers-header-remove": "", + "custom-headers-header-value": "", + "custom-headers-title": "", + "secure-socks-heading": "", + "secure-socks-label": "", + "secure-socks-tooltip": "", + "tls-certification-label": "", + "tls-certification-placeholder": "", + "tls-client-certification-label": "", + "tls-client-key-label": "", + "tls-client-key-placeholder": "", + "tls-heading": "", + "tls-server-name-label": "", + "tls-tooltip": "" + }, + "date-time-picker": { + "apply": "", + "calendar-icon-label": "", + "cancel": "", + "next-label": "", + "previous-label": "", + "select-placeholder": "" + }, + "drawer": { + "close": "" + }, + "feature-badge": { + "experimental": "", + "new": "", + "preview": "", + "private-preview": "" + }, + "field-link-list": { + "external-links-heading": "" + }, + "file-dropzone": { + "cancel-upload": "", + "file-too-large": "" + }, + "filter-input": { + "clear": "" + }, + "modal": { + "close-tooltip": "" + }, + "named-colors-palette": { + "text-color-swatch": "", + "transparent-swatch": "" + }, + "page-toolbar": { + "go-back": "", + "search-dashboard-name": "", + "search-links": "", + "search-parent-folder": "" + }, + "pagination": { + "next-page": "", + "previous-page": "" + }, + "secret-form-field": { + "reset": "" + }, + "segment-async": { + "error": "", + "loading": "", + "no-options": "" + }, + "select": { + "default-create-label": "", + "no-options-label": "", + "placeholder": "" + }, + "series-color-picker-popover": { + "y-axis-usage": "" + }, + "spinner": { + "aria-label": "" + }, + "table": { + "copy": "", + "csv-counts": "", + "filter-popup-apply": "", + "filter-popup-cancel": "", + "filter-popup-clear": "", + "filter-popup-heading": "", + "no-values-label": "", + "pagination-summary": "" + }, + "tags-input": { + "add": "" + }, + "user-icon": { + "active-text": "" + }, + "value-pill": { + "remove-button": "" + }, + "viz-legend": { + "right-axis-indicator": "" + }, + "viz-tooltip": { + "actions-confirmation-input-placeholder": "", + "actions-confirmation-label": "", + "actions-confirmation-message": "", + "footer-add-annotation": "", + "footer-click-to-action": "", + "footer-click-to-navigate": "" + } + }, + "graph": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "", + "title": "" + } + }, + "help-modal": { + "column-headers": { + "description": "", + "keys": "" + }, + "shortcuts-category": { + "dashboard": "", + "focused-panel": "", + "global": "", + "time-range": "" + }, + "shortcuts-description": { + "change-theme": "", + "collapse-all-rows": "", + "copy-time-range": "", + "dashboard-settings": "", + "duplicate-panel": "", + "exit-edit/setting-views": "", + "expand-all-rows": "", + "go-to-dashboards": "", + "go-to-explore": "", + "go-to-home-dashboard": "", + "go-to-profile": "", + "make-time-range-permanent": "", + "move-time-range-back": "", + "move-time-range-forward": "", + "open-search": "", + "open-shared-modal": "", + "paste-time-range": "", + "refresh-all-panels": "", + "remove-panel": "", + "save-dashboard": "", + "show-all-shortcuts": "", + "toggle-active-mode": "", + "toggle-all-panel-legends": "", + "toggle-auto-fit": "", + "toggle-exemplars": "", + "toggle-graph-crosshair": "", + "toggle-kiosk": "", + "toggle-panel-edit": "", + "toggle-panel-fullscreen": "", + "toggle-panel-legend": "", + "zoom-out-time-range": "" + }, + "title": "" + }, + "help-wizard": { + "download-snapshot": "", + "github-comment": "", + "support-bundle": "", + "troubleshooting-help": "" + }, + "inspector": { + "query": { + "collapse-all": "", + "copy-to-clipboard": "", + "description": "", + "expand-all": "", + "no-data": "", + "refresh": "" + } + }, + "ldap-drawer": { + "attributes-section": { + "description": "", + "email-label": "", + "label": "", + "member-of-label": "", + "name-label": "", + "surname-label": "", + "username-label": "" + }, + "extra-security-section": { + "client-cert-label": "", + "client-cert-placeholder": "", + "client-cert-value-label": "", + "client-cert-value-placeholder": "", + "client-key-label": "", + "client-key-placeholder": "", + "client-key-value-label": "", + "client-key-value-placeholder": "", + "encryption-provider-base-64": "", + "encryption-provider-description": "", + "encryption-provider-file-path": "", + "encryption-provider-label": "", + "label": "", + "min-tls-version-description": "", + "min-tls-version-label": "", + "root-ca-cert-label": "", + "root-ca-cert-placeholder": "", + "root-ca-cert-value-label": "", + "root-ca-cert-value-placeholder": "", + "start-tls-description": "", + "start-tls-label": "", + "tls-ciphers-label": "", + "tls-ciphers-placeholder": "", + "use-ssl-description": "", + "use-ssl-label": "", + "use-ssl-tooltip": "" + }, + "group-mapping": { + "grafana-admin": { + "description": "", + "label": "" + }, + "group-dn": { + "description": "", + "label": "" + }, + "org-id": { + "description": "", + "label": "" + }, + "org-role": { + "label": "" + }, + "remove": { + "button": "" + } + }, + "group-mapping-section": { + "add": { + "button": "" + }, + "description": "", + "group-search-base-dns-label": "", + "group-search-base-dns-placeholder": "", + "group-search-filter-description": "", + "group-search-filter-label": "", + "group-search-filter-user-attribute-description": "", + "group-search-filter-user-attribute-label": "", + "label": "", + "skip-org-role-sync-description": "", + "skip-org-role-sync-label": "" + }, + "misc-section": { + "allow-sign-up-descrition": "", + "allow-sign-up-label": "", + "label": "", + "port-description": "", + "port-label": "", + "timeout-description": "", + "timeout-label": "" + }, + "title": "" + }, + "ldap-settings-page": { + "advanced-settings-section": { + "edit-button": "", + "subtitle": "", + "title": "" + }, + "alert": { + "discard-success": "", + "error-fetching": "", + "error-saving": "", + "error-validate-form": "", + "feature-flag-disabled": "", + "saved": "" + }, + "bind-dn": { + "description": "", + "label": "", + "placeholder": "" + }, + "bind-password": { + "label": "" + }, + "buttons-section": { + "disable-button": "", + "discard-button": "", + "save-and-enable-button": "", + "save-button": "" + }, + "documentation": "", + "host": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "login-form-alert": { + "description": "", + "title": "" + }, + "search_filter": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "search-base-dns": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "subtitle": "", + "title": "" + }, + "library-panel": { + "add-modal": { + "cancel": "", + "create": "", + "error": "", + "folder": "", + "folder-description": "", + "name": "" + }, + "add-widget": { + "title": "" + }, + "empty-state": { + "message": "", + "more-info": "" + } + }, + "library-panels": { + "empty-state": { + "message": "" + }, + "loading-panel-text": "", + "modal": { + "button-cancel": "", + "button-view-panel1": "", + "button-view-panel2": "", + "panel-not-linked": "", + "select-no-options-message": "", + "select-placeholder": "", + "title": "", + "body_other": "" + }, + "save": { + "error": "", + "success": "" + } + }, + "link": { + "share": { + "config-alert-description": "", + "config-alert-title": "", + "config-description": "", + "copy-link-button": "", + "copy-to-clipboard": "", + "short-url-label": "", + "time-range-description": "", + "time-range-label": "" + }, + "share-panel": { + "config-description": "", + "download-image": "", + "render-image": "", + "render-image-error": "", + "render-image-error-description": "" + } + }, + "lock-icon": "", + "login": { + "divider": { + "connecting-text": "" + }, + "error": { + "blocked": "", + "invalid-user-or-password": "", + "title": "", + "unknown": "" + }, + "forgot-password": "", + "form": { + "confirmation-code": "", + "confirmation-code-label": "", + "confirmation-code-placeholder": "", + "email-label": "", + "email-placeholder": "", + "email-required": "", + "name-label": "", + "name-placeholder": "", + "password-label": "", + "password-placeholder": "", + "password-required": "", + "submit-label": "", + "submit-loading-label": "", + "username-label": "", + "username-placeholder": "", + "username-required": "", + "verify-email-label": "", + "verify-email-loading-label": "" + }, + "layout": { + "update-password": "" + }, + "services": { + "sing-in-with-prefix": "" + }, + "signup": { + "button-label": "", + "new-to-question": "" + } + }, + "logs": { + "infinite-scroll": { + "end-of-range": "", + "load-more": "", + "load-newer": "", + "load-older": "", + "older-logs": "" + }, + "log-details": { + "fields": "", + "links": "", + "log-line": "", + "no-details": "" + }, + "log-line-menu": { + "copy-link": "", + "copy-log": "", + "icon-label": "", + "pin-to-outline": "", + "show-context": "", + "unpin-from-outline": "" + }, + "log-row-message": { + "ellipsis": "", + "more": "", + "see-details": "" + }, + "log-rows": { + "disable-popover": { + "confirm": "", + "message": "", + "title": "" + }, + "disable-popover-message": { + "shortcut": "" + } + }, + "logs-navigation": { + "newer-logs": "", + "older-logs": "", + "scroll-bottom": "", + "scroll-top": "", + "start-of-range": "" + }, + "popover-menu": { + "copy": "", + "disable-menu": "", + "line-contains": "", + "line-contains-not": "" + } + }, + "migrate-to-cloud": { + "build-snapshot": { + "description": "", + "title": "", + "when-complete": "" + }, + "building-snapshot": { + "description": "", + "description-eta": "", + "title": "" + }, + "can-i-move": { + "body": "", + "link-title": "", + "title": "" + }, + "connect-modal": { + "body-cloud-stack": "", + "body-get-started": "", + "body-sign-up": "", + "body-token": "", + "body-token-field": "", + "body-token-field-placeholder": "", + "body-token-instructions": "", + "body-view-stacks": "", + "cancel": "", + "connect": "", + "connecting": "", + "title": "", + "token-error-title": "", + "token-errors": { + "instance-request-error": "", + "instance-unreachable": "", + "migration-disabled": "", + "session-creation-failure": "", + "token-invalid": "", + "token-not-saved": "", + "token-request-error": "", + "token-validation-failure": "" + }, + "token-required-error": "" + }, + "cta": { + "button": "", + "header": "" + }, + "delete-migration-token-confirm": { + "body": "", + "confirm-button": "", + "error-title": "", + "title": "" + }, + "disconnect-modal": { + "body": "", + "cancel": "", + "disconnect": "", + "disconnecting": "", + "error": "", + "title": "" + }, + "get-started": { + "body": "", + "configure-pdc-link": "", + "link-title": "", + "step-1": "", + "step-2": "", + "step-3": "", + "step-4": "", + "step-5": "", + "title": "" + }, + "is-it-secure": { + "body": "", + "link-title": "", + "title": "" + }, + "migrate-to-this-stack": { + "body": "", + "link-title": "", + "title": "" + }, + "migrated-counts": { + "alert_rule_groups": "", + "alert_rules": "", + "contact_points": "", + "dashboards": "", + "datasources": "", + "folders": "", + "library_elements": "", + "mute_timings": "", + "notification_policies": "", + "notification_templates": "", + "plugins": "" + }, + "migration-token": { + "delete-button": "", + "delete-modal-body": "", + "delete-modal-cancel": "", + "delete-modal-confirm": "", + "delete-modal-deleting": "", + "delete-modal-title": "", + "error-body": "", + "error-title": "", + "generate-button": "", + "generate-button-loading": "", + "modal-close": "", + "modal-copy-and-close": "", + "modal-copy-button": "", + "modal-field-description": "", + "modal-field-label": "", + "modal-title": "", + "status": "" + }, + "onprem": { + "cancel-snapshot-error-title": "", + "create-snapshot-error-title": "", + "disconnect-error-title": "", + "error-see-server-logs": "", + "get-session-error-title": "", + "get-snapshot-error-title": "", + "migration-finished-with-caveat-title": "", + "migration-finished-with-errors-body": "", + "migration-finished-with-warnings-body": "", + "snapshot-error-status-body": "", + "snapshot-error-status-title": "", + "success-message": "", + "success-message-generic": "", + "success-title": "", + "upload-snapshot-error-title": "" + }, + "pdc": { + "body": "", + "link-title": "", + "title": "" + }, + "pricing": { + "body": "", + "link-title": "", + "title": "" + }, + "public-preview": { + "button-text": "", + "message": "", + "message-cloud": "", + "title": "" + }, + "resource-details": { + "dismiss-button": "", + "error-messages": { + "dashboard-already-managed": "", + "datasource-already-managed": "", + "datasource-invalid-url": "", + "datasource-name-conflict": "", + "folder-name-conflict": "", + "generic-error": "", + "internal-service-error": "", + "library-element-name-conflict": "", + "resource-conflict": "", + "unexpected-error": "", + "unsupported-data-type": "" + }, + "error-title": "", + "generic-title": "", + "missing-message": "", + "resource-summary": "", + "title": "", + "warning-title": "" + }, + "resource-status": { + "error-details-button": "", + "failed": "", + "migrated": "", + "migrating": "", + "not-migrated": "", + "unknown": "", + "warning": "", + "warning-details-button": "" + }, + "resource-table": { + "dashboard-load-error": "", + "error-library-element-sub": "", + "error-library-element-title": "", + "unknown-datasource-title": "", + "unknown-datasource-type": "" + }, + "resource-type": { + "alert_rule": "", + "alert_rule_group": "", + "contact_point": "", + "dashboard": "", + "datasource": "", + "folder": "", + "library_element": "", + "mute_timing": "", + "notification_policy": "", + "notification_template": "", + "plugin": "", + "unknown": "" + }, + "summary": { + "cancel-snapshot": "", + "disconnect": "", + "errored-resource-count": "", + "page-loading": "", + "rebuild-snapshot": "", + "snapshot-date": "", + "snapshot-not-created": "", + "start-migration": "", + "successful-resource-count": "", + "target-stack-title": "", + "total-resource-count": "", + "upload-migration": "" + }, + "support-types-disclosure": { + "text": "" + }, + "token-status": { + "active": "", + "no-active": "", + "unknown": "", + "unknown-error": "" + }, + "what-is-cloud": { + "body": "", + "link-title": "", + "title": "" + }, + "why-host": { + "body": "", + "link-title": "", + "title": "" + } + }, + "multicombobox": { + "all": { + "title": "", + "title-filtered": "" + }, + "clear": { + "title": "" + } + }, + "nav": { + "add-new-connections": { + "title": "" + }, + "admin": { + "subtitle": "", + "title": "" + }, + "alert-list-legacy": { + "title": "" + }, + "alerting": { + "subtitle": "", + "title": "" + }, + "alerting-admin": { + "subtitle": "", + "title": "" + }, + "alerting-am-routes": { + "subtitle": "", + "title": "" + }, + "alerting-channels": { + "title": "" + }, + "alerting-groups": { + "subtitle": "", + "title": "" + }, + "alerting-home": { + "title": "" + }, + "alerting-legacy": { + "title": "" + }, + "alerting-list": { + "subtitle": "", + "title": "" + }, + "alerting-receivers": { + "subtitle": "", + "title": "" + }, + "alerting-silences": { + "subtitle": "", + "title": "" + }, + "alerting-upgrade": { + "subtitle": "", + "title": "" + }, + "alerts-and-incidents": { + "subtitle": "", + "title": "" + }, + "api-keys": { + "subtitle": "", + "title": "" + }, + "application": { + "title": "" + }, + "apps": { + "subtitle": "", + "title": "" + }, + "authentication": { + "title": "" + }, + "bookmarks": { + "title": "" + }, + "bookmarks-empty": { + "title": "" + }, + "collector": { + "title": "" + }, + "config": { + "title": "" + }, + "config-access": { + "subtitle": "", + "title": "" + }, + "config-general": { + "subtitle": "", + "title": "" + }, + "config-plugins": { + "subtitle": "", + "title": "" + }, + "connect-data": { + "title": "" + }, + "connections": { + "subtitle": "", + "title": "" + }, + "correlations": { + "subtitle": "", + "title": "" + }, + "create": { + "title": "" + }, + "create-alert": { + "title": "" + }, + "create-dashboard": { + "title": "" + }, + "create-folder": { + "title": "" + }, + "create-import": { + "title": "" + }, + "dashboards": { + "subtitle": "", + "title": "" + }, + "data-sources": { + "subtitle": "", + "title": "" + }, + "databases": { + "title": "" + }, + "datasources": { + "subtitle": "", + "title": "" + }, + "detect": { + "title": "" + }, + "drilldown": { + "title": "" + }, + "explore": { + "title": "" + }, + "frontend": { + "subtitle": "", + "title": "" + }, + "frontend-app": { + "title": "" + }, + "global-orgs": { + "subtitle": "", + "title": "" + }, + "global-users": { + "subtitle": "", + "title": "" + }, + "grafana-quaderno": { + "title": "" + }, + "groupsync": { + "subtitle": "" + }, + "help": { + "title": "" + }, + "help/community": "", + "help/documentation": "", + "help/keyboard-shortcuts": "", + "help/support": "", + "history-container": { + "drawer-tittle": "" + }, + "history-wrapper": { + "collapse": "", + "expand": "", + "icon-selected": "", + "icon-unselected": "", + "show-more": "", + "today": "", + "yesterday": "" + }, + "home": { + "title": "" + }, + "incidents": { + "title": "" + }, + "infrastructure": { + "subtitle": "", + "title": "" + }, + "integrations": { + "title": "" + }, + "k6": { + "title": "" + }, + "kubernetes": { + "title": "" + }, + "library-panels": { + "subtitle": "", + "title": "" + }, + "machine-learning": { + "title": "" + }, + "manage-folder": { + "subtitle": "" + }, + "migrate-to-cloud": { + "subtitle": "", + "title": "" + }, + "monitoring": { + "subtitle": "", + "title": "" + }, + "new": { + "title": "" + }, + "new-dashboard": { + "title": "" + }, + "new-folder": { + "title": "" + }, + "oncall": { + "title": "" + }, + "org-settings": { + "subtitle": "", + "title": "" + }, + "playlists": { + "subtitle": "", + "title": "" + }, + "plugins": { + "subtitle": "", + "title": "" + }, + "private-data-source-connections": { + "subtitle": "", + "title": "" + }, + "profile/notifications": { + "title": "" + }, + "profile/password": { + "title": "" + }, + "profile/settings": { + "title": "" + }, + "profiles": { + "title": "" + }, + "public": { + "title": "" + }, + "recently-deleted": { + "subtitle": "", + "title": "" + }, + "recorded-queries": { + "title": "" + }, + "reporting": { + "title": "" + }, + "scenes": { + "title": "" + }, + "search": { + "placeholderCommandPalette": "" + }, + "search-dashboards": { + "title": "" + }, + "server-settings": { + "subtitle": "", + "title": "" + }, + "service-accounts": { + "subtitle": "", + "title": "" + }, + "setup-guide": { + "title": "" + }, + "shared-dashboard": { + "subtitle": "", + "title": "" + }, + "sign-out": { + "title": "" + }, + "slo": { + "title": "" + }, + "snapshots": { + "subtitle": "", + "title": "" + }, + "starred": { + "title": "" + }, + "starred-empty": { + "title": "" + }, + "statistics-and-licensing": { + "title": "" + }, + "storage": { + "subtitle": "", + "title": "" + }, + "support-bundles": { + "subtitle": "", + "title": "" + }, + "synthetics": { + "title": "" + }, + "teams": { + "subtitle": "", + "title": "" + }, + "testing-and-synthetics": { + "subtitle": "", + "title": "" + }, + "upgrading": { + "title": "" + }, + "users": { + "subtitle": "", + "title": "" + } + }, + "navigation": { + "invite-user": { + "invite-button": "", + "invite-tooltip": "" + }, + "item": { + "add-bookmark": "", + "remove-bookmark": "" + }, + "kiosk": { + "tv-alert": "" + }, + "megamenu": { + "close": "", + "dock": "", + "list-label": "", + "open": "", + "undock": "" + }, + "rss-button": "" + }, + "news": { + "drawer": { + "close": "" + }, + "title": "" + }, + "notifications": { + "empty-state": { + "description": "", + "title": "" + }, + "starred-dashboard": "", + "unstarred-dashboard": "" + }, + "oauth": { + "form": { + "server-discovery-action-button": "", + "server-discovery-modal-close": "", + "server-discovery-modal-loading": "", + "server-discovery-modal-submit": "" + }, + "login": { + "error": "" + } + }, + "panel": { + "header-menu": { + "copy": "", + "create-library-panel": "", + "duplicate": "", + "edit": "", + "explore": "", + "get-help": "", + "hide-legend": "", + "inspect": "", + "inspect-data": "", + "inspect-json": "", + "more": "", + "new-alert-rule": "", + "query": "", + "remove": "", + "replace-library-panel": "", + "share": "", + "show-legend": "", + "unlink-library-panel": "", + "view": "" + } + }, + "panel-search": { + "no-matches": "", + "unsupported-layout": "" + }, + "panel-type-filter": { + "clear-button": "" + }, + "playlist-edit": { + "error-prefix": "", + "form": { + "add-tag-label": "", + "add-tag-placeholder": "", + "add-title-label": "", + "cancel": "", + "heading": "", + "interval-label": "", + "interval-placeholder": "", + "interval-required": "", + "name-label": "", + "name-placeholder": "", + "name-required": "", + "save": "", + "table-delete": "", + "table-drag": "", + "table-empty": "", + "table-heading": "" + }, + "sub-title": "", + "title": "" + }, + "playlist-page": { + "card": { + "delete": "", + "edit": "", + "start": "", + "tooltip": "" + }, + "create-button": { + "title": "" + }, + "delete-modal": { + "body": "", + "confirm-text": "" + }, + "empty": { + "button": "", + "pro-tip": "", + "title": "" + } + }, + "playlists": { + "empty-state": { + "message": "" + } + }, + "plugins": { + "catalog": { + "no-updates-available": "", + "update-all": { + "all-plugins-updated": "", + "available-header": "", + "button": "", + "cloud-update-message": "", + "error": "", + "error-status-text": "", + "header": "", + "installed-header": "", + "modal-confirmation": "", + "modal-dismiss": "", + "modal-in-progress": "", + "modal-title": "", + "name-header": "", + "update-header": "", + "update-status-text": "" + }, + "versions": { + "confirmation-text-1": "", + "confirmation-text-2": "", + "downgrade-confirm": "", + "downgrade-title": "" + } + }, + "details": { + "connections-tab": { + "description": "" + }, + "labels": { + "contactGrafanaLabs": "", + "customLinks": "", + "customLinksTooltip": "", + "dependencies": "", + "documentation": "", + "downloads": "", + "from": "", + "installedVersion": "", + "lastCommitDate": "", + "latestVersion": "", + "license": "", + "raiseAnIssue": "", + "reportAbuse": "", + "reportAbuseTooltip": "", + "repository": "", + "signature": "", + "status": "", + "updatedAt": "" + }, + "modal": { + "cancel": "", + "copyEmail": "", + "description": "", + "node": "", + "title": "" + } + }, + "empty-state": { + "message": "" + }, + "filter": { + "disabled": "", + "sort": "", + "sort-list": "", + "state": "" + }, + "plugin-help": { + "error": "", + "not-found": "" + } + }, + "profile": { + "change-password": { + "cancel-button": "", + "cannot-change-password-message": "", + "change-password-button": "", + "confirm-password-label": "", + "confirm-password-required": "", + "ldap-auth-proxy-message": "", + "new-password-label": "", + "new-password-required": "", + "new-password-same-as-old": "", + "old-password-label": "", + "old-password-required": "", + "passwords-must-match": "", + "strong-password-validation-register": "" + } + }, + "public-dashboard": { + "acknowledgment-checkboxes": { + "ack-title": "", + "data-src-ack-desc": "", + "data-src-ack-tooltip": "", + "public-ack-desc": "", + "public-ack-tooltip": "", + "usage-ack-desc": "", + "usage-ack-desc-tooltip": "" + }, + "config": { + "can-view-dashboard-radio-button-label": "", + "copy-button": "", + "dashboard-url-field-label": "", + "email-share-type-option-label": "", + "pause-sharing-dashboard-label": "", + "public-share-type-option-label": "", + "revoke-public-URL-button": "", + "revoke-public-URL-button-title": "", + "settings-title": "" + }, + "configuration": { + "display-annotations-description": "", + "display-annotations-label": "", + "enable-time-range-description": "", + "enable-time-range-label": "", + "settings-label": "", + "success-pause": "", + "success-resume": "", + "success-update": "", + "success-update-old": "", + "time-range-label": "", + "time-range-tooltip": "" + }, + "create-page": { + "generate-public-url-button": "", + "unsupported-features-desc": "", + "welcome-title": "" + }, + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "email-sharing": { + "accept-button": "", + "alert-text": "", + "bill-ack": "", + "cancel-button": "", + "input-invalid-email-text": "", + "input-required-email-text": "", + "invite-button": "", + "invite-field-desc": "", + "invite-field-label": "", + "learn-more-button": "", + "recipient-email-placeholder": "", + "recipient-invalid-email-text": "", + "recipient-invitation-button": "", + "recipient-invitation-description": "", + "recipient-invitation-tooltip": "", + "recipient-list-description": "", + "recipient-list-title": "", + "recipient-required-email-text": "", + "resend-button": "", + "resend-button-title": "", + "resend-invite-label": "", + "revoke-access-label": "", + "revoke-button": "", + "revoke-button-title": "", + "success-creation": "", + "success-share-type-change": "" + }, + "modal-alerts": { + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "save-dashboard-changes-alert-title": "", + "unsupport-data-source-alert-readmore-link": "", + "unsupported-data-source-alert-desc": "", + "unsupported-data-source-alert-title": "", + "unsupported-template-variable-alert-desc": "", + "unsupported-template-variable-alert-title": "" + }, + "public-sharing": { + "accept-button": "", + "alert-text": "", + "cancel-button": "", + "learn-more-button": "", + "public-ack": "", + "success-creation": "", + "success-share-type-change": "" + }, + "settings-bar-header": { + "collapse-settings-tooltip": "", + "expand-settings-tooltip": "" + }, + "settings-configuration": { + "default-time-range-label": "", + "default-time-range-label-desc": "", + "show-annotations-label": "", + "show-annotations-label-desc": "", + "time-range-picker-label": "", + "time-range-picker-label-desc": "" + }, + "settings-summary": { + "annotations-hide-text": "", + "annotations-show-text": "", + "time-range-picker-disabled-text": "", + "time-range-picker-enabled-text": "", + "time-range-text": "" + }, + "share": { + "success-delete": "", + "success-delete-old": "" + }, + "share-configuration": { + "share-type-label": "" + }, + "share-externally": { + "copy-link-button": "", + "email-share-type-option-description": "", + "email-share-type-option-label": "", + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "pause-access-button": "", + "pause-access-tooltip": "", + "public-share-type-option-description": "", + "public-share-type-option-label": "", + "resume-access-button": "", + "revoke-access-button": "", + "revoke-access-description": "", + "unsupported-data-source-alert-desc": "" + }, + "sharing": { + "success-creation": "" + } + }, + "public-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "public-dashboard-users-access-list": { + "dashboard-modal": { + "external-link": "", + "loading-text": "", + "open-dashboard-list-text": "", + "public-dashboard-link": "", + "public-dashboard-setting": "", + "sharing-setting": "" + }, + "delete-user-modal": { + "delete-user-button-text": "", + "delete-user-cancel-button": "", + "delete-user-revoke-access-button": "", + "revoke-access-title": "", + "revoke-user-access-modal-desc-line1": "", + "revoke-user-access-modal-desc-line2": "" + }, + "delete-user-shared-dashboards-modal": { + "revoke-user-access-modal-desc-line2": "" + }, + "modal": { + "dashboard-modal-title": "", + "shared-dashboard-modal-title": "" + }, + "table-body": { + "dashboard-count_other": "" + }, + "table-header": { + "activated-label": "", + "activated-tooltip": "", + "email-label": "", + "last-active-label": "", + "origin-label": "", + "role-label": "" + } + }, + "query-operation": { + "header": { + "collapse-row": "", + "datasource-help": "", + "drag-and-drop": "", + "duplicate-query": "", + "expand-row": "", + "hide-response": "", + "remove-query": "", + "show-response": "", + "toggle-edit-mode": "" + }, + "query-editor-not-exported": "" + }, + "recently-deleted": { + "buttons": { + "delete": "", + "restore": "" + }, + "page": { + "no-deleted-dashboards": "", + "no-deleted-dashboards-text": "", + "no-search-result": "" + }, + "permanently-delete-modal": { + "confirm-text": "", + "delete-button": "", + "delete-loading": "", + "title": "", + "text_other": "" + }, + "restore-modal": { + "restore-button": "", + "restore-loading": "", + "title": "", + "folder-picker-text_other": "", + "text_other": "" + } + }, + "recentlyDeleted": { + "filter": { + "placeholder": "" + } + }, + "reduce": { + "strictMode": { + "description": "", + "title": "" + } + }, + "refresh-picker": { + "aria-label": { + "choose-interval": "", + "duration-selected": "" + }, + "auto-option": { + "aria-label": "", + "label": "" + }, + "live-option": { + "aria-label": "", + "label": "" + }, + "off-option": { + "aria-label": "", + "label": "" + }, + "tooltip": { + "interval-selected": "", + "turned-off": "" + } + }, + "return-to-previous": { + "button": { + "label": "" + }, + "dismissable-button": "" + }, + "role-picker": { + "built-in": { + "basic-roles": "" + }, + "input": { + "no-roles": "" + }, + "menu": { + "clear-button": "", + "tooltip": "" + }, + "sub-menu": { + "clear-button": "" + }, + "title": { + "description": "" + } + }, + "role-picker-drawer": { + "basic-roles": { + "label": "" + } + }, + "route-error": { + "description": "", + "reload-button": "", + "title": "" + }, + "save-dashboards": { + "message-length": { + "info": "", + "title": "" + }, + "name-exists": { + "message-info": "", + "message-suggestion": "", + "title": "" + } + }, + "scopes": { + "dashboards": { + "collapse": "", + "expand": "", + "loading": "", + "noResultsForFilter": "", + "noResultsForFilterClear": "", + "noResultsForScopes": "", + "noResultsNoScopes": "", + "search": "", + "toggle": { + "collapse": "", + "disabled": "", + "expand": "" + } + }, + "selector": { + "apply": "", + "cancel": "", + "input": { + "placeholder": "", + "removeAll": "" + }, + "title": "" + }, + "tree": { + "collapse": "", + "expand": "", + "headline": { + "noResults": "", + "recommended": "", + "results": "" + }, + "search": "" + } + }, + "search": { + "actions": { + "include-panels": "", + "remove-datasource-filter": "", + "sort-placeholder": "", + "starred": "", + "view-as-folders": "", + "view-as-list": "" + }, + "dashboard-actions": { + "import": "", + "new": "", + "new-dashboard": "", + "new-folder": "" + }, + "results-table": { + "datasource-header": "", + "deleted-less-than-1-min": "", + "deleted-remaining-header": "", + "location-header": "", + "name-header": "", + "tags-header": "", + "type-dashboard": "", + "type-folder": "", + "type-header": "" + }, + "search-input": { + "include-panels-placeholder": "", + "placeholder": "" + } + }, + "select": { + "select-menu": { + "selected-count": "" + } + }, + "service-account-create-page": { + "create": { + "button": "" + }, + "name": { + "label": "", + "required-error": "" + }, + "page-nav": { + "label": "" + }, + "role": { + "label": "" + } + }, + "service-accounts": { + "empty-state": { + "button-title": "", + "message": "", + "more-info": "", + "title": "" + } + }, + "share-dashboard": { + "menu": { + "export-json-title": "", + "share-externally-title": "", + "share-internally-title": "", + "share-snapshot-title": "" + }, + "share-button": "", + "share-button-tooltip": "" + }, + "share-drawer": { + "confirm-action": { + "back-arrow-button": "", + "cancel-button": "" + } + }, + "share-modal": { + "dashboard": { + "title": "" + }, + "embed": { + "copy": "", + "html": "", + "html-description": "", + "info": "", + "time-range": "" + }, + "export": { + "back-button": "", + "cancel-button": "", + "info-text": "", + "loading": "", + "save-button": "", + "share-externally-label": "", + "view-button": "" + }, + "library": { + "info": "" + }, + "link": { + "copy-link-button": "", + "info-text": "", + "link-url": "", + "render-alert": "", + "render-instructions": "", + "rendered-image": "", + "save-alert": "", + "save-dashboard": "", + "shorten-url": "", + "time-range-description": "", + "time-range-label": "" + }, + "panel": { + "title": "" + }, + "snapshot": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "deleted-message": "", + "expire": "", + "expire-day": "", + "expire-hour": "", + "expire-never": "", + "expire-week": "", + "info-text-1": "", + "info-text-2": "", + "local-button": "", + "mistake-message": "", + "name": "", + "timeout": "", + "timeout-description": "", + "url-label": "" + }, + "tab-title": { + "embed": "", + "export": "", + "library-panel": "", + "link": "", + "panel-embed": "", + "public-dashboard": "", + "public-dashboard-title": "", + "snapshot": "" + }, + "theme-picker": { + "current": "", + "dark": "", + "field-name": "", + "light": "" + }, + "view-json": { + "copy-button": "" + } + }, + "share-panel": { + "drawer": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "" + }, + "menu": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "", + "share-snapshot-title": "" + }, + "new-library-panel": { + "cancel-button": "", + "create-button": "" + } + }, + "share-panel-image": { + "preview": { + "title": "" + }, + "settings": { + "height-label": "", + "height-min": "", + "height-placeholder": "", + "height-required": "", + "max-warning": "", + "scale-factor-label": "", + "scale-factor-min": "", + "scale-factor-placeholder": "", + "scale-factor-required": "", + "title": "", + "width-label": "", + "width-min": "", + "width-placeholder": "", + "width-required": "" + } + }, + "share-playlist": { + "checkbox-description": "", + "checkbox-label": "", + "copy-link-button": "", + "link-url-label": "", + "mode": "", + "mode-kiosk": "", + "mode-normal": "", + "title": "" + }, + "shared": { + "preferences": { + "theme": { + "dark-label": "", + "light-label": "", + "system-label": "" + } + } + }, + "shared-dashboard": { + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "fields": { + "timezone-label": "" + } + }, + "shared-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "shared-preferences": { + "fields": { + "home-dashboard-label": "", + "home-dashboard-placeholder": "", + "locale-label": "", + "locale-placeholder": "", + "theme-description": "", + "theme-label": "", + "week-start-label": "" + }, + "theme": { + "default-label": "" + }, + "title": "" + }, + "sign-up": { + "back-button": "", + "submit-button": "", + "verify": { + "back-button": "", + "complete-button": "", + "header": "", + "info": "", + "send-button": "" + } + }, + "silences": { + "empty-state": { + "button-title": "", + "title": "" + }, + "table": { + "add-silence-button": "", + "edit-button": "", + "expired-silences": "", + "no-matching-silences": "", + "noConfig": "", + "recreate-button": "", + "unsilence-button": "" + } + }, + "silences-table": { + "header": { + "alert-name": "", + "state": "" + } + }, + "snapshot": { + "empty-state": { + "message": "", + "more-info": "" + }, + "external-badge": "", + "name-column-header": "", + "share": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "delete-description": "", + "delete-permission-tooltip": "", + "delete-title": "", + "deleted-alert": "", + "expiration-label": "", + "info-alert": "", + "learn-more-button": "", + "local-button": "", + "name-label": "", + "new-snapshot-button": "", + "success-creation": "", + "success-delete": "", + "view-all-button": "" + }, + "share-panel": { + "info-alert": "" + }, + "url-column-header": "", + "view-button": "" + }, + "table": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "" + } + }, + "tag-filter": { + "clear-button": "", + "loading": "", + "no-tags": "", + "placeholder": "" + }, + "teams": { + "empty-state": { + "button-title": "", + "message": "", + "pro-tip": "", + "title": "" + } + }, + "theme-preview": { + "breadcrumbs": { + "dashboards": "", + "home": "" + }, + "panel": { + "form-label": "", + "title": "" + } + }, + "time-picker": { + "absolute": { + "recent-title": "", + "title": "" + }, + "calendar": { + "apply-button": "", + "cancel-button": "", + "close": "", + "next-month": "", + "previous-month": "", + "select-time": "" + }, + "content": { + "empty-recent-list-docs": "", + "empty-recent-list-info": "", + "filter-placeholder": "" + }, + "copy-paste": { + "copy-success-message": "", + "default-error-message": "", + "default-error-title": "", + "tooltip-copy": "", + "tooltip-paste": "" + }, + "footer": { + "change-settings-button": "", + "fiscal-year-option": "", + "fiscal-year-start": "", + "time-zone-option": "", + "time-zone-selection": "" + }, + "range-content": { + "apply-button": "", + "default-error": "", + "fiscal-year": "", + "from-input": "", + "open-input-calendar": "", + "range-error": "", + "to-input": "" + }, + "range-picker": { + "backwards-time-aria-label": "", + "current-time-selected": "", + "forwards-time-aria-label": "", + "to": "", + "zoom-out-button": "", + "zoom-out-tooltip": "" + }, + "time-range": { + "apply": "", + "aria-role": "", + "default-title": "", + "example": "", + "example-details": "", + "example-title": "", + "from-label": "", + "from-to": "", + "more-info": "", + "specify": "", + "submit-button-label": "", + "supported-formats": "", + "to-label": "" + }, + "zone": { + "select-aria-label": "", + "select-search-input": "" + } + }, + "trails": { + "bookmarks": { + "or-view-bookmarks": "" + }, + "card": { + "date-created": "" + }, + "home": { + "learn-more": "", + "lets-start": "", + "start-your-metrics-exploration": "", + "subtitle": "" + }, + "metric-select": { + "filter-by": "", + "native-histogram": "", + "new-badge": "", + "otel-switch": "" + }, + "native-histogram-banner": { + "ch-heatmap": "", + "ch-histogram": "", + "click-histogram": "", + "hide-examples": "", + "learn-more": "", + "metric-examples": "", + "nh-heatmap": "", + "nh-histogram": "", + "now": "", + "previously": "", + "see-examples": "", + "sentence": "" + }, + "recent-metrics": { + "or-view-a-recent-exploration": "" + }, + "settings": { + "always-keep-selected-metric-graph-in-view": "", + "show-previews-of-metric-graphs": "" + } + }, + "transformations": { + "empty": { + "add-transformation-body": "", + "add-transformation-header": "" + } + }, + "upgrade-box": { + "discovery-text": "", + "discovery-text-continued": "", + "get-started": "", + "learn-more": "", + "upgrade-button": "" + }, + "user-orgs": { + "current-org-button": "", + "name-column": "", + "role-column": "", + "select-org-button": "", + "title": "" + }, + "user-profile": { + "fields": { + "email-error": "", + "email-label": "", + "name-error": "", + "name-label": "", + "username-label": "" + }, + "tabs": { + "general": "" + } + }, + "user-session": { + "auth-module-column": "", + "browser-column": "", + "created-at-column": "", + "identity-provider-column": "", + "ip-column": "", + "revoke": "", + "seen-at-column": "" + }, + "user-sessions": { + "loading": "" + }, + "users": { + "empty-state": { + "message": "" + } + }, + "users-access-list": { + "tabs": { + "public-dashboard-users-tab-title": "", + "shared-dashboard-users-tab-title": "" + } + }, + "variable": { + "adhoc": { + "placeholder": "" + }, + "dropdown": { + "placeholder": "" + }, + "picker": { + "link-all": "", + "option-all": "", + "option-selected-values": "", + "option-tooltip": "" + }, + "textbox": { + "placeholder": "" + } + }, + "variables": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + }, + "unknown-table": { + "loading": "", + "no-unknowns": "", + "renamed-or-missing-variables": "", + "variable": "" + } + } +} \ No newline at end of file diff --git a/public/locales/it-IT/grafana.json b/public/locales/it-IT/grafana.json new file mode 100644 index 00000000000..f3a7ee625b6 --- /dev/null +++ b/public/locales/it-IT/grafana.json @@ -0,0 +1,4010 @@ +{ + "_comment": "", + "access-control": { + "add-permission": { + "role-label": "", + "serviceaccount-label": "", + "team-label": "", + "title": "", + "user-label": "" + }, + "add-permissions": { + "save": "" + }, + "permission-list": { + "permission": "" + }, + "permission-list-item": { + "inherited": "" + }, + "permissions": { + "add-label": "", + "no-permissions": "", + "permissions-change-warning": "", + "role": "", + "serviceaccount": "", + "team": "", + "title": "", + "user": "" + } + }, + "action-editor": { + "modal": { + "cancel-button": "", + "save-button": "" + } + }, + "admin": { + "anon-users": { + "not-found": "" + }, + "edit-org": { + "access-denied": "", + "heading": "", + "update-button": "", + "users-heading": "" + }, + "feature-toggles": { + "sub-title": "" + }, + "get-enterprise": { + "contact-us": "", + "description": "", + "features-heading": "", + "included-description": "", + "included-heading": "", + "service-title": "", + "team-sync-details": "", + "title": "" + }, + "ldap": { + "test-mapping-heading": "", + "test-mapping-run-button": "" + }, + "ldap-permissions": { + "active": "", + "admin": "", + "inactive": "" + }, + "ldap-status": { + "title": "" + }, + "ldap-sync": { + "debug-button": "", + "external-sync-description": "", + "external-sync-label": "", + "next-sync-label": "", + "not-enabled": "", + "sync-button": "", + "title": "" + }, + "ldap-sync-info": { + "title": "" + }, + "ldap-user-groups": { + "no-org-found": "" + }, + "ldap-user-info": { + "no-team": "" + }, + "org-uers": { + "last-seen-never": "" + }, + "org-users": { + "not-editable": "" + }, + "orgs": { + "delete-body": "", + "id-header": "", + "name-header": "", + "new-org-button": "" + }, + "server-settings": { + "alerts-button": "", + "dashboards-button": "", + "data-sources-button": "", + "not-found": "", + "title": "", + "users-button": "" + }, + "settings": { + "info-description": "" + }, + "upgrade-info": { + "title": "" + }, + "user-orgs": { + "add-button": "", + "change-role-button": "", + "external-user-tooltip": "", + "remove-button": "", + "role-not-editable": "", + "title": "" + }, + "user-orgs-modal": { + "add-button": "", + "cancel-button": "" + }, + "user-permissions": { + "change-button": "", + "grafana-admin-key": "", + "grafana-admin-no": "", + "grafana-admin-yes": "", + "title": "" + }, + "user-profile": { + "delete-button": "", + "disable-button": "", + "edit-button": "", + "enable-button": "", + "title": "" + }, + "user-sessions": { + "browser-column": "", + "force-logout-all-button": "", + "force-logout-button": "", + "ip-column": "", + "last-seen-column": "", + "logged-on-column": "", + "title": "" + }, + "users-create": { + "create-button": "" + }, + "users-list": { + "create-button": "" + }, + "users-table": { + "last-seen-never": "", + "no-licensed-roles": "" + } + }, + "alert-labels": { + "button": { + "hide": "", + "show": { + "tooltip": "" + } + } + }, + "alerting": { + "alert": { + "alert-state": "", + "annotations": "", + "evaluation": "", + "evaluation-paused": "", + "evaluation-paused-description": "", + "last-evaluated": "", + "last-evaluation-duration": "", + "last-updated-at": "", + "last-updated-by": "", + "no-annotations": "", + "pending-period": "", + "rule": "", + "rule-identifier": "", + "rule-type": "", + "state-error-timeout": "", + "state-no-data": "", + "target-datasource-uid": "" + }, + "alert-recording-rule-form": { + "evaluation-behaviour": { + "description": { + "text": "" + } + } + }, + "alert-rules": { + "firing-for": "", + "next-evaluation": "", + "next-evaluation-in": "", + "rule-definition": "" + }, + "alertform": { + "labels": { + "alerting": "", + "recording": "" + } + }, + "alertVersionHistory": { + "alerting": "", + "alerting-change-description": "", + "annotations": "", + "compare": "", + "compare-with-latest": "", + "compareVersions": "", + "comparing-versions": "", + "condition": "", + "contactPointRouting": "", + "description": "", + "errorloading": "", + "execErrorState": "", + "intervalSeconds": "", + "labels": "", + "latest": "", + "name": "", + "namespace_uid": "", + "noDataState": "", + "noVersionsFound": "", + "paused": "", + "pendingPeriod": "", + "provisioning": "", + "provisioning-change-description": "", + "queryAndAlertCondition": "", + "restore": "", + "restore-manually": "", + "restore-modal": { + "body": "", + "confirm": "", + "error": "", + "summary": "", + "title": "" + }, + "restore-version": "", + "rule_group": "", + "unknown": "", + "unknown-change-description": "", + "user-id": "", + "warning-restore-manually": "", + "warning-restore-manually-title": "" + }, + "annotations": { + "description": "", + "title": "" + }, + "central-alert-history": { + "details": { + "error": "", + "header": { + "alert-rule": "", + "instance": "", + "state": "", + "timestamp": "" + }, + "loading": "", + "no-recognized-state": "", + "no-values": "", + "not-found": "", + "number-transitions": "", + "state": { + "alerting": "", + "error": "", + "no-data": "", + "normal": "", + "pending": "" + }, + "state-transitions": "", + "unknown-event-state": "", + "unknown-rule": "", + "value-in-transition": "" + }, + "error": "", + "filter": { + "clear": "", + "info": { + "label1": "", + "label2": "", + "label3": "", + "label4": "" + } + }, + "filterBy": "", + "too-many-events": { + "text": "", + "title": "" + } + }, + "common": { + "cancel": "", + "clear-filters": "", + "delete": "", + "edit": "", + "export": "", + "export-all": "", + "loading": "", + "search-by-matchers": "", + "titles": { + "notification-templates": "" + }, + "view": "" + }, + "contact-points": { + "create": "", + "custom-template-value": "", + "delete-reasons": { + "heading": "", + "no-permissions": "", + "policies": "", + "provisioned": "", + "rules": "" + }, + "delivered-to": "", + "delivery-duration": "", + "empty-state": { + "title": "" + }, + "key-value-map": { + "add": "", + "confirm-add": "" + }, + "last-delivery-attempt": "", + "last-delivery-failed": "", + "no-contact-points-found": "", + "no-delivery-attempts": "", + "no-integrations": "", + "only-firing": "", + "receiver-summary": { + "jira": "" + }, + "telegram": { + "parse-mode-warning-body": "", + "parse-mode-warning-title": "" + }, + "used-by_one": "", + "used-by_other": "", + "used-by-rules_one": "", + "used-by-rules_other": "" + }, + "contactPointFilter": { + "label": "" + }, + "copy-to-clipboard": "", + "dag": { + "missing-reference": "", + "self-reference": "" + }, + "export": { + "subtitle": { + "formats": "", + "one-format": "" + } + }, + "folderAndGroup": { + "evaluation": { + "modal": { + "text": { + "alerting": "", + "recording": "" + } + } + } + }, + "group-actions": { + "actions-trigger": "", + "delete": "", + "edit": "", + "export": "", + "reorder": "" + }, + "list-view": { + "empty": { + "new-alert-rule": "", + "new-recording-rule": "", + "provisioning": "" + }, + "section": { + "dataSourceManaged": { + "title": "" + }, + "grafanaManaged": { + "export-new-rule": "", + "export-rules": "", + "loading": "", + "new-recording-rule": "", + "title": "" + } + } + }, + "manage-permissions": { + "button": "", + "title": "" + }, + "mute_timings": { + "error-loading": { + "description": "", + "title": "" + } + }, + "mute-timings": { + "add-mute-timing": "", + "description": "", + "save": "", + "saving": "" + }, + "notification-preview": { + "alertmanager": "", + "error": "", + "initialized": "", + "preview-routing": "", + "title": "", + "uninitialized": "" + }, + "notification-templates": { + "duplicate": { + "subTitle": "", + "title": "" + }, + "edit": { + "subTitle": "", + "title": "" + }, + "new": { + "subTitle": "", + "title": "" + } + }, + "policies": { + "default-policy": { + "description": "", + "title": "", + "update": "" + }, + "delete": { + "confirm": "", + "warning-1": "", + "warning-2": "" + }, + "filter-description": "", + "generated-policies": "", + "matchers": "", + "metadata": { + "active-time": "", + "delivered-to": "", + "grouped-by": "", + "grouping": { + "none": "", + "single-group": "" + }, + "inherited": "", + "mute-time": "", + "timingOptions": { + "groupInterval": { + "description": "", + "label": "" + }, + "groupWait": { + "description": "", + "label": "" + }, + "repeatInterval": { + "description": "", + "label": "" + } + }, + "n-instances_one": "", + "n-instances_other": "" + }, + "new-child": "", + "new-policy": "", + "no-matchers": "", + "reload-policies": "", + "save-policy": "", + "update": { + "please-wait": "", + "update-policy": "", + "updating": "" + }, + "update-errors": { + "conflict": "", + "error-code": "", + "fallback": "", + "suffix": "", + "title": "" + }, + "n-more-policies_one": "", + "n-more-policies_other": "" + }, + "provisioning": { + "badge-tooltip-provenance": "", + "badge-tooltip-standard": "" + }, + "queryAndExpressionsStep": { + "disableAdvancedOptions": { + "text": "" + }, + "preview": "", + "previewCondition": "" + }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, + "rule-form": { + "evaluation": { + "evaluation-group-and-interval": "", + "group": { + "cancel": "", + "create": "", + "interval": "" + }, + "group-name": "", + "group-text": "", + "new-group": "", + "pause": { + "alerting": "", + "recording": "" + }, + "select-folder-before": "" + }, + "evaluation-behaviour": { + "description": { + "text": "" + }, + "info-help": { + "text": "" + }, + "pending-period": "" + }, + "evaluation-behaviour-description1": "", + "evaluation-behaviour-description2": "", + "evaluation-behaviour-description3": "", + "evaluation-behaviour-for": { + "error-parsing": "", + "validation": "" + }, + "folder": { + "cancel": "", + "create": "", + "create-folder": "", + "creating-new-folder": "", + "label": "", + "name": "", + "new-folder": "", + "new-folder-or": "" + }, + "folder-and-labels": "", + "folders": { + "help-info": "" + }, + "labels": { + "help-info": "" + }, + "pause": { + "label": "" + }, + "threshold": { + "recovery": { + "stop-alerting-above": "", + "stop-alerting-bellow": "", + "stop-alerting-equal": "", + "stop-alerting-inside-range": "", + "stop-alerting-less": "", + "stop-alerting-more": "", + "stop-alerting-not-equal": "", + "stop-alerting-outside-range": "", + "title": "" + } + } + }, + "rule-groups": { + "delete": { + "success": "" + }, + "move": { + "success": "" + }, + "rename": { + "success": "" + }, + "update": { + "success": "" + } + }, + "rule-list": { + "configure-datasource": "", + "ds-error-boundary": { + "description": "", + "title": "" + }, + "filter-view": { + "no-more-results": "", + "no-rules-found": "" + }, + "new-alert-rule": "", + "pagination": { + "next-page": "", + "previous-page": "" + }, + "return-button": { + "title": "" + }, + "rulerrule-loading-error": "" + }, + "rule-state": { + "creating": "", + "deleting": "", + "paused": "", + "recording-rule": "" + }, + "rule-view": { + "query": { + "datasources-na": { + "description": "", + "title": "" + } + } + }, + "rule-viewer": { + "error-loading": "", + "prometheus-consistency-check": { + "alert-message": "", + "alert-title": "" + } + }, + "rules": { + "add-rule": { + "success": "" + }, + "delete-rule": { + "success": "" + }, + "pause-rule": { + "success": "" + }, + "resume-rule": { + "success": "" + }, + "update-rule": { + "success": "" + } + }, + "search": { + "property": { + "data-source": "", + "evaluation-group": "", + "labels": "", + "namespace": "", + "rule-health": "", + "rule-name": "", + "rule-type": "", + "state": "" + }, + "save-query": "" + }, + "silences": { + "affected-instances": "", + "only-firing-instances": "", + "preview-affected-instances": "" + }, + "simpleCondition": { + "alertCondition": "" + }, + "templates": { + "editor": { + "add-example": "", + "auto-complete": "", + "goto-docs": "" + }, + "help": { + "intro": "" + }, + "misconfigured-badge-text": "", + "misconfigured-warning": "", + "misconfigured-warning-details": "" + }, + "threshold": { + "to": "" + } + }, + "annotations": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + } + }, + "api-keys": { + "empty-state": { + "message": "" + } + }, + "app-chrome": { + "skip-content-button": "", + "top-bar": { + "sign-in": "" + } + }, + "app-notification": { + "item": { + "trace-id": "" + } + }, + "bookmarks-page": { + "empty": { + "message": "", + "tip": "" + } + }, + "bouncing-loader": { + "label": "" + }, + "browse-dashboards": { + "action": { + "cancel-button": "", + "cannot-move-folders": "", + "confirmation-text": "", + "delete-button": "", + "delete-modal-invalid-text": "", + "delete-modal-invalid-title": "", + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "delete-modal-title": "", + "deleting": "", + "manage-permissions-button": "", + "move-button": "", + "move-modal-alert": "", + "move-modal-field-label": "", + "move-modal-text": "", + "move-modal-title": "", + "moving": "", + "new-folder-name-required-phrase": "" + }, + "actions": { + "button-to-recently-deleted": "" + }, + "counts": { + "alertRule_one": "", + "alertRule_other": "", + "dashboard_one": "", + "dashboard_other": "", + "folder_one": "", + "folder_other": "", + "libraryPanel_one": "", + "libraryPanel_other": "", + "total_one": "", + "total_other": "" + }, + "dashboards-tree": { + "collapse-folder-button": "", + "expand-folder-button": "", + "name-column": "", + "select-all-header-checkbox": "", + "select-checkbox": "", + "tags-column": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "", + "title-folder": "" + }, + "folder-actions-button": { + "delete": "", + "folder-actions": "", + "manage-permissions": "", + "move": "" + }, + "folder-picker": { + "accessible-label": "", + "button-label": "", + "clear-selection": "", + "empty-message": "", + "error-title": "", + "non-folder-item": "", + "search-placeholder": "", + "unknown-error": "" + }, + "hard-delete": { + "success": "" + }, + "manage-folder-nav": { + "alert-rules": "", + "dashboards": "", + "panels": "" + }, + "new-folder-form": { + "cancel-label": "", + "create-label": "", + "name-label": "" + }, + "no-results": { + "clear": "", + "text": "" + }, + "soft-delete": { + "success": "" + } + }, + "clipboard-button": { + "inline-toast": { + "success": "" + } + }, + "combobox": { + "async": { + "error": "" + }, + "clear": { + "title": "" + }, + "custom-value": { + "description": "" + }, + "group": { + "undefined": "" + }, + "options": { + "no-found": "" + } + }, + "command-palette": { + "action": { + "change-theme": "", + "dark-theme": "", + "light-theme": "" + }, + "empty-state": { + "message": "" + }, + "search-box": { + "placeholder": "" + }, + "section": { + "actions": "", + "dashboard-search-results": "", + "folder-search-results": "", + "pages": "", + "preferences": "", + "recent-dashboards": "" + } + }, + "common": { + "apply": "", + "cancel": "", + "clear": "", + "close": "", + "collapse": "", + "edit": "", + "help": "", + "loading": "", + "locale": { + "default": "" + }, + "save": "", + "search": "", + "view": "" + }, + "configuration-tracker": { + "config-card": { + "complete": "" + } + }, + "connections": { + "connect-data": { + "category-header-label": "", + "empty-message": "", + "request-data-source": "", + "roadmap": "" + }, + "search": { + "placeholder": "" + } + }, + "core": { + "versionHistory": { + "comparison": { + "header": { + "hide-json-diff": "", + "show-json-diff": "", + "text": "" + }, + "select": "" + }, + "no-properties-changed": "", + "table": { + "updated": "", + "updatedBy": "", + "version": "" + }, + "view-json-diff": "" + } + }, + "correlations": { + "add-new": "", + "alert": { + "error-message": "", + "title": "" + }, + "basic-info-form": { + "description-description": "", + "description-label": "", + "label-description": "", + "label-label": "", + "label-placeholder": "", + "label-required": "", + "sub-text": "", + "title": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + }, + "list": { + "delete": "", + "label": "", + "loading": "", + "read-only": "", + "source": "", + "target": "" + }, + "navigation-form": { + "add-button": "", + "back-button": "", + "next-button": "", + "save-button": "" + }, + "page-content": "", + "page-heading": "", + "query-editor": { + "control-rules": "", + "data-source-text": "", + "data-source-title": "", + "error-text": "", + "error-title": "", + "loading": "", + "query-description": "", + "query-editor-title": "", + "query-label": "" + }, + "source-form": { + "control-required": "", + "description": "", + "description-external-pre": "", + "description-query-pre": "", + "external-title": "", + "heading-external": "", + "heading-query": "", + "query-title": "", + "results-description": "", + "results-label": "", + "results-required": "", + "source-description": "", + "source-label": "", + "sub-text": "" + }, + "sub-title": "", + "target-form": { + "control-rules": "", + "sub-text": "", + "target-description-external": "", + "target-description-query": "", + "target-label": "", + "target-type-description": "", + "title": "", + "type-label": "" + }, + "trans-details": { + "logfmt-description": "", + "logfmt-label": "", + "regex-description": "", + "regex-expression": "", + "regex-label": "", + "regex-map-values": "" + }, + "transform": { + "add-button": "", + "heading": "", + "no-transform": "" + }, + "transform-row": { + "expression-label": "", + "expression-required": "", + "expression-tooltip": "", + "field-input": "", + "field-label": "", + "field-tooltip": "", + "map-value-label": "", + "map-value-tooltip": "", + "remove-button": "", + "remove-tooltip": "", + "transform-required": "", + "type-label": "", + "type-tooltip": "" + } + }, + "dashboard": { + "add-menu": { + "import": "", + "paste-panel": "", + "row": "", + "visualization": "" + }, + "alert-rules-drawer": { + "redirect-link": "", + "subtitle": "" + }, + "default-layout": { + "description": "", + "item-options": { + "repeat": { + "direction": { + "horizontal": "", + "title": "", + "vertical": "" + }, + "max": "", + "title": "", + "variable": { + "description": "", + "title": "" + } + } + }, + "name": "", + "row-actions": { + "delete": "", + "modal": { + "alt-action": "", + "text": "", + "title": "" + } + }, + "row-options": { + "button": { + "label": "" + }, + "form": { + "cancel": "", + "repeat-for": { + "label": "", + "learn-more": "", + "warning": { + "text": "" + } + }, + "title": "", + "update": "" + }, + "modal": { + "title": "" + }, + "repeat": { + "title": "", + "variable": { + "title": "" + } + }, + "title": "" + } + }, + "edit-pane": { + "elements": { + "dashboard": "", + "objects": "", + "panel": "", + "panels": "", + "row": "", + "rows": "", + "tab": "", + "tabs": "" + }, + "open": "", + "row": { + "header": { + "hide": "", + "title": "" + } + } + }, + "editpane": { + "add": "", + "configure": "", + "outline": "" + }, + "empty": { + "add-library-panel-body": "", + "add-library-panel-button": "", + "add-library-panel-header": "", + "add-visualization-body": "", + "add-visualization-button": "", + "add-visualization-header": "", + "import-a-dashboard-body": "", + "import-a-dashboard-header": "", + "import-dashboard-button": "" + }, + "errors": { + "failed-to-load": "" + }, + "inspect": { + "data-tab": "", + "error-tab": "", + "json-tab": "", + "meta-tab": "", + "query-tab": "", + "stats-tab": "", + "subtitle": "", + "title": "" + }, + "inspect-data": { + "data-options": "", + "dataframe-aria-label": "", + "dataframe-label": "", + "download-csv": "", + "download-excel-description": "", + "download-excel-label": "", + "download-logs": "", + "download-service": "", + "download-traces": "", + "excel-header": "", + "formatted": "", + "formatted-data-description": "", + "formatted-data-label": "", + "panel-transforms": "", + "series-to-columns": "", + "transformation": "", + "transformations-description": "", + "transformations-label": "" + }, + "inspect-json": { + "dataframe-description": "", + "dataframe-label": "", + "panel-data-description": "", + "panel-data-label": "", + "panel-json-description": "", + "panel-json-label": "", + "select-source": "", + "unknown": "" + }, + "inspect-meta": { + "no-inspector": "" + }, + "inspect-stats": { + "data-title": "", + "data-traceids": "", + "processing-time": "", + "queries": "", + "request-time": "", + "rows": "", + "table-title": "" + }, + "layout": { + "common": { + "copy": "", + "copy-or-duplicate": "", + "delete": "", + "duplicate": "", + "layout": "" + } + }, + "options": { + "description": "", + "title-option": "" + }, + "outline": { + "tree": { + "item": { + "collapse": "", + "empty": "", + "expand": "" + } + } + }, + "panel-edit": { + "alerting-tab": { + "dashboard-not-saved": "", + "no-rules": "" + } + }, + "responsive-layout": { + "description": "", + "item-options": { + "hide-no-data": "", + "repeat": { + "variable": { + "description": "", + "title": "" + } + }, + "title": "" + }, + "name": "", + "options": { + "columns": "", + "fixed": "", + "min": "", + "one-column": "", + "rows": "", + "three-columns": "", + "two-columns": "" + } + }, + "rows-layout": { + "description": "", + "name": "", + "option": { + "height": "", + "hide-header": "", + "repeat": "", + "title": "" + }, + "options": { + "height-expand": "", + "height-min": "" + }, + "row": { + "collapse": "", + "expand": "", + "menu": { + "add": "", + "add-panel": "", + "add-row-above": "", + "add-row-below": "", + "move-down": "", + "move-row": "", + "move-up": "" + }, + "new": "", + "repeat": { + "learn-more": "", + "warning": "" + } + }, + "row-options": { + "title-option": "" + } + }, + "tabs-layout": { + "description": "", + "menu": { + "move-tab": "" + }, + "name": "", + "tab": { + "menu": { + "add": "", + "add-panel": "", + "add-tab-above": "", + "add-tab-after": "", + "add-tab-before": "", + "move-left": "", + "move-right": "" + }, + "new": "" + }, + "tab-options": { + "title-option": "" + } + }, + "toolbar": { + "add": "", + "add-panel": "", + "add-panel-description": "", + "add-panel-lib": "", + "add-row": "", + "add-tab": "", + "alert-rules": "", + "back-to-dashboard": "", + "dashboard-settings": { + "label": "", + "tooltip": "" + }, + "discard-library-panel-changes": "", + "discard-panel": "", + "discard-panel-new": "", + "edit": { + "label": "", + "tooltip": "" + }, + "edit-dashboard-v2-schema": "", + "enter-edit-mode": { + "label": "", + "tooltip": "" + }, + "exit-edit-mode": { + "label": "", + "tooltip": "" + }, + "libray-panel-description": "", + "mark-favorite": "", + "more-save-options": "", + "open-original": "", + "playlist-next": "", + "playlist-previous": "", + "playlist-stop": "", + "public-dashboard": "", + "refresh": "", + "row-description": "", + "save": "", + "save-dashboard": { + "label": "", + "tooltip": "" + }, + "save-dashboard-copy": { + "label": "", + "tooltip": "" + }, + "save-dashboard-short": "", + "save-library-panel": "", + "settings": "", + "share": { + "label": "", + "tooltip": "" + }, + "share-button": "", + "show-hidden-elements": "", + "switch-old-dashboard": "", + "tabs-description": "", + "unlink-library-panel": "", + "unmark-favorite": "" + }, + "validation": { + "invalid-dashboard-id": "", + "invalid-json": "", + "tags-expected-array": "", + "tags-expected-strings": "" + }, + "viz-panel": { + "options": { + "description": "", + "open-edit": "", + "plugin-type-image": "", + "title-option": "", + "transparent-background": "" + } + } + }, + "dashboard-import": { + "file-dropzone": { + "primary-text": "", + "secondary-text": "" + }, + "form-actions": { + "cancel": "", + "load": "" + }, + "gcom-field": { + "label": "", + "load-button": "", + "placeholder": "", + "validation-required": "" + }, + "json-field": { + "label": "", + "validation-required": "" + } + }, + "dashboard-links": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "title": "" + } + }, + "dashboard-settings": { + "annotations": { + "title": "" + }, + "dashboard-delete-button": "", + "delete-modal": { + "confirmation-text": "", + "delete-button": "", + "title": "" + }, + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "general": { + "auto-refresh-description": "", + "auto-refresh-label": "", + "description-label": "", + "editable-description": "", + "editable-label": "", + "folder-label": "", + "panel-options-graph-tooltip-description": "", + "panel-options-graph-tooltip-label": "", + "panel-options-label": "", + "panels-preload-description": "", + "panels-preload-label": "", + "tags-label": "", + "title": "", + "title-label": "" + }, + "json-editor": { + "save-button": "", + "subtitle": "", + "title": "" + }, + "links": { + "title": "" + }, + "permissions": { + "title": "" + }, + "provisioned-delete-modal": { + "confirm-button": "", + "text-1": "", + "text-2": "", + "text-3": "", + "text-link": "", + "title": "" + }, + "settings": { + "title": "" + }, + "time-picker": { + "hide-time-picker": "", + "now-delay-description": "", + "now-delay-label": "", + "refresh-live-dashboards-description": "", + "refresh-live-dashboards-label": "", + "time-options-label": "", + "time-zone-label": "", + "week-start-label": "" + }, + "time-regions": { + "advanced-description-cron": "", + "advanced-description-rest": "", + "advanced-description-use": "", + "advanced-label": "" + }, + "variables": { + "title": "" + }, + "versions": { + "title": "" + } + }, + "dashboards": { + "panel-edit": { + "angular-deprecation-button-open-panel-json": "", + "angular-deprecation-description": "", + "angular-deprecation-heading": "" + }, + "panel-queries": { + "add-query-from-library": "" + }, + "settings": { + "variables": { + "dependencies": { + "button": "", + "title": "" + } + } + } + }, + "data-source-list": { + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + } + }, + "data-source-picker": { + "add-new-data-source": "", + "built-in-list": { + "description-dashboard": "", + "description-grafana": "", + "description-mixed": "" + }, + "list": { + "no-data-source-message": "" + }, + "modal": { + "configure-new-data-source": "", + "input-placeholder": "", + "title": "" + }, + "open-advanced-button": "" + }, + "data-source-testing-status-page": { + "error-more-details-link": "", + "success-more-details-links": "" + }, + "data-sources": { + "datasource-add-button": { + "label": "" + }, + "empty-state": { + "message": "" + } + }, + "embed": { + "share": { + "time-range-description": "", + "time-range-label": "" + } + }, + "empty-list-cta": { + "pro-tip": "" + }, + "entity-not-found": { + "description": "" + }, + "errors": { + "dashboard-settings": { + "annotations": { + "datasource": "" + } + } + }, + "explore": { + "add-to-dashboard": "", + "drilldownInfo": { + "action": "", + "description": "", + "title": "" + }, + "logs": { + "logs-volume": { + "add-filters": "", + "decrease-timerange": "", + "much-data": "" + }, + "maximum-pinned-logs": "", + "no-logs-found": "", + "scan-for-older-logs": "", + "stop-scan": "" + }, + "rich-history": { + "close-tooltip": "", + "datasource-a-z": "", + "datasource-z-a": "", + "newest-first": "", + "oldest-first": "", + "query-history": "", + "query-library": "", + "settings": "", + "starred": "" + }, + "rich-history-card": { + "add-comment-form": "", + "add-comment-tooltip": "", + "add-to-library": "", + "cancel": "", + "confirm-delete": "", + "copy-query-tooltip": "", + "copy-shortened-link-tooltip": "", + "datasource-icon-label": "", + "datasource-name-label": "", + "datasource-not-exist": "", + "delete-query-confirmation-title": "", + "delete-query-title": "", + "delete-query-tooltip": "", + "delete-starred-query-confirmation-text": "", + "edit-comment-tooltip": "", + "optional-description": "", + "query-comment-label": "", + "query-text-label": "", + "save-comment": "", + "star-query-tooltip": "", + "unstar-query-tooltip": "", + "update-comment-form": "" + }, + "rich-history-container": { + "loading": "" + }, + "rich-history-notification": { + "query-copied": "", + "query-deleted": "" + }, + "rich-history-queries-tab": { + "displaying-partial-queries": "", + "displaying-queries": "", + "filter-aria-label": "", + "filter-history": "", + "filter-placeholder": "", + "history-local": "", + "loading": "", + "loading-results": "", + "search-placeholder": "", + "showing-queries": "", + "sort-aria-label": "", + "sort-placeholder": "" + }, + "rich-history-settings-tab": { + "alert-info": "", + "change-default-tab": "", + "clear-history-info": "", + "clear-query-history": "", + "clear-query-history-button": "", + "delete-confirm": "", + "delete-confirm-text": "", + "delete-title": "", + "history-time-span": "", + "history-time-span-description": "", + "only-show-active-datasource": "", + "query-history-deleted": "", + "retention-period": { + "1-week": "", + "2-days": "", + "2-weeks": "", + "5-days": "" + } + }, + "rich-history-starred-tab": { + "filter-queries-aria-label": "", + "filter-queries-placeholder": "", + "loading": "", + "loading-results": "", + "local-history-message": "", + "search-queries-placeholder": "", + "showing-queries": "", + "sort-queries-aria-label": "", + "sort-queries-placeholder": "" + }, + "rich-history-utils": { + "a-week-ago": "", + "days-ago": "", + "default-from": "", + "default-to": "", + "today": "", + "two-weeks-ago": "", + "yesterday": "" + }, + "rich-history-utils-notification": { + "saving-failed": "", + "update-failed": "" + }, + "run-query": { + "left-pane": "", + "right-pane": "", + "run-query-button": "", + "switch-datasource-button": "" + }, + "secondary-actions": { + "add-from-query-library": "", + "query-add-button": "", + "query-add-button-aria-label": "", + "query-history-button": "", + "query-history-button-aria-label": "", + "query-inspector-button": "", + "query-inspector-button-aria-label": "" + }, + "table": { + "no-data": "", + "title": "", + "title-with-name": "" + }, + "toolbar": { + "add-to-extensions": "", + "add-to-queryless-extensions": "", + "aria-label": "", + "copy-link": "", + "copy-link-abs-time": "", + "copy-links-absolute-category": "", + "copy-links-normal-category": "", + "copy-shortened-link": "", + "copy-shortened-link-abs-time": "", + "copy-shortened-link-label": "", + "copy-shortened-link-menu": "", + "refresh-picker-cancel": "", + "refresh-picker-run": "", + "split-close": "", + "split-close-tooltip": "", + "split-narrow": "", + "split-title": "", + "split-tooltip": "", + "split-widen": "" + } + }, + "explore-metrics": { + "breakdown": { + "clearFilter": "", + "labelSelect": "", + "missing-otel-labels": "", + "noMatchingValue": "", + "sortBy": "" + }, + "related-logs": { + "LrrDocsLink": "", + "openExploreLogs": "", + "relatedLogsUnavailable": "", + "warnExperimentalFeature": "" + }, + "viewBy": "" + }, + "export": { + "json": { + "cancel-button": "", + "copy-button": "", + "download-button": "", + "download-successful_toast_message": "", + "export-externally-label": "", + "info-text": "", + "title": "" + }, + "menu": { + "export-as-json-label": "", + "export-as-json-tooltip": "" + } + }, + "folder-filter": { + "clear-folder-button": "" + }, + "folder-picker": { + "create-instructions": "", + "loading": "" + }, + "forgot-password": { + "back-button": "", + "change-password": { + "skip-button": "", + "submit-button": "" + }, + "contact-admin": "", + "email-sent": "", + "reset-password-header": "", + "send-email-button": "" + }, + "form-prompt": { + "continue-button": "", + "description": "", + "discard-button": "" + }, + "gen-ai": { + "apply-suggestion": "", + "incomplete-request-error": "", + "send-custom-feedback": "" + }, + "get-enterprise": { + "requires-license": "", + "title": "" + }, + "grafana-ui": { + "action-editor": { + "button": { + "confirm": "", + "confirm-action": "" + }, + "inline": { + "add-action": "", + "edit-action": "" + }, + "modal": { + "action-body": "", + "action-method": "", + "action-query-params": "", + "action-title": "", + "action-title-placeholder": "", + "one-click-description": "" + } + }, + "alert": { + "close-button": "" + }, + "auto-save-field": { + "saved": "", + "saving": "" + }, + "card": { + "option": "" + }, + "cascader": { + "clear-button": "" + }, + "color-picker-popover": { + "palette-tab": "", + "spectrum-tab": "" + }, + "confirm-button": { + "cancel": "" + }, + "confirm-content": { + "placeholder": "" + }, + "data-link-editor": { + "info": "", + "new-tab-label": "", + "title-label": "", + "title-placeholder": "", + "url-label": "" + }, + "data-link-editor-modal": { + "cancel": "", + "one-click-description": "", + "save": "" + }, + "data-link-inline-editor": { + "one-click": "" + }, + "data-links-inline-editor": { + "add-link": "", + "edit-link": "", + "one-click": "", + "one-click-enabled": "", + "title-not-provided": "", + "tooltip-edit": "", + "tooltip-remove": "", + "url-not-provided": "" + }, + "data-source-basic-auth-settings": { + "user-label": "", + "user-placeholder": "" + }, + "data-source-http-proxy-settings": { + "oauth-identity-label": "", + "oauth-identity-tooltip": "", + "skip-tls-verify-label": "", + "ts-client-auth-label": "", + "with-ca-cert-label": "", + "with-ca-cert-tooltip": "" + }, + "data-source-http-settings": { + "access-help": "", + "access-help-details": "", + "access-label": "", + "access-options-browser": "", + "access-options-proxy": "", + "allowed-cookies": "", + "allowed-cookies-tooltip": "", + "auth": "", + "azure-auth-label": "", + "azure-auth-tooltip": "", + "basic-auth": "", + "basic-auth-label": "", + "browser-mode-description": "", + "browser-mode-title": "", + "default-url-access-select": "", + "default-url-tooltip": "", + "direct-url-tooltip": "", + "heading": "", + "proxy-url-tooltip": "", + "server-mode-description": "", + "server-mode-title": "", + "timeout-form-label": "", + "timeout-label": "", + "timeout-tooltip": "", + "url-label": "", + "with-credential-label": "", + "with-credential-tooltip": "" + }, + "data-source-settings": { + "alerting-settings-heading": "", + "alerting-settings-label": "", + "alerting-settings-tooltip": "", + "cert-key-reset": "", + "custom-headers-add": "", + "custom-headers-header": "", + "custom-headers-header-placeholder": "", + "custom-headers-header-remove": "", + "custom-headers-header-value": "", + "custom-headers-title": "", + "secure-socks-heading": "", + "secure-socks-label": "", + "secure-socks-tooltip": "", + "tls-certification-label": "", + "tls-certification-placeholder": "", + "tls-client-certification-label": "", + "tls-client-key-label": "", + "tls-client-key-placeholder": "", + "tls-heading": "", + "tls-server-name-label": "", + "tls-tooltip": "" + }, + "date-time-picker": { + "apply": "", + "calendar-icon-label": "", + "cancel": "", + "next-label": "", + "previous-label": "", + "select-placeholder": "" + }, + "drawer": { + "close": "" + }, + "feature-badge": { + "experimental": "", + "new": "", + "preview": "", + "private-preview": "" + }, + "field-link-list": { + "external-links-heading": "" + }, + "file-dropzone": { + "cancel-upload": "", + "file-too-large": "" + }, + "filter-input": { + "clear": "" + }, + "modal": { + "close-tooltip": "" + }, + "named-colors-palette": { + "text-color-swatch": "", + "transparent-swatch": "" + }, + "page-toolbar": { + "go-back": "", + "search-dashboard-name": "", + "search-links": "", + "search-parent-folder": "" + }, + "pagination": { + "next-page": "", + "previous-page": "" + }, + "secret-form-field": { + "reset": "" + }, + "segment-async": { + "error": "", + "loading": "", + "no-options": "" + }, + "select": { + "default-create-label": "", + "no-options-label": "", + "placeholder": "" + }, + "series-color-picker-popover": { + "y-axis-usage": "" + }, + "spinner": { + "aria-label": "" + }, + "table": { + "copy": "", + "csv-counts": "", + "filter-popup-apply": "", + "filter-popup-cancel": "", + "filter-popup-clear": "", + "filter-popup-heading": "", + "no-values-label": "", + "pagination-summary": "" + }, + "tags-input": { + "add": "" + }, + "user-icon": { + "active-text": "" + }, + "value-pill": { + "remove-button": "" + }, + "viz-legend": { + "right-axis-indicator": "" + }, + "viz-tooltip": { + "actions-confirmation-input-placeholder": "", + "actions-confirmation-label": "", + "actions-confirmation-message": "", + "footer-add-annotation": "", + "footer-click-to-action": "", + "footer-click-to-navigate": "" + } + }, + "graph": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "", + "title": "" + } + }, + "help-modal": { + "column-headers": { + "description": "", + "keys": "" + }, + "shortcuts-category": { + "dashboard": "", + "focused-panel": "", + "global": "", + "time-range": "" + }, + "shortcuts-description": { + "change-theme": "", + "collapse-all-rows": "", + "copy-time-range": "", + "dashboard-settings": "", + "duplicate-panel": "", + "exit-edit/setting-views": "", + "expand-all-rows": "", + "go-to-dashboards": "", + "go-to-explore": "", + "go-to-home-dashboard": "", + "go-to-profile": "", + "make-time-range-permanent": "", + "move-time-range-back": "", + "move-time-range-forward": "", + "open-search": "", + "open-shared-modal": "", + "paste-time-range": "", + "refresh-all-panels": "", + "remove-panel": "", + "save-dashboard": "", + "show-all-shortcuts": "", + "toggle-active-mode": "", + "toggle-all-panel-legends": "", + "toggle-auto-fit": "", + "toggle-exemplars": "", + "toggle-graph-crosshair": "", + "toggle-kiosk": "", + "toggle-panel-edit": "", + "toggle-panel-fullscreen": "", + "toggle-panel-legend": "", + "zoom-out-time-range": "" + }, + "title": "" + }, + "help-wizard": { + "download-snapshot": "", + "github-comment": "", + "support-bundle": "", + "troubleshooting-help": "" + }, + "inspector": { + "query": { + "collapse-all": "", + "copy-to-clipboard": "", + "description": "", + "expand-all": "", + "no-data": "", + "refresh": "" + } + }, + "ldap-drawer": { + "attributes-section": { + "description": "", + "email-label": "", + "label": "", + "member-of-label": "", + "name-label": "", + "surname-label": "", + "username-label": "" + }, + "extra-security-section": { + "client-cert-label": "", + "client-cert-placeholder": "", + "client-cert-value-label": "", + "client-cert-value-placeholder": "", + "client-key-label": "", + "client-key-placeholder": "", + "client-key-value-label": "", + "client-key-value-placeholder": "", + "encryption-provider-base-64": "", + "encryption-provider-description": "", + "encryption-provider-file-path": "", + "encryption-provider-label": "", + "label": "", + "min-tls-version-description": "", + "min-tls-version-label": "", + "root-ca-cert-label": "", + "root-ca-cert-placeholder": "", + "root-ca-cert-value-label": "", + "root-ca-cert-value-placeholder": "", + "start-tls-description": "", + "start-tls-label": "", + "tls-ciphers-label": "", + "tls-ciphers-placeholder": "", + "use-ssl-description": "", + "use-ssl-label": "", + "use-ssl-tooltip": "" + }, + "group-mapping": { + "grafana-admin": { + "description": "", + "label": "" + }, + "group-dn": { + "description": "", + "label": "" + }, + "org-id": { + "description": "", + "label": "" + }, + "org-role": { + "label": "" + }, + "remove": { + "button": "" + } + }, + "group-mapping-section": { + "add": { + "button": "" + }, + "description": "", + "group-search-base-dns-label": "", + "group-search-base-dns-placeholder": "", + "group-search-filter-description": "", + "group-search-filter-label": "", + "group-search-filter-user-attribute-description": "", + "group-search-filter-user-attribute-label": "", + "label": "", + "skip-org-role-sync-description": "", + "skip-org-role-sync-label": "" + }, + "misc-section": { + "allow-sign-up-descrition": "", + "allow-sign-up-label": "", + "label": "", + "port-description": "", + "port-label": "", + "timeout-description": "", + "timeout-label": "" + }, + "title": "" + }, + "ldap-settings-page": { + "advanced-settings-section": { + "edit-button": "", + "subtitle": "", + "title": "" + }, + "alert": { + "discard-success": "", + "error-fetching": "", + "error-saving": "", + "error-validate-form": "", + "feature-flag-disabled": "", + "saved": "" + }, + "bind-dn": { + "description": "", + "label": "", + "placeholder": "" + }, + "bind-password": { + "label": "" + }, + "buttons-section": { + "disable-button": "", + "discard-button": "", + "save-and-enable-button": "", + "save-button": "" + }, + "documentation": "", + "host": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "login-form-alert": { + "description": "", + "title": "" + }, + "search_filter": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "search-base-dns": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "subtitle": "", + "title": "" + }, + "library-panel": { + "add-modal": { + "cancel": "", + "create": "", + "error": "", + "folder": "", + "folder-description": "", + "name": "" + }, + "add-widget": { + "title": "" + }, + "empty-state": { + "message": "", + "more-info": "" + } + }, + "library-panels": { + "empty-state": { + "message": "" + }, + "loading-panel-text": "", + "modal": { + "button-cancel": "", + "button-view-panel1": "", + "button-view-panel2": "", + "panel-not-linked": "", + "select-no-options-message": "", + "select-placeholder": "", + "title": "", + "body_one": "", + "body_other": "" + }, + "save": { + "error": "", + "success": "" + } + }, + "link": { + "share": { + "config-alert-description": "", + "config-alert-title": "", + "config-description": "", + "copy-link-button": "", + "copy-to-clipboard": "", + "short-url-label": "", + "time-range-description": "", + "time-range-label": "" + }, + "share-panel": { + "config-description": "", + "download-image": "", + "render-image": "", + "render-image-error": "", + "render-image-error-description": "" + } + }, + "lock-icon": "", + "login": { + "divider": { + "connecting-text": "" + }, + "error": { + "blocked": "", + "invalid-user-or-password": "", + "title": "", + "unknown": "" + }, + "forgot-password": "", + "form": { + "confirmation-code": "", + "confirmation-code-label": "", + "confirmation-code-placeholder": "", + "email-label": "", + "email-placeholder": "", + "email-required": "", + "name-label": "", + "name-placeholder": "", + "password-label": "", + "password-placeholder": "", + "password-required": "", + "submit-label": "", + "submit-loading-label": "", + "username-label": "", + "username-placeholder": "", + "username-required": "", + "verify-email-label": "", + "verify-email-loading-label": "" + }, + "layout": { + "update-password": "" + }, + "services": { + "sing-in-with-prefix": "" + }, + "signup": { + "button-label": "", + "new-to-question": "" + } + }, + "logs": { + "infinite-scroll": { + "end-of-range": "", + "load-more": "", + "load-newer": "", + "load-older": "", + "older-logs": "" + }, + "log-details": { + "fields": "", + "links": "", + "log-line": "", + "no-details": "" + }, + "log-line-menu": { + "copy-link": "", + "copy-log": "", + "icon-label": "", + "pin-to-outline": "", + "show-context": "", + "unpin-from-outline": "" + }, + "log-row-message": { + "ellipsis": "", + "more": "", + "see-details": "" + }, + "log-rows": { + "disable-popover": { + "confirm": "", + "message": "", + "title": "" + }, + "disable-popover-message": { + "shortcut": "" + } + }, + "logs-navigation": { + "newer-logs": "", + "older-logs": "", + "scroll-bottom": "", + "scroll-top": "", + "start-of-range": "" + }, + "popover-menu": { + "copy": "", + "disable-menu": "", + "line-contains": "", + "line-contains-not": "" + } + }, + "migrate-to-cloud": { + "build-snapshot": { + "description": "", + "title": "", + "when-complete": "" + }, + "building-snapshot": { + "description": "", + "description-eta": "", + "title": "" + }, + "can-i-move": { + "body": "", + "link-title": "", + "title": "" + }, + "connect-modal": { + "body-cloud-stack": "", + "body-get-started": "", + "body-sign-up": "", + "body-token": "", + "body-token-field": "", + "body-token-field-placeholder": "", + "body-token-instructions": "", + "body-view-stacks": "", + "cancel": "", + "connect": "", + "connecting": "", + "title": "", + "token-error-title": "", + "token-errors": { + "instance-request-error": "", + "instance-unreachable": "", + "migration-disabled": "", + "session-creation-failure": "", + "token-invalid": "", + "token-not-saved": "", + "token-request-error": "", + "token-validation-failure": "" + }, + "token-required-error": "" + }, + "cta": { + "button": "", + "header": "" + }, + "delete-migration-token-confirm": { + "body": "", + "confirm-button": "", + "error-title": "", + "title": "" + }, + "disconnect-modal": { + "body": "", + "cancel": "", + "disconnect": "", + "disconnecting": "", + "error": "", + "title": "" + }, + "get-started": { + "body": "", + "configure-pdc-link": "", + "link-title": "", + "step-1": "", + "step-2": "", + "step-3": "", + "step-4": "", + "step-5": "", + "title": "" + }, + "is-it-secure": { + "body": "", + "link-title": "", + "title": "" + }, + "migrate-to-this-stack": { + "body": "", + "link-title": "", + "title": "" + }, + "migrated-counts": { + "alert_rule_groups": "", + "alert_rules": "", + "contact_points": "", + "dashboards": "", + "datasources": "", + "folders": "", + "library_elements": "", + "mute_timings": "", + "notification_policies": "", + "notification_templates": "", + "plugins": "" + }, + "migration-token": { + "delete-button": "", + "delete-modal-body": "", + "delete-modal-cancel": "", + "delete-modal-confirm": "", + "delete-modal-deleting": "", + "delete-modal-title": "", + "error-body": "", + "error-title": "", + "generate-button": "", + "generate-button-loading": "", + "modal-close": "", + "modal-copy-and-close": "", + "modal-copy-button": "", + "modal-field-description": "", + "modal-field-label": "", + "modal-title": "", + "status": "" + }, + "onprem": { + "cancel-snapshot-error-title": "", + "create-snapshot-error-title": "", + "disconnect-error-title": "", + "error-see-server-logs": "", + "get-session-error-title": "", + "get-snapshot-error-title": "", + "migration-finished-with-caveat-title": "", + "migration-finished-with-errors-body": "", + "migration-finished-with-warnings-body": "", + "snapshot-error-status-body": "", + "snapshot-error-status-title": "", + "success-message": "", + "success-message-generic": "", + "success-title": "", + "upload-snapshot-error-title": "" + }, + "pdc": { + "body": "", + "link-title": "", + "title": "" + }, + "pricing": { + "body": "", + "link-title": "", + "title": "" + }, + "public-preview": { + "button-text": "", + "message": "", + "message-cloud": "", + "title": "" + }, + "resource-details": { + "dismiss-button": "", + "error-messages": { + "dashboard-already-managed": "", + "datasource-already-managed": "", + "datasource-invalid-url": "", + "datasource-name-conflict": "", + "folder-name-conflict": "", + "generic-error": "", + "internal-service-error": "", + "library-element-name-conflict": "", + "resource-conflict": "", + "unexpected-error": "", + "unsupported-data-type": "" + }, + "error-title": "", + "generic-title": "", + "missing-message": "", + "resource-summary": "", + "title": "", + "warning-title": "" + }, + "resource-status": { + "error-details-button": "", + "failed": "", + "migrated": "", + "migrating": "", + "not-migrated": "", + "unknown": "", + "warning": "", + "warning-details-button": "" + }, + "resource-table": { + "dashboard-load-error": "", + "error-library-element-sub": "", + "error-library-element-title": "", + "unknown-datasource-title": "", + "unknown-datasource-type": "" + }, + "resource-type": { + "alert_rule": "", + "alert_rule_group": "", + "contact_point": "", + "dashboard": "", + "datasource": "", + "folder": "", + "library_element": "", + "mute_timing": "", + "notification_policy": "", + "notification_template": "", + "plugin": "", + "unknown": "" + }, + "summary": { + "cancel-snapshot": "", + "disconnect": "", + "errored-resource-count": "", + "page-loading": "", + "rebuild-snapshot": "", + "snapshot-date": "", + "snapshot-not-created": "", + "start-migration": "", + "successful-resource-count": "", + "target-stack-title": "", + "total-resource-count": "", + "upload-migration": "" + }, + "support-types-disclosure": { + "text": "" + }, + "token-status": { + "active": "", + "no-active": "", + "unknown": "", + "unknown-error": "" + }, + "what-is-cloud": { + "body": "", + "link-title": "", + "title": "" + }, + "why-host": { + "body": "", + "link-title": "", + "title": "" + } + }, + "multicombobox": { + "all": { + "title": "", + "title-filtered": "" + }, + "clear": { + "title": "" + } + }, + "nav": { + "add-new-connections": { + "title": "" + }, + "admin": { + "subtitle": "", + "title": "" + }, + "alert-list-legacy": { + "title": "" + }, + "alerting": { + "subtitle": "", + "title": "" + }, + "alerting-admin": { + "subtitle": "", + "title": "" + }, + "alerting-am-routes": { + "subtitle": "", + "title": "" + }, + "alerting-channels": { + "title": "" + }, + "alerting-groups": { + "subtitle": "", + "title": "" + }, + "alerting-home": { + "title": "" + }, + "alerting-legacy": { + "title": "" + }, + "alerting-list": { + "subtitle": "", + "title": "" + }, + "alerting-receivers": { + "subtitle": "", + "title": "" + }, + "alerting-silences": { + "subtitle": "", + "title": "" + }, + "alerting-upgrade": { + "subtitle": "", + "title": "" + }, + "alerts-and-incidents": { + "subtitle": "", + "title": "" + }, + "api-keys": { + "subtitle": "", + "title": "" + }, + "application": { + "title": "" + }, + "apps": { + "subtitle": "", + "title": "" + }, + "authentication": { + "title": "" + }, + "bookmarks": { + "title": "" + }, + "bookmarks-empty": { + "title": "" + }, + "collector": { + "title": "" + }, + "config": { + "title": "" + }, + "config-access": { + "subtitle": "", + "title": "" + }, + "config-general": { + "subtitle": "", + "title": "" + }, + "config-plugins": { + "subtitle": "", + "title": "" + }, + "connect-data": { + "title": "" + }, + "connections": { + "subtitle": "", + "title": "" + }, + "correlations": { + "subtitle": "", + "title": "" + }, + "create": { + "title": "" + }, + "create-alert": { + "title": "" + }, + "create-dashboard": { + "title": "" + }, + "create-folder": { + "title": "" + }, + "create-import": { + "title": "" + }, + "dashboards": { + "subtitle": "", + "title": "" + }, + "data-sources": { + "subtitle": "", + "title": "" + }, + "databases": { + "title": "" + }, + "datasources": { + "subtitle": "", + "title": "" + }, + "detect": { + "title": "" + }, + "drilldown": { + "title": "" + }, + "explore": { + "title": "" + }, + "frontend": { + "subtitle": "", + "title": "" + }, + "frontend-app": { + "title": "" + }, + "global-orgs": { + "subtitle": "", + "title": "" + }, + "global-users": { + "subtitle": "", + "title": "" + }, + "grafana-quaderno": { + "title": "" + }, + "groupsync": { + "subtitle": "" + }, + "help": { + "title": "" + }, + "help/community": "", + "help/documentation": "", + "help/keyboard-shortcuts": "", + "help/support": "", + "history-container": { + "drawer-tittle": "" + }, + "history-wrapper": { + "collapse": "", + "expand": "", + "icon-selected": "", + "icon-unselected": "", + "show-more": "", + "today": "", + "yesterday": "" + }, + "home": { + "title": "" + }, + "incidents": { + "title": "" + }, + "infrastructure": { + "subtitle": "", + "title": "" + }, + "integrations": { + "title": "" + }, + "k6": { + "title": "" + }, + "kubernetes": { + "title": "" + }, + "library-panels": { + "subtitle": "", + "title": "" + }, + "machine-learning": { + "title": "" + }, + "manage-folder": { + "subtitle": "" + }, + "migrate-to-cloud": { + "subtitle": "", + "title": "" + }, + "monitoring": { + "subtitle": "", + "title": "" + }, + "new": { + "title": "" + }, + "new-dashboard": { + "title": "" + }, + "new-folder": { + "title": "" + }, + "oncall": { + "title": "" + }, + "org-settings": { + "subtitle": "", + "title": "" + }, + "playlists": { + "subtitle": "", + "title": "" + }, + "plugins": { + "subtitle": "", + "title": "" + }, + "private-data-source-connections": { + "subtitle": "", + "title": "" + }, + "profile/notifications": { + "title": "" + }, + "profile/password": { + "title": "" + }, + "profile/settings": { + "title": "" + }, + "profiles": { + "title": "" + }, + "public": { + "title": "" + }, + "recently-deleted": { + "subtitle": "", + "title": "" + }, + "recorded-queries": { + "title": "" + }, + "reporting": { + "title": "" + }, + "scenes": { + "title": "" + }, + "search": { + "placeholderCommandPalette": "" + }, + "search-dashboards": { + "title": "" + }, + "server-settings": { + "subtitle": "", + "title": "" + }, + "service-accounts": { + "subtitle": "", + "title": "" + }, + "setup-guide": { + "title": "" + }, + "shared-dashboard": { + "subtitle": "", + "title": "" + }, + "sign-out": { + "title": "" + }, + "slo": { + "title": "" + }, + "snapshots": { + "subtitle": "", + "title": "" + }, + "starred": { + "title": "" + }, + "starred-empty": { + "title": "" + }, + "statistics-and-licensing": { + "title": "" + }, + "storage": { + "subtitle": "", + "title": "" + }, + "support-bundles": { + "subtitle": "", + "title": "" + }, + "synthetics": { + "title": "" + }, + "teams": { + "subtitle": "", + "title": "" + }, + "testing-and-synthetics": { + "subtitle": "", + "title": "" + }, + "upgrading": { + "title": "" + }, + "users": { + "subtitle": "", + "title": "" + } + }, + "navigation": { + "invite-user": { + "invite-button": "", + "invite-tooltip": "" + }, + "item": { + "add-bookmark": "", + "remove-bookmark": "" + }, + "kiosk": { + "tv-alert": "" + }, + "megamenu": { + "close": "", + "dock": "", + "list-label": "", + "open": "", + "undock": "" + }, + "rss-button": "" + }, + "news": { + "drawer": { + "close": "" + }, + "title": "" + }, + "notifications": { + "empty-state": { + "description": "", + "title": "" + }, + "starred-dashboard": "", + "unstarred-dashboard": "" + }, + "oauth": { + "form": { + "server-discovery-action-button": "", + "server-discovery-modal-close": "", + "server-discovery-modal-loading": "", + "server-discovery-modal-submit": "" + }, + "login": { + "error": "" + } + }, + "panel": { + "header-menu": { + "copy": "", + "create-library-panel": "", + "duplicate": "", + "edit": "", + "explore": "", + "get-help": "", + "hide-legend": "", + "inspect": "", + "inspect-data": "", + "inspect-json": "", + "more": "", + "new-alert-rule": "", + "query": "", + "remove": "", + "replace-library-panel": "", + "share": "", + "show-legend": "", + "unlink-library-panel": "", + "view": "" + } + }, + "panel-search": { + "no-matches": "", + "unsupported-layout": "" + }, + "panel-type-filter": { + "clear-button": "" + }, + "playlist-edit": { + "error-prefix": "", + "form": { + "add-tag-label": "", + "add-tag-placeholder": "", + "add-title-label": "", + "cancel": "", + "heading": "", + "interval-label": "", + "interval-placeholder": "", + "interval-required": "", + "name-label": "", + "name-placeholder": "", + "name-required": "", + "save": "", + "table-delete": "", + "table-drag": "", + "table-empty": "", + "table-heading": "" + }, + "sub-title": "", + "title": "" + }, + "playlist-page": { + "card": { + "delete": "", + "edit": "", + "start": "", + "tooltip": "" + }, + "create-button": { + "title": "" + }, + "delete-modal": { + "body": "", + "confirm-text": "" + }, + "empty": { + "button": "", + "pro-tip": "", + "title": "" + } + }, + "playlists": { + "empty-state": { + "message": "" + } + }, + "plugins": { + "catalog": { + "no-updates-available": "", + "update-all": { + "all-plugins-updated": "", + "available-header": "", + "button": "", + "cloud-update-message": "", + "error": "", + "error-status-text": "", + "header": "", + "installed-header": "", + "modal-confirmation": "", + "modal-dismiss": "", + "modal-in-progress": "", + "modal-title": "", + "name-header": "", + "update-header": "", + "update-status-text": "" + }, + "versions": { + "confirmation-text-1": "", + "confirmation-text-2": "", + "downgrade-confirm": "", + "downgrade-title": "" + } + }, + "details": { + "connections-tab": { + "description": "" + }, + "labels": { + "contactGrafanaLabs": "", + "customLinks": "", + "customLinksTooltip": "", + "dependencies": "", + "documentation": "", + "downloads": "", + "from": "", + "installedVersion": "", + "lastCommitDate": "", + "latestVersion": "", + "license": "", + "raiseAnIssue": "", + "reportAbuse": "", + "reportAbuseTooltip": "", + "repository": "", + "signature": "", + "status": "", + "updatedAt": "" + }, + "modal": { + "cancel": "", + "copyEmail": "", + "description": "", + "node": "", + "title": "" + } + }, + "empty-state": { + "message": "" + }, + "filter": { + "disabled": "", + "sort": "", + "sort-list": "", + "state": "" + }, + "plugin-help": { + "error": "", + "not-found": "" + } + }, + "profile": { + "change-password": { + "cancel-button": "", + "cannot-change-password-message": "", + "change-password-button": "", + "confirm-password-label": "", + "confirm-password-required": "", + "ldap-auth-proxy-message": "", + "new-password-label": "", + "new-password-required": "", + "new-password-same-as-old": "", + "old-password-label": "", + "old-password-required": "", + "passwords-must-match": "", + "strong-password-validation-register": "" + } + }, + "public-dashboard": { + "acknowledgment-checkboxes": { + "ack-title": "", + "data-src-ack-desc": "", + "data-src-ack-tooltip": "", + "public-ack-desc": "", + "public-ack-tooltip": "", + "usage-ack-desc": "", + "usage-ack-desc-tooltip": "" + }, + "config": { + "can-view-dashboard-radio-button-label": "", + "copy-button": "", + "dashboard-url-field-label": "", + "email-share-type-option-label": "", + "pause-sharing-dashboard-label": "", + "public-share-type-option-label": "", + "revoke-public-URL-button": "", + "revoke-public-URL-button-title": "", + "settings-title": "" + }, + "configuration": { + "display-annotations-description": "", + "display-annotations-label": "", + "enable-time-range-description": "", + "enable-time-range-label": "", + "settings-label": "", + "success-pause": "", + "success-resume": "", + "success-update": "", + "success-update-old": "", + "time-range-label": "", + "time-range-tooltip": "" + }, + "create-page": { + "generate-public-url-button": "", + "unsupported-features-desc": "", + "welcome-title": "" + }, + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "email-sharing": { + "accept-button": "", + "alert-text": "", + "bill-ack": "", + "cancel-button": "", + "input-invalid-email-text": "", + "input-required-email-text": "", + "invite-button": "", + "invite-field-desc": "", + "invite-field-label": "", + "learn-more-button": "", + "recipient-email-placeholder": "", + "recipient-invalid-email-text": "", + "recipient-invitation-button": "", + "recipient-invitation-description": "", + "recipient-invitation-tooltip": "", + "recipient-list-description": "", + "recipient-list-title": "", + "recipient-required-email-text": "", + "resend-button": "", + "resend-button-title": "", + "resend-invite-label": "", + "revoke-access-label": "", + "revoke-button": "", + "revoke-button-title": "", + "success-creation": "", + "success-share-type-change": "" + }, + "modal-alerts": { + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "save-dashboard-changes-alert-title": "", + "unsupport-data-source-alert-readmore-link": "", + "unsupported-data-source-alert-desc": "", + "unsupported-data-source-alert-title": "", + "unsupported-template-variable-alert-desc": "", + "unsupported-template-variable-alert-title": "" + }, + "public-sharing": { + "accept-button": "", + "alert-text": "", + "cancel-button": "", + "learn-more-button": "", + "public-ack": "", + "success-creation": "", + "success-share-type-change": "" + }, + "settings-bar-header": { + "collapse-settings-tooltip": "", + "expand-settings-tooltip": "" + }, + "settings-configuration": { + "default-time-range-label": "", + "default-time-range-label-desc": "", + "show-annotations-label": "", + "show-annotations-label-desc": "", + "time-range-picker-label": "", + "time-range-picker-label-desc": "" + }, + "settings-summary": { + "annotations-hide-text": "", + "annotations-show-text": "", + "time-range-picker-disabled-text": "", + "time-range-picker-enabled-text": "", + "time-range-text": "" + }, + "share": { + "success-delete": "", + "success-delete-old": "" + }, + "share-configuration": { + "share-type-label": "" + }, + "share-externally": { + "copy-link-button": "", + "email-share-type-option-description": "", + "email-share-type-option-label": "", + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "pause-access-button": "", + "pause-access-tooltip": "", + "public-share-type-option-description": "", + "public-share-type-option-label": "", + "resume-access-button": "", + "revoke-access-button": "", + "revoke-access-description": "", + "unsupported-data-source-alert-desc": "" + }, + "sharing": { + "success-creation": "" + } + }, + "public-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "public-dashboard-users-access-list": { + "dashboard-modal": { + "external-link": "", + "loading-text": "", + "open-dashboard-list-text": "", + "public-dashboard-link": "", + "public-dashboard-setting": "", + "sharing-setting": "" + }, + "delete-user-modal": { + "delete-user-button-text": "", + "delete-user-cancel-button": "", + "delete-user-revoke-access-button": "", + "revoke-access-title": "", + "revoke-user-access-modal-desc-line1": "", + "revoke-user-access-modal-desc-line2": "" + }, + "delete-user-shared-dashboards-modal": { + "revoke-user-access-modal-desc-line2": "" + }, + "modal": { + "dashboard-modal-title": "", + "shared-dashboard-modal-title": "" + }, + "table-body": { + "dashboard-count_one": "", + "dashboard-count_other": "" + }, + "table-header": { + "activated-label": "", + "activated-tooltip": "", + "email-label": "", + "last-active-label": "", + "origin-label": "", + "role-label": "" + } + }, + "query-operation": { + "header": { + "collapse-row": "", + "datasource-help": "", + "drag-and-drop": "", + "duplicate-query": "", + "expand-row": "", + "hide-response": "", + "remove-query": "", + "show-response": "", + "toggle-edit-mode": "" + }, + "query-editor-not-exported": "" + }, + "recently-deleted": { + "buttons": { + "delete": "", + "restore": "" + }, + "page": { + "no-deleted-dashboards": "", + "no-deleted-dashboards-text": "", + "no-search-result": "" + }, + "permanently-delete-modal": { + "confirm-text": "", + "delete-button": "", + "delete-loading": "", + "title": "", + "text_one": "", + "text_other": "" + }, + "restore-modal": { + "restore-button": "", + "restore-loading": "", + "title": "", + "folder-picker-text_one": "", + "folder-picker-text_other": "", + "text_one": "", + "text_other": "" + } + }, + "recentlyDeleted": { + "filter": { + "placeholder": "" + } + }, + "reduce": { + "strictMode": { + "description": "", + "title": "" + } + }, + "refresh-picker": { + "aria-label": { + "choose-interval": "", + "duration-selected": "" + }, + "auto-option": { + "aria-label": "", + "label": "" + }, + "live-option": { + "aria-label": "", + "label": "" + }, + "off-option": { + "aria-label": "", + "label": "" + }, + "tooltip": { + "interval-selected": "", + "turned-off": "" + } + }, + "return-to-previous": { + "button": { + "label": "" + }, + "dismissable-button": "" + }, + "role-picker": { + "built-in": { + "basic-roles": "" + }, + "input": { + "no-roles": "" + }, + "menu": { + "clear-button": "", + "tooltip": "" + }, + "sub-menu": { + "clear-button": "" + }, + "title": { + "description": "" + } + }, + "role-picker-drawer": { + "basic-roles": { + "label": "" + } + }, + "route-error": { + "description": "", + "reload-button": "", + "title": "" + }, + "save-dashboards": { + "message-length": { + "info": "", + "title": "" + }, + "name-exists": { + "message-info": "", + "message-suggestion": "", + "title": "" + } + }, + "scopes": { + "dashboards": { + "collapse": "", + "expand": "", + "loading": "", + "noResultsForFilter": "", + "noResultsForFilterClear": "", + "noResultsForScopes": "", + "noResultsNoScopes": "", + "search": "", + "toggle": { + "collapse": "", + "disabled": "", + "expand": "" + } + }, + "selector": { + "apply": "", + "cancel": "", + "input": { + "placeholder": "", + "removeAll": "" + }, + "title": "" + }, + "tree": { + "collapse": "", + "expand": "", + "headline": { + "noResults": "", + "recommended": "", + "results": "" + }, + "search": "" + } + }, + "search": { + "actions": { + "include-panels": "", + "remove-datasource-filter": "", + "sort-placeholder": "", + "starred": "", + "view-as-folders": "", + "view-as-list": "" + }, + "dashboard-actions": { + "import": "", + "new": "", + "new-dashboard": "", + "new-folder": "" + }, + "results-table": { + "datasource-header": "", + "deleted-less-than-1-min": "", + "deleted-remaining-header": "", + "location-header": "", + "name-header": "", + "tags-header": "", + "type-dashboard": "", + "type-folder": "", + "type-header": "" + }, + "search-input": { + "include-panels-placeholder": "", + "placeholder": "" + } + }, + "select": { + "select-menu": { + "selected-count": "" + } + }, + "service-account-create-page": { + "create": { + "button": "" + }, + "name": { + "label": "", + "required-error": "" + }, + "page-nav": { + "label": "" + }, + "role": { + "label": "" + } + }, + "service-accounts": { + "empty-state": { + "button-title": "", + "message": "", + "more-info": "", + "title": "" + } + }, + "share-dashboard": { + "menu": { + "export-json-title": "", + "share-externally-title": "", + "share-internally-title": "", + "share-snapshot-title": "" + }, + "share-button": "", + "share-button-tooltip": "" + }, + "share-drawer": { + "confirm-action": { + "back-arrow-button": "", + "cancel-button": "" + } + }, + "share-modal": { + "dashboard": { + "title": "" + }, + "embed": { + "copy": "", + "html": "", + "html-description": "", + "info": "", + "time-range": "" + }, + "export": { + "back-button": "", + "cancel-button": "", + "info-text": "", + "loading": "", + "save-button": "", + "share-externally-label": "", + "view-button": "" + }, + "library": { + "info": "" + }, + "link": { + "copy-link-button": "", + "info-text": "", + "link-url": "", + "render-alert": "", + "render-instructions": "", + "rendered-image": "", + "save-alert": "", + "save-dashboard": "", + "shorten-url": "", + "time-range-description": "", + "time-range-label": "" + }, + "panel": { + "title": "" + }, + "snapshot": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "deleted-message": "", + "expire": "", + "expire-day": "", + "expire-hour": "", + "expire-never": "", + "expire-week": "", + "info-text-1": "", + "info-text-2": "", + "local-button": "", + "mistake-message": "", + "name": "", + "timeout": "", + "timeout-description": "", + "url-label": "" + }, + "tab-title": { + "embed": "", + "export": "", + "library-panel": "", + "link": "", + "panel-embed": "", + "public-dashboard": "", + "public-dashboard-title": "", + "snapshot": "" + }, + "theme-picker": { + "current": "", + "dark": "", + "field-name": "", + "light": "" + }, + "view-json": { + "copy-button": "" + } + }, + "share-panel": { + "drawer": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "" + }, + "menu": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "", + "share-snapshot-title": "" + }, + "new-library-panel": { + "cancel-button": "", + "create-button": "" + } + }, + "share-panel-image": { + "preview": { + "title": "" + }, + "settings": { + "height-label": "", + "height-min": "", + "height-placeholder": "", + "height-required": "", + "max-warning": "", + "scale-factor-label": "", + "scale-factor-min": "", + "scale-factor-placeholder": "", + "scale-factor-required": "", + "title": "", + "width-label": "", + "width-min": "", + "width-placeholder": "", + "width-required": "" + } + }, + "share-playlist": { + "checkbox-description": "", + "checkbox-label": "", + "copy-link-button": "", + "link-url-label": "", + "mode": "", + "mode-kiosk": "", + "mode-normal": "", + "title": "" + }, + "shared": { + "preferences": { + "theme": { + "dark-label": "", + "light-label": "", + "system-label": "" + } + } + }, + "shared-dashboard": { + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "fields": { + "timezone-label": "" + } + }, + "shared-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "shared-preferences": { + "fields": { + "home-dashboard-label": "", + "home-dashboard-placeholder": "", + "locale-label": "", + "locale-placeholder": "", + "theme-description": "", + "theme-label": "", + "week-start-label": "" + }, + "theme": { + "default-label": "" + }, + "title": "" + }, + "sign-up": { + "back-button": "", + "submit-button": "", + "verify": { + "back-button": "", + "complete-button": "", + "header": "", + "info": "", + "send-button": "" + } + }, + "silences": { + "empty-state": { + "button-title": "", + "title": "" + }, + "table": { + "add-silence-button": "", + "edit-button": "", + "expired-silences": "", + "no-matching-silences": "", + "noConfig": "", + "recreate-button": "", + "unsilence-button": "" + } + }, + "silences-table": { + "header": { + "alert-name": "", + "state": "" + } + }, + "snapshot": { + "empty-state": { + "message": "", + "more-info": "" + }, + "external-badge": "", + "name-column-header": "", + "share": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "delete-description": "", + "delete-permission-tooltip": "", + "delete-title": "", + "deleted-alert": "", + "expiration-label": "", + "info-alert": "", + "learn-more-button": "", + "local-button": "", + "name-label": "", + "new-snapshot-button": "", + "success-creation": "", + "success-delete": "", + "view-all-button": "" + }, + "share-panel": { + "info-alert": "" + }, + "url-column-header": "", + "view-button": "" + }, + "table": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "" + } + }, + "tag-filter": { + "clear-button": "", + "loading": "", + "no-tags": "", + "placeholder": "" + }, + "teams": { + "empty-state": { + "button-title": "", + "message": "", + "pro-tip": "", + "title": "" + } + }, + "theme-preview": { + "breadcrumbs": { + "dashboards": "", + "home": "" + }, + "panel": { + "form-label": "", + "title": "" + } + }, + "time-picker": { + "absolute": { + "recent-title": "", + "title": "" + }, + "calendar": { + "apply-button": "", + "cancel-button": "", + "close": "", + "next-month": "", + "previous-month": "", + "select-time": "" + }, + "content": { + "empty-recent-list-docs": "", + "empty-recent-list-info": "", + "filter-placeholder": "" + }, + "copy-paste": { + "copy-success-message": "", + "default-error-message": "", + "default-error-title": "", + "tooltip-copy": "", + "tooltip-paste": "" + }, + "footer": { + "change-settings-button": "", + "fiscal-year-option": "", + "fiscal-year-start": "", + "time-zone-option": "", + "time-zone-selection": "" + }, + "range-content": { + "apply-button": "", + "default-error": "", + "fiscal-year": "", + "from-input": "", + "open-input-calendar": "", + "range-error": "", + "to-input": "" + }, + "range-picker": { + "backwards-time-aria-label": "", + "current-time-selected": "", + "forwards-time-aria-label": "", + "to": "", + "zoom-out-button": "", + "zoom-out-tooltip": "" + }, + "time-range": { + "apply": "", + "aria-role": "", + "default-title": "", + "example": "", + "example-details": "", + "example-title": "", + "from-label": "", + "from-to": "", + "more-info": "", + "specify": "", + "submit-button-label": "", + "supported-formats": "", + "to-label": "" + }, + "zone": { + "select-aria-label": "", + "select-search-input": "" + } + }, + "trails": { + "bookmarks": { + "or-view-bookmarks": "" + }, + "card": { + "date-created": "" + }, + "home": { + "learn-more": "", + "lets-start": "", + "start-your-metrics-exploration": "", + "subtitle": "" + }, + "metric-select": { + "filter-by": "", + "native-histogram": "", + "new-badge": "", + "otel-switch": "" + }, + "native-histogram-banner": { + "ch-heatmap": "", + "ch-histogram": "", + "click-histogram": "", + "hide-examples": "", + "learn-more": "", + "metric-examples": "", + "nh-heatmap": "", + "nh-histogram": "", + "now": "", + "previously": "", + "see-examples": "", + "sentence": "" + }, + "recent-metrics": { + "or-view-a-recent-exploration": "" + }, + "settings": { + "always-keep-selected-metric-graph-in-view": "", + "show-previews-of-metric-graphs": "" + } + }, + "transformations": { + "empty": { + "add-transformation-body": "", + "add-transformation-header": "" + } + }, + "upgrade-box": { + "discovery-text": "", + "discovery-text-continued": "", + "get-started": "", + "learn-more": "", + "upgrade-button": "" + }, + "user-orgs": { + "current-org-button": "", + "name-column": "", + "role-column": "", + "select-org-button": "", + "title": "" + }, + "user-profile": { + "fields": { + "email-error": "", + "email-label": "", + "name-error": "", + "name-label": "", + "username-label": "" + }, + "tabs": { + "general": "" + } + }, + "user-session": { + "auth-module-column": "", + "browser-column": "", + "created-at-column": "", + "identity-provider-column": "", + "ip-column": "", + "revoke": "", + "seen-at-column": "" + }, + "user-sessions": { + "loading": "" + }, + "users": { + "empty-state": { + "message": "" + } + }, + "users-access-list": { + "tabs": { + "public-dashboard-users-tab-title": "", + "shared-dashboard-users-tab-title": "" + } + }, + "variable": { + "adhoc": { + "placeholder": "" + }, + "dropdown": { + "placeholder": "" + }, + "picker": { + "link-all": "", + "option-all": "", + "option-selected-values": "", + "option-tooltip": "" + }, + "textbox": { + "placeholder": "" + } + }, + "variables": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + }, + "unknown-table": { + "loading": "", + "no-unknowns": "", + "renamed-or-missing-variables": "", + "variable": "" + } + } +} \ No newline at end of file diff --git a/public/locales/ja-JP/grafana.json b/public/locales/ja-JP/grafana.json new file mode 100644 index 00000000000..7d47740aff8 --- /dev/null +++ b/public/locales/ja-JP/grafana.json @@ -0,0 +1,3996 @@ +{ + "_comment": "", + "access-control": { + "add-permission": { + "role-label": "", + "serviceaccount-label": "", + "team-label": "", + "title": "", + "user-label": "" + }, + "add-permissions": { + "save": "" + }, + "permission-list": { + "permission": "" + }, + "permission-list-item": { + "inherited": "" + }, + "permissions": { + "add-label": "", + "no-permissions": "", + "permissions-change-warning": "", + "role": "", + "serviceaccount": "", + "team": "", + "title": "", + "user": "" + } + }, + "action-editor": { + "modal": { + "cancel-button": "", + "save-button": "" + } + }, + "admin": { + "anon-users": { + "not-found": "" + }, + "edit-org": { + "access-denied": "", + "heading": "", + "update-button": "", + "users-heading": "" + }, + "feature-toggles": { + "sub-title": "" + }, + "get-enterprise": { + "contact-us": "", + "description": "", + "features-heading": "", + "included-description": "", + "included-heading": "", + "service-title": "", + "team-sync-details": "", + "title": "" + }, + "ldap": { + "test-mapping-heading": "", + "test-mapping-run-button": "" + }, + "ldap-permissions": { + "active": "", + "admin": "", + "inactive": "" + }, + "ldap-status": { + "title": "" + }, + "ldap-sync": { + "debug-button": "", + "external-sync-description": "", + "external-sync-label": "", + "next-sync-label": "", + "not-enabled": "", + "sync-button": "", + "title": "" + }, + "ldap-sync-info": { + "title": "" + }, + "ldap-user-groups": { + "no-org-found": "" + }, + "ldap-user-info": { + "no-team": "" + }, + "org-uers": { + "last-seen-never": "" + }, + "org-users": { + "not-editable": "" + }, + "orgs": { + "delete-body": "", + "id-header": "", + "name-header": "", + "new-org-button": "" + }, + "server-settings": { + "alerts-button": "", + "dashboards-button": "", + "data-sources-button": "", + "not-found": "", + "title": "", + "users-button": "" + }, + "settings": { + "info-description": "" + }, + "upgrade-info": { + "title": "" + }, + "user-orgs": { + "add-button": "", + "change-role-button": "", + "external-user-tooltip": "", + "remove-button": "", + "role-not-editable": "", + "title": "" + }, + "user-orgs-modal": { + "add-button": "", + "cancel-button": "" + }, + "user-permissions": { + "change-button": "", + "grafana-admin-key": "", + "grafana-admin-no": "", + "grafana-admin-yes": "", + "title": "" + }, + "user-profile": { + "delete-button": "", + "disable-button": "", + "edit-button": "", + "enable-button": "", + "title": "" + }, + "user-sessions": { + "browser-column": "", + "force-logout-all-button": "", + "force-logout-button": "", + "ip-column": "", + "last-seen-column": "", + "logged-on-column": "", + "title": "" + }, + "users-create": { + "create-button": "" + }, + "users-list": { + "create-button": "" + }, + "users-table": { + "last-seen-never": "", + "no-licensed-roles": "" + } + }, + "alert-labels": { + "button": { + "hide": "", + "show": { + "tooltip": "" + } + } + }, + "alerting": { + "alert": { + "alert-state": "", + "annotations": "", + "evaluation": "", + "evaluation-paused": "", + "evaluation-paused-description": "", + "last-evaluated": "", + "last-evaluation-duration": "", + "last-updated-at": "", + "last-updated-by": "", + "no-annotations": "", + "pending-period": "", + "rule": "", + "rule-identifier": "", + "rule-type": "", + "state-error-timeout": "", + "state-no-data": "", + "target-datasource-uid": "" + }, + "alert-recording-rule-form": { + "evaluation-behaviour": { + "description": { + "text": "" + } + } + }, + "alert-rules": { + "firing-for": "", + "next-evaluation": "", + "next-evaluation-in": "", + "rule-definition": "" + }, + "alertform": { + "labels": { + "alerting": "", + "recording": "" + } + }, + "alertVersionHistory": { + "alerting": "", + "alerting-change-description": "", + "annotations": "", + "compare": "", + "compare-with-latest": "", + "compareVersions": "", + "comparing-versions": "", + "condition": "", + "contactPointRouting": "", + "description": "", + "errorloading": "", + "execErrorState": "", + "intervalSeconds": "", + "labels": "", + "latest": "", + "name": "", + "namespace_uid": "", + "noDataState": "", + "noVersionsFound": "", + "paused": "", + "pendingPeriod": "", + "provisioning": "", + "provisioning-change-description": "", + "queryAndAlertCondition": "", + "restore": "", + "restore-manually": "", + "restore-modal": { + "body": "", + "confirm": "", + "error": "", + "summary": "", + "title": "" + }, + "restore-version": "", + "rule_group": "", + "unknown": "", + "unknown-change-description": "", + "user-id": "", + "warning-restore-manually": "", + "warning-restore-manually-title": "" + }, + "annotations": { + "description": "", + "title": "" + }, + "central-alert-history": { + "details": { + "error": "", + "header": { + "alert-rule": "", + "instance": "", + "state": "", + "timestamp": "" + }, + "loading": "", + "no-recognized-state": "", + "no-values": "", + "not-found": "", + "number-transitions": "", + "state": { + "alerting": "", + "error": "", + "no-data": "", + "normal": "", + "pending": "" + }, + "state-transitions": "", + "unknown-event-state": "", + "unknown-rule": "", + "value-in-transition": "" + }, + "error": "", + "filter": { + "clear": "", + "info": { + "label1": "", + "label2": "", + "label3": "", + "label4": "" + } + }, + "filterBy": "", + "too-many-events": { + "text": "", + "title": "" + } + }, + "common": { + "cancel": "", + "clear-filters": "", + "delete": "", + "edit": "", + "export": "", + "export-all": "", + "loading": "", + "search-by-matchers": "", + "titles": { + "notification-templates": "" + }, + "view": "" + }, + "contact-points": { + "create": "", + "custom-template-value": "", + "delete-reasons": { + "heading": "", + "no-permissions": "", + "policies": "", + "provisioned": "", + "rules": "" + }, + "delivered-to": "", + "delivery-duration": "", + "empty-state": { + "title": "" + }, + "key-value-map": { + "add": "", + "confirm-add": "" + }, + "last-delivery-attempt": "", + "last-delivery-failed": "", + "no-contact-points-found": "", + "no-delivery-attempts": "", + "no-integrations": "", + "only-firing": "", + "receiver-summary": { + "jira": "" + }, + "telegram": { + "parse-mode-warning-body": "", + "parse-mode-warning-title": "" + }, + "used-by_other": "", + "used-by-rules_other": "" + }, + "contactPointFilter": { + "label": "" + }, + "copy-to-clipboard": "", + "dag": { + "missing-reference": "", + "self-reference": "" + }, + "export": { + "subtitle": { + "formats": "", + "one-format": "" + } + }, + "folderAndGroup": { + "evaluation": { + "modal": { + "text": { + "alerting": "", + "recording": "" + } + } + } + }, + "group-actions": { + "actions-trigger": "", + "delete": "", + "edit": "", + "export": "", + "reorder": "" + }, + "list-view": { + "empty": { + "new-alert-rule": "", + "new-recording-rule": "", + "provisioning": "" + }, + "section": { + "dataSourceManaged": { + "title": "" + }, + "grafanaManaged": { + "export-new-rule": "", + "export-rules": "", + "loading": "", + "new-recording-rule": "", + "title": "" + } + } + }, + "manage-permissions": { + "button": "", + "title": "" + }, + "mute_timings": { + "error-loading": { + "description": "", + "title": "" + } + }, + "mute-timings": { + "add-mute-timing": "", + "description": "", + "save": "", + "saving": "" + }, + "notification-preview": { + "alertmanager": "", + "error": "", + "initialized": "", + "preview-routing": "", + "title": "", + "uninitialized": "" + }, + "notification-templates": { + "duplicate": { + "subTitle": "", + "title": "" + }, + "edit": { + "subTitle": "", + "title": "" + }, + "new": { + "subTitle": "", + "title": "" + } + }, + "policies": { + "default-policy": { + "description": "", + "title": "", + "update": "" + }, + "delete": { + "confirm": "", + "warning-1": "", + "warning-2": "" + }, + "filter-description": "", + "generated-policies": "", + "matchers": "", + "metadata": { + "active-time": "", + "delivered-to": "", + "grouped-by": "", + "grouping": { + "none": "", + "single-group": "" + }, + "inherited": "", + "mute-time": "", + "timingOptions": { + "groupInterval": { + "description": "", + "label": "" + }, + "groupWait": { + "description": "", + "label": "" + }, + "repeatInterval": { + "description": "", + "label": "" + } + }, + "n-instances_other": "" + }, + "new-child": "", + "new-policy": "", + "no-matchers": "", + "reload-policies": "", + "save-policy": "", + "update": { + "please-wait": "", + "update-policy": "", + "updating": "" + }, + "update-errors": { + "conflict": "", + "error-code": "", + "fallback": "", + "suffix": "", + "title": "" + }, + "n-more-policies_other": "" + }, + "provisioning": { + "badge-tooltip-provenance": "", + "badge-tooltip-standard": "" + }, + "queryAndExpressionsStep": { + "disableAdvancedOptions": { + "text": "" + }, + "preview": "", + "previewCondition": "" + }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, + "rule-form": { + "evaluation": { + "evaluation-group-and-interval": "", + "group": { + "cancel": "", + "create": "", + "interval": "" + }, + "group-name": "", + "group-text": "", + "new-group": "", + "pause": { + "alerting": "", + "recording": "" + }, + "select-folder-before": "" + }, + "evaluation-behaviour": { + "description": { + "text": "" + }, + "info-help": { + "text": "" + }, + "pending-period": "" + }, + "evaluation-behaviour-description1": "", + "evaluation-behaviour-description2": "", + "evaluation-behaviour-description3": "", + "evaluation-behaviour-for": { + "error-parsing": "", + "validation": "" + }, + "folder": { + "cancel": "", + "create": "", + "create-folder": "", + "creating-new-folder": "", + "label": "", + "name": "", + "new-folder": "", + "new-folder-or": "" + }, + "folder-and-labels": "", + "folders": { + "help-info": "" + }, + "labels": { + "help-info": "" + }, + "pause": { + "label": "" + }, + "threshold": { + "recovery": { + "stop-alerting-above": "", + "stop-alerting-bellow": "", + "stop-alerting-equal": "", + "stop-alerting-inside-range": "", + "stop-alerting-less": "", + "stop-alerting-more": "", + "stop-alerting-not-equal": "", + "stop-alerting-outside-range": "", + "title": "" + } + } + }, + "rule-groups": { + "delete": { + "success": "" + }, + "move": { + "success": "" + }, + "rename": { + "success": "" + }, + "update": { + "success": "" + } + }, + "rule-list": { + "configure-datasource": "", + "ds-error-boundary": { + "description": "", + "title": "" + }, + "filter-view": { + "no-more-results": "", + "no-rules-found": "" + }, + "new-alert-rule": "", + "pagination": { + "next-page": "", + "previous-page": "" + }, + "return-button": { + "title": "" + }, + "rulerrule-loading-error": "" + }, + "rule-state": { + "creating": "", + "deleting": "", + "paused": "", + "recording-rule": "" + }, + "rule-view": { + "query": { + "datasources-na": { + "description": "", + "title": "" + } + } + }, + "rule-viewer": { + "error-loading": "", + "prometheus-consistency-check": { + "alert-message": "", + "alert-title": "" + } + }, + "rules": { + "add-rule": { + "success": "" + }, + "delete-rule": { + "success": "" + }, + "pause-rule": { + "success": "" + }, + "resume-rule": { + "success": "" + }, + "update-rule": { + "success": "" + } + }, + "search": { + "property": { + "data-source": "", + "evaluation-group": "", + "labels": "", + "namespace": "", + "rule-health": "", + "rule-name": "", + "rule-type": "", + "state": "" + }, + "save-query": "" + }, + "silences": { + "affected-instances": "", + "only-firing-instances": "", + "preview-affected-instances": "" + }, + "simpleCondition": { + "alertCondition": "" + }, + "templates": { + "editor": { + "add-example": "", + "auto-complete": "", + "goto-docs": "" + }, + "help": { + "intro": "" + }, + "misconfigured-badge-text": "", + "misconfigured-warning": "", + "misconfigured-warning-details": "" + }, + "threshold": { + "to": "" + } + }, + "annotations": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + } + }, + "api-keys": { + "empty-state": { + "message": "" + } + }, + "app-chrome": { + "skip-content-button": "", + "top-bar": { + "sign-in": "" + } + }, + "app-notification": { + "item": { + "trace-id": "" + } + }, + "bookmarks-page": { + "empty": { + "message": "", + "tip": "" + } + }, + "bouncing-loader": { + "label": "" + }, + "browse-dashboards": { + "action": { + "cancel-button": "", + "cannot-move-folders": "", + "confirmation-text": "", + "delete-button": "", + "delete-modal-invalid-text": "", + "delete-modal-invalid-title": "", + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "delete-modal-title": "", + "deleting": "", + "manage-permissions-button": "", + "move-button": "", + "move-modal-alert": "", + "move-modal-field-label": "", + "move-modal-text": "", + "move-modal-title": "", + "moving": "", + "new-folder-name-required-phrase": "" + }, + "actions": { + "button-to-recently-deleted": "" + }, + "counts": { + "alertRule_other": "", + "dashboard_other": "", + "folder_other": "", + "libraryPanel_other": "", + "total_other": "" + }, + "dashboards-tree": { + "collapse-folder-button": "", + "expand-folder-button": "", + "name-column": "", + "select-all-header-checkbox": "", + "select-checkbox": "", + "tags-column": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "", + "title-folder": "" + }, + "folder-actions-button": { + "delete": "", + "folder-actions": "", + "manage-permissions": "", + "move": "" + }, + "folder-picker": { + "accessible-label": "", + "button-label": "", + "clear-selection": "", + "empty-message": "", + "error-title": "", + "non-folder-item": "", + "search-placeholder": "", + "unknown-error": "" + }, + "hard-delete": { + "success": "" + }, + "manage-folder-nav": { + "alert-rules": "", + "dashboards": "", + "panels": "" + }, + "new-folder-form": { + "cancel-label": "", + "create-label": "", + "name-label": "" + }, + "no-results": { + "clear": "", + "text": "" + }, + "soft-delete": { + "success": "" + } + }, + "clipboard-button": { + "inline-toast": { + "success": "" + } + }, + "combobox": { + "async": { + "error": "" + }, + "clear": { + "title": "" + }, + "custom-value": { + "description": "" + }, + "group": { + "undefined": "" + }, + "options": { + "no-found": "" + } + }, + "command-palette": { + "action": { + "change-theme": "", + "dark-theme": "", + "light-theme": "" + }, + "empty-state": { + "message": "" + }, + "search-box": { + "placeholder": "" + }, + "section": { + "actions": "", + "dashboard-search-results": "", + "folder-search-results": "", + "pages": "", + "preferences": "", + "recent-dashboards": "" + } + }, + "common": { + "apply": "", + "cancel": "", + "clear": "", + "close": "", + "collapse": "", + "edit": "", + "help": "", + "loading": "", + "locale": { + "default": "" + }, + "save": "", + "search": "", + "view": "" + }, + "configuration-tracker": { + "config-card": { + "complete": "" + } + }, + "connections": { + "connect-data": { + "category-header-label": "", + "empty-message": "", + "request-data-source": "", + "roadmap": "" + }, + "search": { + "placeholder": "" + } + }, + "core": { + "versionHistory": { + "comparison": { + "header": { + "hide-json-diff": "", + "show-json-diff": "", + "text": "" + }, + "select": "" + }, + "no-properties-changed": "", + "table": { + "updated": "", + "updatedBy": "", + "version": "" + }, + "view-json-diff": "" + } + }, + "correlations": { + "add-new": "", + "alert": { + "error-message": "", + "title": "" + }, + "basic-info-form": { + "description-description": "", + "description-label": "", + "label-description": "", + "label-label": "", + "label-placeholder": "", + "label-required": "", + "sub-text": "", + "title": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + }, + "list": { + "delete": "", + "label": "", + "loading": "", + "read-only": "", + "source": "", + "target": "" + }, + "navigation-form": { + "add-button": "", + "back-button": "", + "next-button": "", + "save-button": "" + }, + "page-content": "", + "page-heading": "", + "query-editor": { + "control-rules": "", + "data-source-text": "", + "data-source-title": "", + "error-text": "", + "error-title": "", + "loading": "", + "query-description": "", + "query-editor-title": "", + "query-label": "" + }, + "source-form": { + "control-required": "", + "description": "", + "description-external-pre": "", + "description-query-pre": "", + "external-title": "", + "heading-external": "", + "heading-query": "", + "query-title": "", + "results-description": "", + "results-label": "", + "results-required": "", + "source-description": "", + "source-label": "", + "sub-text": "" + }, + "sub-title": "", + "target-form": { + "control-rules": "", + "sub-text": "", + "target-description-external": "", + "target-description-query": "", + "target-label": "", + "target-type-description": "", + "title": "", + "type-label": "" + }, + "trans-details": { + "logfmt-description": "", + "logfmt-label": "", + "regex-description": "", + "regex-expression": "", + "regex-label": "", + "regex-map-values": "" + }, + "transform": { + "add-button": "", + "heading": "", + "no-transform": "" + }, + "transform-row": { + "expression-label": "", + "expression-required": "", + "expression-tooltip": "", + "field-input": "", + "field-label": "", + "field-tooltip": "", + "map-value-label": "", + "map-value-tooltip": "", + "remove-button": "", + "remove-tooltip": "", + "transform-required": "", + "type-label": "", + "type-tooltip": "" + } + }, + "dashboard": { + "add-menu": { + "import": "", + "paste-panel": "", + "row": "", + "visualization": "" + }, + "alert-rules-drawer": { + "redirect-link": "", + "subtitle": "" + }, + "default-layout": { + "description": "", + "item-options": { + "repeat": { + "direction": { + "horizontal": "", + "title": "", + "vertical": "" + }, + "max": "", + "title": "", + "variable": { + "description": "", + "title": "" + } + } + }, + "name": "", + "row-actions": { + "delete": "", + "modal": { + "alt-action": "", + "text": "", + "title": "" + } + }, + "row-options": { + "button": { + "label": "" + }, + "form": { + "cancel": "", + "repeat-for": { + "label": "", + "learn-more": "", + "warning": { + "text": "" + } + }, + "title": "", + "update": "" + }, + "modal": { + "title": "" + }, + "repeat": { + "title": "", + "variable": { + "title": "" + } + }, + "title": "" + } + }, + "edit-pane": { + "elements": { + "dashboard": "", + "objects": "", + "panel": "", + "panels": "", + "row": "", + "rows": "", + "tab": "", + "tabs": "" + }, + "open": "", + "row": { + "header": { + "hide": "", + "title": "" + } + } + }, + "editpane": { + "add": "", + "configure": "", + "outline": "" + }, + "empty": { + "add-library-panel-body": "", + "add-library-panel-button": "", + "add-library-panel-header": "", + "add-visualization-body": "", + "add-visualization-button": "", + "add-visualization-header": "", + "import-a-dashboard-body": "", + "import-a-dashboard-header": "", + "import-dashboard-button": "" + }, + "errors": { + "failed-to-load": "" + }, + "inspect": { + "data-tab": "", + "error-tab": "", + "json-tab": "", + "meta-tab": "", + "query-tab": "", + "stats-tab": "", + "subtitle": "", + "title": "" + }, + "inspect-data": { + "data-options": "", + "dataframe-aria-label": "", + "dataframe-label": "", + "download-csv": "", + "download-excel-description": "", + "download-excel-label": "", + "download-logs": "", + "download-service": "", + "download-traces": "", + "excel-header": "", + "formatted": "", + "formatted-data-description": "", + "formatted-data-label": "", + "panel-transforms": "", + "series-to-columns": "", + "transformation": "", + "transformations-description": "", + "transformations-label": "" + }, + "inspect-json": { + "dataframe-description": "", + "dataframe-label": "", + "panel-data-description": "", + "panel-data-label": "", + "panel-json-description": "", + "panel-json-label": "", + "select-source": "", + "unknown": "" + }, + "inspect-meta": { + "no-inspector": "" + }, + "inspect-stats": { + "data-title": "", + "data-traceids": "", + "processing-time": "", + "queries": "", + "request-time": "", + "rows": "", + "table-title": "" + }, + "layout": { + "common": { + "copy": "", + "copy-or-duplicate": "", + "delete": "", + "duplicate": "", + "layout": "" + } + }, + "options": { + "description": "", + "title-option": "" + }, + "outline": { + "tree": { + "item": { + "collapse": "", + "empty": "", + "expand": "" + } + } + }, + "panel-edit": { + "alerting-tab": { + "dashboard-not-saved": "", + "no-rules": "" + } + }, + "responsive-layout": { + "description": "", + "item-options": { + "hide-no-data": "", + "repeat": { + "variable": { + "description": "", + "title": "" + } + }, + "title": "" + }, + "name": "", + "options": { + "columns": "", + "fixed": "", + "min": "", + "one-column": "", + "rows": "", + "three-columns": "", + "two-columns": "" + } + }, + "rows-layout": { + "description": "", + "name": "", + "option": { + "height": "", + "hide-header": "", + "repeat": "", + "title": "" + }, + "options": { + "height-expand": "", + "height-min": "" + }, + "row": { + "collapse": "", + "expand": "", + "menu": { + "add": "", + "add-panel": "", + "add-row-above": "", + "add-row-below": "", + "move-down": "", + "move-row": "", + "move-up": "" + }, + "new": "", + "repeat": { + "learn-more": "", + "warning": "" + } + }, + "row-options": { + "title-option": "" + } + }, + "tabs-layout": { + "description": "", + "menu": { + "move-tab": "" + }, + "name": "", + "tab": { + "menu": { + "add": "", + "add-panel": "", + "add-tab-above": "", + "add-tab-after": "", + "add-tab-before": "", + "move-left": "", + "move-right": "" + }, + "new": "" + }, + "tab-options": { + "title-option": "" + } + }, + "toolbar": { + "add": "", + "add-panel": "", + "add-panel-description": "", + "add-panel-lib": "", + "add-row": "", + "add-tab": "", + "alert-rules": "", + "back-to-dashboard": "", + "dashboard-settings": { + "label": "", + "tooltip": "" + }, + "discard-library-panel-changes": "", + "discard-panel": "", + "discard-panel-new": "", + "edit": { + "label": "", + "tooltip": "" + }, + "edit-dashboard-v2-schema": "", + "enter-edit-mode": { + "label": "", + "tooltip": "" + }, + "exit-edit-mode": { + "label": "", + "tooltip": "" + }, + "libray-panel-description": "", + "mark-favorite": "", + "more-save-options": "", + "open-original": "", + "playlist-next": "", + "playlist-previous": "", + "playlist-stop": "", + "public-dashboard": "", + "refresh": "", + "row-description": "", + "save": "", + "save-dashboard": { + "label": "", + "tooltip": "" + }, + "save-dashboard-copy": { + "label": "", + "tooltip": "" + }, + "save-dashboard-short": "", + "save-library-panel": "", + "settings": "", + "share": { + "label": "", + "tooltip": "" + }, + "share-button": "", + "show-hidden-elements": "", + "switch-old-dashboard": "", + "tabs-description": "", + "unlink-library-panel": "", + "unmark-favorite": "" + }, + "validation": { + "invalid-dashboard-id": "", + "invalid-json": "", + "tags-expected-array": "", + "tags-expected-strings": "" + }, + "viz-panel": { + "options": { + "description": "", + "open-edit": "", + "plugin-type-image": "", + "title-option": "", + "transparent-background": "" + } + } + }, + "dashboard-import": { + "file-dropzone": { + "primary-text": "", + "secondary-text": "" + }, + "form-actions": { + "cancel": "", + "load": "" + }, + "gcom-field": { + "label": "", + "load-button": "", + "placeholder": "", + "validation-required": "" + }, + "json-field": { + "label": "", + "validation-required": "" + } + }, + "dashboard-links": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "title": "" + } + }, + "dashboard-settings": { + "annotations": { + "title": "" + }, + "dashboard-delete-button": "", + "delete-modal": { + "confirmation-text": "", + "delete-button": "", + "title": "" + }, + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "general": { + "auto-refresh-description": "", + "auto-refresh-label": "", + "description-label": "", + "editable-description": "", + "editable-label": "", + "folder-label": "", + "panel-options-graph-tooltip-description": "", + "panel-options-graph-tooltip-label": "", + "panel-options-label": "", + "panels-preload-description": "", + "panels-preload-label": "", + "tags-label": "", + "title": "", + "title-label": "" + }, + "json-editor": { + "save-button": "", + "subtitle": "", + "title": "" + }, + "links": { + "title": "" + }, + "permissions": { + "title": "" + }, + "provisioned-delete-modal": { + "confirm-button": "", + "text-1": "", + "text-2": "", + "text-3": "", + "text-link": "", + "title": "" + }, + "settings": { + "title": "" + }, + "time-picker": { + "hide-time-picker": "", + "now-delay-description": "", + "now-delay-label": "", + "refresh-live-dashboards-description": "", + "refresh-live-dashboards-label": "", + "time-options-label": "", + "time-zone-label": "", + "week-start-label": "" + }, + "time-regions": { + "advanced-description-cron": "", + "advanced-description-rest": "", + "advanced-description-use": "", + "advanced-label": "" + }, + "variables": { + "title": "" + }, + "versions": { + "title": "" + } + }, + "dashboards": { + "panel-edit": { + "angular-deprecation-button-open-panel-json": "", + "angular-deprecation-description": "", + "angular-deprecation-heading": "" + }, + "panel-queries": { + "add-query-from-library": "" + }, + "settings": { + "variables": { + "dependencies": { + "button": "", + "title": "" + } + } + } + }, + "data-source-list": { + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + } + }, + "data-source-picker": { + "add-new-data-source": "", + "built-in-list": { + "description-dashboard": "", + "description-grafana": "", + "description-mixed": "" + }, + "list": { + "no-data-source-message": "" + }, + "modal": { + "configure-new-data-source": "", + "input-placeholder": "", + "title": "" + }, + "open-advanced-button": "" + }, + "data-source-testing-status-page": { + "error-more-details-link": "", + "success-more-details-links": "" + }, + "data-sources": { + "datasource-add-button": { + "label": "" + }, + "empty-state": { + "message": "" + } + }, + "embed": { + "share": { + "time-range-description": "", + "time-range-label": "" + } + }, + "empty-list-cta": { + "pro-tip": "" + }, + "entity-not-found": { + "description": "" + }, + "errors": { + "dashboard-settings": { + "annotations": { + "datasource": "" + } + } + }, + "explore": { + "add-to-dashboard": "", + "drilldownInfo": { + "action": "", + "description": "", + "title": "" + }, + "logs": { + "logs-volume": { + "add-filters": "", + "decrease-timerange": "", + "much-data": "" + }, + "maximum-pinned-logs": "", + "no-logs-found": "", + "scan-for-older-logs": "", + "stop-scan": "" + }, + "rich-history": { + "close-tooltip": "", + "datasource-a-z": "", + "datasource-z-a": "", + "newest-first": "", + "oldest-first": "", + "query-history": "", + "query-library": "", + "settings": "", + "starred": "" + }, + "rich-history-card": { + "add-comment-form": "", + "add-comment-tooltip": "", + "add-to-library": "", + "cancel": "", + "confirm-delete": "", + "copy-query-tooltip": "", + "copy-shortened-link-tooltip": "", + "datasource-icon-label": "", + "datasource-name-label": "", + "datasource-not-exist": "", + "delete-query-confirmation-title": "", + "delete-query-title": "", + "delete-query-tooltip": "", + "delete-starred-query-confirmation-text": "", + "edit-comment-tooltip": "", + "optional-description": "", + "query-comment-label": "", + "query-text-label": "", + "save-comment": "", + "star-query-tooltip": "", + "unstar-query-tooltip": "", + "update-comment-form": "" + }, + "rich-history-container": { + "loading": "" + }, + "rich-history-notification": { + "query-copied": "", + "query-deleted": "" + }, + "rich-history-queries-tab": { + "displaying-partial-queries": "", + "displaying-queries": "", + "filter-aria-label": "", + "filter-history": "", + "filter-placeholder": "", + "history-local": "", + "loading": "", + "loading-results": "", + "search-placeholder": "", + "showing-queries": "", + "sort-aria-label": "", + "sort-placeholder": "" + }, + "rich-history-settings-tab": { + "alert-info": "", + "change-default-tab": "", + "clear-history-info": "", + "clear-query-history": "", + "clear-query-history-button": "", + "delete-confirm": "", + "delete-confirm-text": "", + "delete-title": "", + "history-time-span": "", + "history-time-span-description": "", + "only-show-active-datasource": "", + "query-history-deleted": "", + "retention-period": { + "1-week": "", + "2-days": "", + "2-weeks": "", + "5-days": "" + } + }, + "rich-history-starred-tab": { + "filter-queries-aria-label": "", + "filter-queries-placeholder": "", + "loading": "", + "loading-results": "", + "local-history-message": "", + "search-queries-placeholder": "", + "showing-queries": "", + "sort-queries-aria-label": "", + "sort-queries-placeholder": "" + }, + "rich-history-utils": { + "a-week-ago": "", + "days-ago": "", + "default-from": "", + "default-to": "", + "today": "", + "two-weeks-ago": "", + "yesterday": "" + }, + "rich-history-utils-notification": { + "saving-failed": "", + "update-failed": "" + }, + "run-query": { + "left-pane": "", + "right-pane": "", + "run-query-button": "", + "switch-datasource-button": "" + }, + "secondary-actions": { + "add-from-query-library": "", + "query-add-button": "", + "query-add-button-aria-label": "", + "query-history-button": "", + "query-history-button-aria-label": "", + "query-inspector-button": "", + "query-inspector-button-aria-label": "" + }, + "table": { + "no-data": "", + "title": "", + "title-with-name": "" + }, + "toolbar": { + "add-to-extensions": "", + "add-to-queryless-extensions": "", + "aria-label": "", + "copy-link": "", + "copy-link-abs-time": "", + "copy-links-absolute-category": "", + "copy-links-normal-category": "", + "copy-shortened-link": "", + "copy-shortened-link-abs-time": "", + "copy-shortened-link-label": "", + "copy-shortened-link-menu": "", + "refresh-picker-cancel": "", + "refresh-picker-run": "", + "split-close": "", + "split-close-tooltip": "", + "split-narrow": "", + "split-title": "", + "split-tooltip": "", + "split-widen": "" + } + }, + "explore-metrics": { + "breakdown": { + "clearFilter": "", + "labelSelect": "", + "missing-otel-labels": "", + "noMatchingValue": "", + "sortBy": "" + }, + "related-logs": { + "LrrDocsLink": "", + "openExploreLogs": "", + "relatedLogsUnavailable": "", + "warnExperimentalFeature": "" + }, + "viewBy": "" + }, + "export": { + "json": { + "cancel-button": "", + "copy-button": "", + "download-button": "", + "download-successful_toast_message": "", + "export-externally-label": "", + "info-text": "", + "title": "" + }, + "menu": { + "export-as-json-label": "", + "export-as-json-tooltip": "" + } + }, + "folder-filter": { + "clear-folder-button": "" + }, + "folder-picker": { + "create-instructions": "", + "loading": "" + }, + "forgot-password": { + "back-button": "", + "change-password": { + "skip-button": "", + "submit-button": "" + }, + "contact-admin": "", + "email-sent": "", + "reset-password-header": "", + "send-email-button": "" + }, + "form-prompt": { + "continue-button": "", + "description": "", + "discard-button": "" + }, + "gen-ai": { + "apply-suggestion": "", + "incomplete-request-error": "", + "send-custom-feedback": "" + }, + "get-enterprise": { + "requires-license": "", + "title": "" + }, + "grafana-ui": { + "action-editor": { + "button": { + "confirm": "", + "confirm-action": "" + }, + "inline": { + "add-action": "", + "edit-action": "" + }, + "modal": { + "action-body": "", + "action-method": "", + "action-query-params": "", + "action-title": "", + "action-title-placeholder": "", + "one-click-description": "" + } + }, + "alert": { + "close-button": "" + }, + "auto-save-field": { + "saved": "", + "saving": "" + }, + "card": { + "option": "" + }, + "cascader": { + "clear-button": "" + }, + "color-picker-popover": { + "palette-tab": "", + "spectrum-tab": "" + }, + "confirm-button": { + "cancel": "" + }, + "confirm-content": { + "placeholder": "" + }, + "data-link-editor": { + "info": "", + "new-tab-label": "", + "title-label": "", + "title-placeholder": "", + "url-label": "" + }, + "data-link-editor-modal": { + "cancel": "", + "one-click-description": "", + "save": "" + }, + "data-link-inline-editor": { + "one-click": "" + }, + "data-links-inline-editor": { + "add-link": "", + "edit-link": "", + "one-click": "", + "one-click-enabled": "", + "title-not-provided": "", + "tooltip-edit": "", + "tooltip-remove": "", + "url-not-provided": "" + }, + "data-source-basic-auth-settings": { + "user-label": "", + "user-placeholder": "" + }, + "data-source-http-proxy-settings": { + "oauth-identity-label": "", + "oauth-identity-tooltip": "", + "skip-tls-verify-label": "", + "ts-client-auth-label": "", + "with-ca-cert-label": "", + "with-ca-cert-tooltip": "" + }, + "data-source-http-settings": { + "access-help": "", + "access-help-details": "", + "access-label": "", + "access-options-browser": "", + "access-options-proxy": "", + "allowed-cookies": "", + "allowed-cookies-tooltip": "", + "auth": "", + "azure-auth-label": "", + "azure-auth-tooltip": "", + "basic-auth": "", + "basic-auth-label": "", + "browser-mode-description": "", + "browser-mode-title": "", + "default-url-access-select": "", + "default-url-tooltip": "", + "direct-url-tooltip": "", + "heading": "", + "proxy-url-tooltip": "", + "server-mode-description": "", + "server-mode-title": "", + "timeout-form-label": "", + "timeout-label": "", + "timeout-tooltip": "", + "url-label": "", + "with-credential-label": "", + "with-credential-tooltip": "" + }, + "data-source-settings": { + "alerting-settings-heading": "", + "alerting-settings-label": "", + "alerting-settings-tooltip": "", + "cert-key-reset": "", + "custom-headers-add": "", + "custom-headers-header": "", + "custom-headers-header-placeholder": "", + "custom-headers-header-remove": "", + "custom-headers-header-value": "", + "custom-headers-title": "", + "secure-socks-heading": "", + "secure-socks-label": "", + "secure-socks-tooltip": "", + "tls-certification-label": "", + "tls-certification-placeholder": "", + "tls-client-certification-label": "", + "tls-client-key-label": "", + "tls-client-key-placeholder": "", + "tls-heading": "", + "tls-server-name-label": "", + "tls-tooltip": "" + }, + "date-time-picker": { + "apply": "", + "calendar-icon-label": "", + "cancel": "", + "next-label": "", + "previous-label": "", + "select-placeholder": "" + }, + "drawer": { + "close": "" + }, + "feature-badge": { + "experimental": "", + "new": "", + "preview": "", + "private-preview": "" + }, + "field-link-list": { + "external-links-heading": "" + }, + "file-dropzone": { + "cancel-upload": "", + "file-too-large": "" + }, + "filter-input": { + "clear": "" + }, + "modal": { + "close-tooltip": "" + }, + "named-colors-palette": { + "text-color-swatch": "", + "transparent-swatch": "" + }, + "page-toolbar": { + "go-back": "", + "search-dashboard-name": "", + "search-links": "", + "search-parent-folder": "" + }, + "pagination": { + "next-page": "", + "previous-page": "" + }, + "secret-form-field": { + "reset": "" + }, + "segment-async": { + "error": "", + "loading": "", + "no-options": "" + }, + "select": { + "default-create-label": "", + "no-options-label": "", + "placeholder": "" + }, + "series-color-picker-popover": { + "y-axis-usage": "" + }, + "spinner": { + "aria-label": "" + }, + "table": { + "copy": "", + "csv-counts": "", + "filter-popup-apply": "", + "filter-popup-cancel": "", + "filter-popup-clear": "", + "filter-popup-heading": "", + "no-values-label": "", + "pagination-summary": "" + }, + "tags-input": { + "add": "" + }, + "user-icon": { + "active-text": "" + }, + "value-pill": { + "remove-button": "" + }, + "viz-legend": { + "right-axis-indicator": "" + }, + "viz-tooltip": { + "actions-confirmation-input-placeholder": "", + "actions-confirmation-label": "", + "actions-confirmation-message": "", + "footer-add-annotation": "", + "footer-click-to-action": "", + "footer-click-to-navigate": "" + } + }, + "graph": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "", + "title": "" + } + }, + "help-modal": { + "column-headers": { + "description": "", + "keys": "" + }, + "shortcuts-category": { + "dashboard": "", + "focused-panel": "", + "global": "", + "time-range": "" + }, + "shortcuts-description": { + "change-theme": "", + "collapse-all-rows": "", + "copy-time-range": "", + "dashboard-settings": "", + "duplicate-panel": "", + "exit-edit/setting-views": "", + "expand-all-rows": "", + "go-to-dashboards": "", + "go-to-explore": "", + "go-to-home-dashboard": "", + "go-to-profile": "", + "make-time-range-permanent": "", + "move-time-range-back": "", + "move-time-range-forward": "", + "open-search": "", + "open-shared-modal": "", + "paste-time-range": "", + "refresh-all-panels": "", + "remove-panel": "", + "save-dashboard": "", + "show-all-shortcuts": "", + "toggle-active-mode": "", + "toggle-all-panel-legends": "", + "toggle-auto-fit": "", + "toggle-exemplars": "", + "toggle-graph-crosshair": "", + "toggle-kiosk": "", + "toggle-panel-edit": "", + "toggle-panel-fullscreen": "", + "toggle-panel-legend": "", + "zoom-out-time-range": "" + }, + "title": "" + }, + "help-wizard": { + "download-snapshot": "", + "github-comment": "", + "support-bundle": "", + "troubleshooting-help": "" + }, + "inspector": { + "query": { + "collapse-all": "", + "copy-to-clipboard": "", + "description": "", + "expand-all": "", + "no-data": "", + "refresh": "" + } + }, + "ldap-drawer": { + "attributes-section": { + "description": "", + "email-label": "", + "label": "", + "member-of-label": "", + "name-label": "", + "surname-label": "", + "username-label": "" + }, + "extra-security-section": { + "client-cert-label": "", + "client-cert-placeholder": "", + "client-cert-value-label": "", + "client-cert-value-placeholder": "", + "client-key-label": "", + "client-key-placeholder": "", + "client-key-value-label": "", + "client-key-value-placeholder": "", + "encryption-provider-base-64": "", + "encryption-provider-description": "", + "encryption-provider-file-path": "", + "encryption-provider-label": "", + "label": "", + "min-tls-version-description": "", + "min-tls-version-label": "", + "root-ca-cert-label": "", + "root-ca-cert-placeholder": "", + "root-ca-cert-value-label": "", + "root-ca-cert-value-placeholder": "", + "start-tls-description": "", + "start-tls-label": "", + "tls-ciphers-label": "", + "tls-ciphers-placeholder": "", + "use-ssl-description": "", + "use-ssl-label": "", + "use-ssl-tooltip": "" + }, + "group-mapping": { + "grafana-admin": { + "description": "", + "label": "" + }, + "group-dn": { + "description": "", + "label": "" + }, + "org-id": { + "description": "", + "label": "" + }, + "org-role": { + "label": "" + }, + "remove": { + "button": "" + } + }, + "group-mapping-section": { + "add": { + "button": "" + }, + "description": "", + "group-search-base-dns-label": "", + "group-search-base-dns-placeholder": "", + "group-search-filter-description": "", + "group-search-filter-label": "", + "group-search-filter-user-attribute-description": "", + "group-search-filter-user-attribute-label": "", + "label": "", + "skip-org-role-sync-description": "", + "skip-org-role-sync-label": "" + }, + "misc-section": { + "allow-sign-up-descrition": "", + "allow-sign-up-label": "", + "label": "", + "port-description": "", + "port-label": "", + "timeout-description": "", + "timeout-label": "" + }, + "title": "" + }, + "ldap-settings-page": { + "advanced-settings-section": { + "edit-button": "", + "subtitle": "", + "title": "" + }, + "alert": { + "discard-success": "", + "error-fetching": "", + "error-saving": "", + "error-validate-form": "", + "feature-flag-disabled": "", + "saved": "" + }, + "bind-dn": { + "description": "", + "label": "", + "placeholder": "" + }, + "bind-password": { + "label": "" + }, + "buttons-section": { + "disable-button": "", + "discard-button": "", + "save-and-enable-button": "", + "save-button": "" + }, + "documentation": "", + "host": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "login-form-alert": { + "description": "", + "title": "" + }, + "search_filter": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "search-base-dns": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "subtitle": "", + "title": "" + }, + "library-panel": { + "add-modal": { + "cancel": "", + "create": "", + "error": "", + "folder": "", + "folder-description": "", + "name": "" + }, + "add-widget": { + "title": "" + }, + "empty-state": { + "message": "", + "more-info": "" + } + }, + "library-panels": { + "empty-state": { + "message": "" + }, + "loading-panel-text": "", + "modal": { + "button-cancel": "", + "button-view-panel1": "", + "button-view-panel2": "", + "panel-not-linked": "", + "select-no-options-message": "", + "select-placeholder": "", + "title": "", + "body_other": "" + }, + "save": { + "error": "", + "success": "" + } + }, + "link": { + "share": { + "config-alert-description": "", + "config-alert-title": "", + "config-description": "", + "copy-link-button": "", + "copy-to-clipboard": "", + "short-url-label": "", + "time-range-description": "", + "time-range-label": "" + }, + "share-panel": { + "config-description": "", + "download-image": "", + "render-image": "", + "render-image-error": "", + "render-image-error-description": "" + } + }, + "lock-icon": "", + "login": { + "divider": { + "connecting-text": "" + }, + "error": { + "blocked": "", + "invalid-user-or-password": "", + "title": "", + "unknown": "" + }, + "forgot-password": "", + "form": { + "confirmation-code": "", + "confirmation-code-label": "", + "confirmation-code-placeholder": "", + "email-label": "", + "email-placeholder": "", + "email-required": "", + "name-label": "", + "name-placeholder": "", + "password-label": "", + "password-placeholder": "", + "password-required": "", + "submit-label": "", + "submit-loading-label": "", + "username-label": "", + "username-placeholder": "", + "username-required": "", + "verify-email-label": "", + "verify-email-loading-label": "" + }, + "layout": { + "update-password": "" + }, + "services": { + "sing-in-with-prefix": "" + }, + "signup": { + "button-label": "", + "new-to-question": "" + } + }, + "logs": { + "infinite-scroll": { + "end-of-range": "", + "load-more": "", + "load-newer": "", + "load-older": "", + "older-logs": "" + }, + "log-details": { + "fields": "", + "links": "", + "log-line": "", + "no-details": "" + }, + "log-line-menu": { + "copy-link": "", + "copy-log": "", + "icon-label": "", + "pin-to-outline": "", + "show-context": "", + "unpin-from-outline": "" + }, + "log-row-message": { + "ellipsis": "", + "more": "", + "see-details": "" + }, + "log-rows": { + "disable-popover": { + "confirm": "", + "message": "", + "title": "" + }, + "disable-popover-message": { + "shortcut": "" + } + }, + "logs-navigation": { + "newer-logs": "", + "older-logs": "", + "scroll-bottom": "", + "scroll-top": "", + "start-of-range": "" + }, + "popover-menu": { + "copy": "", + "disable-menu": "", + "line-contains": "", + "line-contains-not": "" + } + }, + "migrate-to-cloud": { + "build-snapshot": { + "description": "", + "title": "", + "when-complete": "" + }, + "building-snapshot": { + "description": "", + "description-eta": "", + "title": "" + }, + "can-i-move": { + "body": "", + "link-title": "", + "title": "" + }, + "connect-modal": { + "body-cloud-stack": "", + "body-get-started": "", + "body-sign-up": "", + "body-token": "", + "body-token-field": "", + "body-token-field-placeholder": "", + "body-token-instructions": "", + "body-view-stacks": "", + "cancel": "", + "connect": "", + "connecting": "", + "title": "", + "token-error-title": "", + "token-errors": { + "instance-request-error": "", + "instance-unreachable": "", + "migration-disabled": "", + "session-creation-failure": "", + "token-invalid": "", + "token-not-saved": "", + "token-request-error": "", + "token-validation-failure": "" + }, + "token-required-error": "" + }, + "cta": { + "button": "", + "header": "" + }, + "delete-migration-token-confirm": { + "body": "", + "confirm-button": "", + "error-title": "", + "title": "" + }, + "disconnect-modal": { + "body": "", + "cancel": "", + "disconnect": "", + "disconnecting": "", + "error": "", + "title": "" + }, + "get-started": { + "body": "", + "configure-pdc-link": "", + "link-title": "", + "step-1": "", + "step-2": "", + "step-3": "", + "step-4": "", + "step-5": "", + "title": "" + }, + "is-it-secure": { + "body": "", + "link-title": "", + "title": "" + }, + "migrate-to-this-stack": { + "body": "", + "link-title": "", + "title": "" + }, + "migrated-counts": { + "alert_rule_groups": "", + "alert_rules": "", + "contact_points": "", + "dashboards": "", + "datasources": "", + "folders": "", + "library_elements": "", + "mute_timings": "", + "notification_policies": "", + "notification_templates": "", + "plugins": "" + }, + "migration-token": { + "delete-button": "", + "delete-modal-body": "", + "delete-modal-cancel": "", + "delete-modal-confirm": "", + "delete-modal-deleting": "", + "delete-modal-title": "", + "error-body": "", + "error-title": "", + "generate-button": "", + "generate-button-loading": "", + "modal-close": "", + "modal-copy-and-close": "", + "modal-copy-button": "", + "modal-field-description": "", + "modal-field-label": "", + "modal-title": "", + "status": "" + }, + "onprem": { + "cancel-snapshot-error-title": "", + "create-snapshot-error-title": "", + "disconnect-error-title": "", + "error-see-server-logs": "", + "get-session-error-title": "", + "get-snapshot-error-title": "", + "migration-finished-with-caveat-title": "", + "migration-finished-with-errors-body": "", + "migration-finished-with-warnings-body": "", + "snapshot-error-status-body": "", + "snapshot-error-status-title": "", + "success-message": "", + "success-message-generic": "", + "success-title": "", + "upload-snapshot-error-title": "" + }, + "pdc": { + "body": "", + "link-title": "", + "title": "" + }, + "pricing": { + "body": "", + "link-title": "", + "title": "" + }, + "public-preview": { + "button-text": "", + "message": "", + "message-cloud": "", + "title": "" + }, + "resource-details": { + "dismiss-button": "", + "error-messages": { + "dashboard-already-managed": "", + "datasource-already-managed": "", + "datasource-invalid-url": "", + "datasource-name-conflict": "", + "folder-name-conflict": "", + "generic-error": "", + "internal-service-error": "", + "library-element-name-conflict": "", + "resource-conflict": "", + "unexpected-error": "", + "unsupported-data-type": "" + }, + "error-title": "", + "generic-title": "", + "missing-message": "", + "resource-summary": "", + "title": "", + "warning-title": "" + }, + "resource-status": { + "error-details-button": "", + "failed": "", + "migrated": "", + "migrating": "", + "not-migrated": "", + "unknown": "", + "warning": "", + "warning-details-button": "" + }, + "resource-table": { + "dashboard-load-error": "", + "error-library-element-sub": "", + "error-library-element-title": "", + "unknown-datasource-title": "", + "unknown-datasource-type": "" + }, + "resource-type": { + "alert_rule": "", + "alert_rule_group": "", + "contact_point": "", + "dashboard": "", + "datasource": "", + "folder": "", + "library_element": "", + "mute_timing": "", + "notification_policy": "", + "notification_template": "", + "plugin": "", + "unknown": "" + }, + "summary": { + "cancel-snapshot": "", + "disconnect": "", + "errored-resource-count": "", + "page-loading": "", + "rebuild-snapshot": "", + "snapshot-date": "", + "snapshot-not-created": "", + "start-migration": "", + "successful-resource-count": "", + "target-stack-title": "", + "total-resource-count": "", + "upload-migration": "" + }, + "support-types-disclosure": { + "text": "" + }, + "token-status": { + "active": "", + "no-active": "", + "unknown": "", + "unknown-error": "" + }, + "what-is-cloud": { + "body": "", + "link-title": "", + "title": "" + }, + "why-host": { + "body": "", + "link-title": "", + "title": "" + } + }, + "multicombobox": { + "all": { + "title": "", + "title-filtered": "" + }, + "clear": { + "title": "" + } + }, + "nav": { + "add-new-connections": { + "title": "" + }, + "admin": { + "subtitle": "", + "title": "" + }, + "alert-list-legacy": { + "title": "" + }, + "alerting": { + "subtitle": "", + "title": "" + }, + "alerting-admin": { + "subtitle": "", + "title": "" + }, + "alerting-am-routes": { + "subtitle": "", + "title": "" + }, + "alerting-channels": { + "title": "" + }, + "alerting-groups": { + "subtitle": "", + "title": "" + }, + "alerting-home": { + "title": "" + }, + "alerting-legacy": { + "title": "" + }, + "alerting-list": { + "subtitle": "", + "title": "" + }, + "alerting-receivers": { + "subtitle": "", + "title": "" + }, + "alerting-silences": { + "subtitle": "", + "title": "" + }, + "alerting-upgrade": { + "subtitle": "", + "title": "" + }, + "alerts-and-incidents": { + "subtitle": "", + "title": "" + }, + "api-keys": { + "subtitle": "", + "title": "" + }, + "application": { + "title": "" + }, + "apps": { + "subtitle": "", + "title": "" + }, + "authentication": { + "title": "" + }, + "bookmarks": { + "title": "" + }, + "bookmarks-empty": { + "title": "" + }, + "collector": { + "title": "" + }, + "config": { + "title": "" + }, + "config-access": { + "subtitle": "", + "title": "" + }, + "config-general": { + "subtitle": "", + "title": "" + }, + "config-plugins": { + "subtitle": "", + "title": "" + }, + "connect-data": { + "title": "" + }, + "connections": { + "subtitle": "", + "title": "" + }, + "correlations": { + "subtitle": "", + "title": "" + }, + "create": { + "title": "" + }, + "create-alert": { + "title": "" + }, + "create-dashboard": { + "title": "" + }, + "create-folder": { + "title": "" + }, + "create-import": { + "title": "" + }, + "dashboards": { + "subtitle": "", + "title": "" + }, + "data-sources": { + "subtitle": "", + "title": "" + }, + "databases": { + "title": "" + }, + "datasources": { + "subtitle": "", + "title": "" + }, + "detect": { + "title": "" + }, + "drilldown": { + "title": "" + }, + "explore": { + "title": "" + }, + "frontend": { + "subtitle": "", + "title": "" + }, + "frontend-app": { + "title": "" + }, + "global-orgs": { + "subtitle": "", + "title": "" + }, + "global-users": { + "subtitle": "", + "title": "" + }, + "grafana-quaderno": { + "title": "" + }, + "groupsync": { + "subtitle": "" + }, + "help": { + "title": "" + }, + "help/community": "", + "help/documentation": "", + "help/keyboard-shortcuts": "", + "help/support": "", + "history-container": { + "drawer-tittle": "" + }, + "history-wrapper": { + "collapse": "", + "expand": "", + "icon-selected": "", + "icon-unselected": "", + "show-more": "", + "today": "", + "yesterday": "" + }, + "home": { + "title": "" + }, + "incidents": { + "title": "" + }, + "infrastructure": { + "subtitle": "", + "title": "" + }, + "integrations": { + "title": "" + }, + "k6": { + "title": "" + }, + "kubernetes": { + "title": "" + }, + "library-panels": { + "subtitle": "", + "title": "" + }, + "machine-learning": { + "title": "" + }, + "manage-folder": { + "subtitle": "" + }, + "migrate-to-cloud": { + "subtitle": "", + "title": "" + }, + "monitoring": { + "subtitle": "", + "title": "" + }, + "new": { + "title": "" + }, + "new-dashboard": { + "title": "" + }, + "new-folder": { + "title": "" + }, + "oncall": { + "title": "" + }, + "org-settings": { + "subtitle": "", + "title": "" + }, + "playlists": { + "subtitle": "", + "title": "" + }, + "plugins": { + "subtitle": "", + "title": "" + }, + "private-data-source-connections": { + "subtitle": "", + "title": "" + }, + "profile/notifications": { + "title": "" + }, + "profile/password": { + "title": "" + }, + "profile/settings": { + "title": "" + }, + "profiles": { + "title": "" + }, + "public": { + "title": "" + }, + "recently-deleted": { + "subtitle": "", + "title": "" + }, + "recorded-queries": { + "title": "" + }, + "reporting": { + "title": "" + }, + "scenes": { + "title": "" + }, + "search": { + "placeholderCommandPalette": "" + }, + "search-dashboards": { + "title": "" + }, + "server-settings": { + "subtitle": "", + "title": "" + }, + "service-accounts": { + "subtitle": "", + "title": "" + }, + "setup-guide": { + "title": "" + }, + "shared-dashboard": { + "subtitle": "", + "title": "" + }, + "sign-out": { + "title": "" + }, + "slo": { + "title": "" + }, + "snapshots": { + "subtitle": "", + "title": "" + }, + "starred": { + "title": "" + }, + "starred-empty": { + "title": "" + }, + "statistics-and-licensing": { + "title": "" + }, + "storage": { + "subtitle": "", + "title": "" + }, + "support-bundles": { + "subtitle": "", + "title": "" + }, + "synthetics": { + "title": "" + }, + "teams": { + "subtitle": "", + "title": "" + }, + "testing-and-synthetics": { + "subtitle": "", + "title": "" + }, + "upgrading": { + "title": "" + }, + "users": { + "subtitle": "", + "title": "" + } + }, + "navigation": { + "invite-user": { + "invite-button": "", + "invite-tooltip": "" + }, + "item": { + "add-bookmark": "", + "remove-bookmark": "" + }, + "kiosk": { + "tv-alert": "" + }, + "megamenu": { + "close": "", + "dock": "", + "list-label": "", + "open": "", + "undock": "" + }, + "rss-button": "" + }, + "news": { + "drawer": { + "close": "" + }, + "title": "" + }, + "notifications": { + "empty-state": { + "description": "", + "title": "" + }, + "starred-dashboard": "", + "unstarred-dashboard": "" + }, + "oauth": { + "form": { + "server-discovery-action-button": "", + "server-discovery-modal-close": "", + "server-discovery-modal-loading": "", + "server-discovery-modal-submit": "" + }, + "login": { + "error": "" + } + }, + "panel": { + "header-menu": { + "copy": "", + "create-library-panel": "", + "duplicate": "", + "edit": "", + "explore": "", + "get-help": "", + "hide-legend": "", + "inspect": "", + "inspect-data": "", + "inspect-json": "", + "more": "", + "new-alert-rule": "", + "query": "", + "remove": "", + "replace-library-panel": "", + "share": "", + "show-legend": "", + "unlink-library-panel": "", + "view": "" + } + }, + "panel-search": { + "no-matches": "", + "unsupported-layout": "" + }, + "panel-type-filter": { + "clear-button": "" + }, + "playlist-edit": { + "error-prefix": "", + "form": { + "add-tag-label": "", + "add-tag-placeholder": "", + "add-title-label": "", + "cancel": "", + "heading": "", + "interval-label": "", + "interval-placeholder": "", + "interval-required": "", + "name-label": "", + "name-placeholder": "", + "name-required": "", + "save": "", + "table-delete": "", + "table-drag": "", + "table-empty": "", + "table-heading": "" + }, + "sub-title": "", + "title": "" + }, + "playlist-page": { + "card": { + "delete": "", + "edit": "", + "start": "", + "tooltip": "" + }, + "create-button": { + "title": "" + }, + "delete-modal": { + "body": "", + "confirm-text": "" + }, + "empty": { + "button": "", + "pro-tip": "", + "title": "" + } + }, + "playlists": { + "empty-state": { + "message": "" + } + }, + "plugins": { + "catalog": { + "no-updates-available": "", + "update-all": { + "all-plugins-updated": "", + "available-header": "", + "button": "", + "cloud-update-message": "", + "error": "", + "error-status-text": "", + "header": "", + "installed-header": "", + "modal-confirmation": "", + "modal-dismiss": "", + "modal-in-progress": "", + "modal-title": "", + "name-header": "", + "update-header": "", + "update-status-text": "" + }, + "versions": { + "confirmation-text-1": "", + "confirmation-text-2": "", + "downgrade-confirm": "", + "downgrade-title": "" + } + }, + "details": { + "connections-tab": { + "description": "" + }, + "labels": { + "contactGrafanaLabs": "", + "customLinks": "", + "customLinksTooltip": "", + "dependencies": "", + "documentation": "", + "downloads": "", + "from": "", + "installedVersion": "", + "lastCommitDate": "", + "latestVersion": "", + "license": "", + "raiseAnIssue": "", + "reportAbuse": "", + "reportAbuseTooltip": "", + "repository": "", + "signature": "", + "status": "", + "updatedAt": "" + }, + "modal": { + "cancel": "", + "copyEmail": "", + "description": "", + "node": "", + "title": "" + } + }, + "empty-state": { + "message": "" + }, + "filter": { + "disabled": "", + "sort": "", + "sort-list": "", + "state": "" + }, + "plugin-help": { + "error": "", + "not-found": "" + } + }, + "profile": { + "change-password": { + "cancel-button": "", + "cannot-change-password-message": "", + "change-password-button": "", + "confirm-password-label": "", + "confirm-password-required": "", + "ldap-auth-proxy-message": "", + "new-password-label": "", + "new-password-required": "", + "new-password-same-as-old": "", + "old-password-label": "", + "old-password-required": "", + "passwords-must-match": "", + "strong-password-validation-register": "" + } + }, + "public-dashboard": { + "acknowledgment-checkboxes": { + "ack-title": "", + "data-src-ack-desc": "", + "data-src-ack-tooltip": "", + "public-ack-desc": "", + "public-ack-tooltip": "", + "usage-ack-desc": "", + "usage-ack-desc-tooltip": "" + }, + "config": { + "can-view-dashboard-radio-button-label": "", + "copy-button": "", + "dashboard-url-field-label": "", + "email-share-type-option-label": "", + "pause-sharing-dashboard-label": "", + "public-share-type-option-label": "", + "revoke-public-URL-button": "", + "revoke-public-URL-button-title": "", + "settings-title": "" + }, + "configuration": { + "display-annotations-description": "", + "display-annotations-label": "", + "enable-time-range-description": "", + "enable-time-range-label": "", + "settings-label": "", + "success-pause": "", + "success-resume": "", + "success-update": "", + "success-update-old": "", + "time-range-label": "", + "time-range-tooltip": "" + }, + "create-page": { + "generate-public-url-button": "", + "unsupported-features-desc": "", + "welcome-title": "" + }, + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "email-sharing": { + "accept-button": "", + "alert-text": "", + "bill-ack": "", + "cancel-button": "", + "input-invalid-email-text": "", + "input-required-email-text": "", + "invite-button": "", + "invite-field-desc": "", + "invite-field-label": "", + "learn-more-button": "", + "recipient-email-placeholder": "", + "recipient-invalid-email-text": "", + "recipient-invitation-button": "", + "recipient-invitation-description": "", + "recipient-invitation-tooltip": "", + "recipient-list-description": "", + "recipient-list-title": "", + "recipient-required-email-text": "", + "resend-button": "", + "resend-button-title": "", + "resend-invite-label": "", + "revoke-access-label": "", + "revoke-button": "", + "revoke-button-title": "", + "success-creation": "", + "success-share-type-change": "" + }, + "modal-alerts": { + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "save-dashboard-changes-alert-title": "", + "unsupport-data-source-alert-readmore-link": "", + "unsupported-data-source-alert-desc": "", + "unsupported-data-source-alert-title": "", + "unsupported-template-variable-alert-desc": "", + "unsupported-template-variable-alert-title": "" + }, + "public-sharing": { + "accept-button": "", + "alert-text": "", + "cancel-button": "", + "learn-more-button": "", + "public-ack": "", + "success-creation": "", + "success-share-type-change": "" + }, + "settings-bar-header": { + "collapse-settings-tooltip": "", + "expand-settings-tooltip": "" + }, + "settings-configuration": { + "default-time-range-label": "", + "default-time-range-label-desc": "", + "show-annotations-label": "", + "show-annotations-label-desc": "", + "time-range-picker-label": "", + "time-range-picker-label-desc": "" + }, + "settings-summary": { + "annotations-hide-text": "", + "annotations-show-text": "", + "time-range-picker-disabled-text": "", + "time-range-picker-enabled-text": "", + "time-range-text": "" + }, + "share": { + "success-delete": "", + "success-delete-old": "" + }, + "share-configuration": { + "share-type-label": "" + }, + "share-externally": { + "copy-link-button": "", + "email-share-type-option-description": "", + "email-share-type-option-label": "", + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "pause-access-button": "", + "pause-access-tooltip": "", + "public-share-type-option-description": "", + "public-share-type-option-label": "", + "resume-access-button": "", + "revoke-access-button": "", + "revoke-access-description": "", + "unsupported-data-source-alert-desc": "" + }, + "sharing": { + "success-creation": "" + } + }, + "public-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "public-dashboard-users-access-list": { + "dashboard-modal": { + "external-link": "", + "loading-text": "", + "open-dashboard-list-text": "", + "public-dashboard-link": "", + "public-dashboard-setting": "", + "sharing-setting": "" + }, + "delete-user-modal": { + "delete-user-button-text": "", + "delete-user-cancel-button": "", + "delete-user-revoke-access-button": "", + "revoke-access-title": "", + "revoke-user-access-modal-desc-line1": "", + "revoke-user-access-modal-desc-line2": "" + }, + "delete-user-shared-dashboards-modal": { + "revoke-user-access-modal-desc-line2": "" + }, + "modal": { + "dashboard-modal-title": "", + "shared-dashboard-modal-title": "" + }, + "table-body": { + "dashboard-count_other": "" + }, + "table-header": { + "activated-label": "", + "activated-tooltip": "", + "email-label": "", + "last-active-label": "", + "origin-label": "", + "role-label": "" + } + }, + "query-operation": { + "header": { + "collapse-row": "", + "datasource-help": "", + "drag-and-drop": "", + "duplicate-query": "", + "expand-row": "", + "hide-response": "", + "remove-query": "", + "show-response": "", + "toggle-edit-mode": "" + }, + "query-editor-not-exported": "" + }, + "recently-deleted": { + "buttons": { + "delete": "", + "restore": "" + }, + "page": { + "no-deleted-dashboards": "", + "no-deleted-dashboards-text": "", + "no-search-result": "" + }, + "permanently-delete-modal": { + "confirm-text": "", + "delete-button": "", + "delete-loading": "", + "title": "", + "text_other": "" + }, + "restore-modal": { + "restore-button": "", + "restore-loading": "", + "title": "", + "folder-picker-text_other": "", + "text_other": "" + } + }, + "recentlyDeleted": { + "filter": { + "placeholder": "" + } + }, + "reduce": { + "strictMode": { + "description": "", + "title": "" + } + }, + "refresh-picker": { + "aria-label": { + "choose-interval": "", + "duration-selected": "" + }, + "auto-option": { + "aria-label": "", + "label": "" + }, + "live-option": { + "aria-label": "", + "label": "" + }, + "off-option": { + "aria-label": "", + "label": "" + }, + "tooltip": { + "interval-selected": "", + "turned-off": "" + } + }, + "return-to-previous": { + "button": { + "label": "" + }, + "dismissable-button": "" + }, + "role-picker": { + "built-in": { + "basic-roles": "" + }, + "input": { + "no-roles": "" + }, + "menu": { + "clear-button": "", + "tooltip": "" + }, + "sub-menu": { + "clear-button": "" + }, + "title": { + "description": "" + } + }, + "role-picker-drawer": { + "basic-roles": { + "label": "" + } + }, + "route-error": { + "description": "", + "reload-button": "", + "title": "" + }, + "save-dashboards": { + "message-length": { + "info": "", + "title": "" + }, + "name-exists": { + "message-info": "", + "message-suggestion": "", + "title": "" + } + }, + "scopes": { + "dashboards": { + "collapse": "", + "expand": "", + "loading": "", + "noResultsForFilter": "", + "noResultsForFilterClear": "", + "noResultsForScopes": "", + "noResultsNoScopes": "", + "search": "", + "toggle": { + "collapse": "", + "disabled": "", + "expand": "" + } + }, + "selector": { + "apply": "", + "cancel": "", + "input": { + "placeholder": "", + "removeAll": "" + }, + "title": "" + }, + "tree": { + "collapse": "", + "expand": "", + "headline": { + "noResults": "", + "recommended": "", + "results": "" + }, + "search": "" + } + }, + "search": { + "actions": { + "include-panels": "", + "remove-datasource-filter": "", + "sort-placeholder": "", + "starred": "", + "view-as-folders": "", + "view-as-list": "" + }, + "dashboard-actions": { + "import": "", + "new": "", + "new-dashboard": "", + "new-folder": "" + }, + "results-table": { + "datasource-header": "", + "deleted-less-than-1-min": "", + "deleted-remaining-header": "", + "location-header": "", + "name-header": "", + "tags-header": "", + "type-dashboard": "", + "type-folder": "", + "type-header": "" + }, + "search-input": { + "include-panels-placeholder": "", + "placeholder": "" + } + }, + "select": { + "select-menu": { + "selected-count": "" + } + }, + "service-account-create-page": { + "create": { + "button": "" + }, + "name": { + "label": "", + "required-error": "" + }, + "page-nav": { + "label": "" + }, + "role": { + "label": "" + } + }, + "service-accounts": { + "empty-state": { + "button-title": "", + "message": "", + "more-info": "", + "title": "" + } + }, + "share-dashboard": { + "menu": { + "export-json-title": "", + "share-externally-title": "", + "share-internally-title": "", + "share-snapshot-title": "" + }, + "share-button": "", + "share-button-tooltip": "" + }, + "share-drawer": { + "confirm-action": { + "back-arrow-button": "", + "cancel-button": "" + } + }, + "share-modal": { + "dashboard": { + "title": "" + }, + "embed": { + "copy": "", + "html": "", + "html-description": "", + "info": "", + "time-range": "" + }, + "export": { + "back-button": "", + "cancel-button": "", + "info-text": "", + "loading": "", + "save-button": "", + "share-externally-label": "", + "view-button": "" + }, + "library": { + "info": "" + }, + "link": { + "copy-link-button": "", + "info-text": "", + "link-url": "", + "render-alert": "", + "render-instructions": "", + "rendered-image": "", + "save-alert": "", + "save-dashboard": "", + "shorten-url": "", + "time-range-description": "", + "time-range-label": "" + }, + "panel": { + "title": "" + }, + "snapshot": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "deleted-message": "", + "expire": "", + "expire-day": "", + "expire-hour": "", + "expire-never": "", + "expire-week": "", + "info-text-1": "", + "info-text-2": "", + "local-button": "", + "mistake-message": "", + "name": "", + "timeout": "", + "timeout-description": "", + "url-label": "" + }, + "tab-title": { + "embed": "", + "export": "", + "library-panel": "", + "link": "", + "panel-embed": "", + "public-dashboard": "", + "public-dashboard-title": "", + "snapshot": "" + }, + "theme-picker": { + "current": "", + "dark": "", + "field-name": "", + "light": "" + }, + "view-json": { + "copy-button": "" + } + }, + "share-panel": { + "drawer": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "" + }, + "menu": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "", + "share-snapshot-title": "" + }, + "new-library-panel": { + "cancel-button": "", + "create-button": "" + } + }, + "share-panel-image": { + "preview": { + "title": "" + }, + "settings": { + "height-label": "", + "height-min": "", + "height-placeholder": "", + "height-required": "", + "max-warning": "", + "scale-factor-label": "", + "scale-factor-min": "", + "scale-factor-placeholder": "", + "scale-factor-required": "", + "title": "", + "width-label": "", + "width-min": "", + "width-placeholder": "", + "width-required": "" + } + }, + "share-playlist": { + "checkbox-description": "", + "checkbox-label": "", + "copy-link-button": "", + "link-url-label": "", + "mode": "", + "mode-kiosk": "", + "mode-normal": "", + "title": "" + }, + "shared": { + "preferences": { + "theme": { + "dark-label": "", + "light-label": "", + "system-label": "" + } + } + }, + "shared-dashboard": { + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "fields": { + "timezone-label": "" + } + }, + "shared-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "shared-preferences": { + "fields": { + "home-dashboard-label": "", + "home-dashboard-placeholder": "", + "locale-label": "", + "locale-placeholder": "", + "theme-description": "", + "theme-label": "", + "week-start-label": "" + }, + "theme": { + "default-label": "" + }, + "title": "" + }, + "sign-up": { + "back-button": "", + "submit-button": "", + "verify": { + "back-button": "", + "complete-button": "", + "header": "", + "info": "", + "send-button": "" + } + }, + "silences": { + "empty-state": { + "button-title": "", + "title": "" + }, + "table": { + "add-silence-button": "", + "edit-button": "", + "expired-silences": "", + "no-matching-silences": "", + "noConfig": "", + "recreate-button": "", + "unsilence-button": "" + } + }, + "silences-table": { + "header": { + "alert-name": "", + "state": "" + } + }, + "snapshot": { + "empty-state": { + "message": "", + "more-info": "" + }, + "external-badge": "", + "name-column-header": "", + "share": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "delete-description": "", + "delete-permission-tooltip": "", + "delete-title": "", + "deleted-alert": "", + "expiration-label": "", + "info-alert": "", + "learn-more-button": "", + "local-button": "", + "name-label": "", + "new-snapshot-button": "", + "success-creation": "", + "success-delete": "", + "view-all-button": "" + }, + "share-panel": { + "info-alert": "" + }, + "url-column-header": "", + "view-button": "" + }, + "table": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "" + } + }, + "tag-filter": { + "clear-button": "", + "loading": "", + "no-tags": "", + "placeholder": "" + }, + "teams": { + "empty-state": { + "button-title": "", + "message": "", + "pro-tip": "", + "title": "" + } + }, + "theme-preview": { + "breadcrumbs": { + "dashboards": "", + "home": "" + }, + "panel": { + "form-label": "", + "title": "" + } + }, + "time-picker": { + "absolute": { + "recent-title": "", + "title": "" + }, + "calendar": { + "apply-button": "", + "cancel-button": "", + "close": "", + "next-month": "", + "previous-month": "", + "select-time": "" + }, + "content": { + "empty-recent-list-docs": "", + "empty-recent-list-info": "", + "filter-placeholder": "" + }, + "copy-paste": { + "copy-success-message": "", + "default-error-message": "", + "default-error-title": "", + "tooltip-copy": "", + "tooltip-paste": "" + }, + "footer": { + "change-settings-button": "", + "fiscal-year-option": "", + "fiscal-year-start": "", + "time-zone-option": "", + "time-zone-selection": "" + }, + "range-content": { + "apply-button": "", + "default-error": "", + "fiscal-year": "", + "from-input": "", + "open-input-calendar": "", + "range-error": "", + "to-input": "" + }, + "range-picker": { + "backwards-time-aria-label": "", + "current-time-selected": "", + "forwards-time-aria-label": "", + "to": "", + "zoom-out-button": "", + "zoom-out-tooltip": "" + }, + "time-range": { + "apply": "", + "aria-role": "", + "default-title": "", + "example": "", + "example-details": "", + "example-title": "", + "from-label": "", + "from-to": "", + "more-info": "", + "specify": "", + "submit-button-label": "", + "supported-formats": "", + "to-label": "" + }, + "zone": { + "select-aria-label": "", + "select-search-input": "" + } + }, + "trails": { + "bookmarks": { + "or-view-bookmarks": "" + }, + "card": { + "date-created": "" + }, + "home": { + "learn-more": "", + "lets-start": "", + "start-your-metrics-exploration": "", + "subtitle": "" + }, + "metric-select": { + "filter-by": "", + "native-histogram": "", + "new-badge": "", + "otel-switch": "" + }, + "native-histogram-banner": { + "ch-heatmap": "", + "ch-histogram": "", + "click-histogram": "", + "hide-examples": "", + "learn-more": "", + "metric-examples": "", + "nh-heatmap": "", + "nh-histogram": "", + "now": "", + "previously": "", + "see-examples": "", + "sentence": "" + }, + "recent-metrics": { + "or-view-a-recent-exploration": "" + }, + "settings": { + "always-keep-selected-metric-graph-in-view": "", + "show-previews-of-metric-graphs": "" + } + }, + "transformations": { + "empty": { + "add-transformation-body": "", + "add-transformation-header": "" + } + }, + "upgrade-box": { + "discovery-text": "", + "discovery-text-continued": "", + "get-started": "", + "learn-more": "", + "upgrade-button": "" + }, + "user-orgs": { + "current-org-button": "", + "name-column": "", + "role-column": "", + "select-org-button": "", + "title": "" + }, + "user-profile": { + "fields": { + "email-error": "", + "email-label": "", + "name-error": "", + "name-label": "", + "username-label": "" + }, + "tabs": { + "general": "" + } + }, + "user-session": { + "auth-module-column": "", + "browser-column": "", + "created-at-column": "", + "identity-provider-column": "", + "ip-column": "", + "revoke": "", + "seen-at-column": "" + }, + "user-sessions": { + "loading": "" + }, + "users": { + "empty-state": { + "message": "" + } + }, + "users-access-list": { + "tabs": { + "public-dashboard-users-tab-title": "", + "shared-dashboard-users-tab-title": "" + } + }, + "variable": { + "adhoc": { + "placeholder": "" + }, + "dropdown": { + "placeholder": "" + }, + "picker": { + "link-all": "", + "option-all": "", + "option-selected-values": "", + "option-tooltip": "" + }, + "textbox": { + "placeholder": "" + } + }, + "variables": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + }, + "unknown-table": { + "loading": "", + "no-unknowns": "", + "renamed-or-missing-variables": "", + "variable": "" + } + } +} \ No newline at end of file diff --git a/public/locales/ko-KR/grafana.json b/public/locales/ko-KR/grafana.json new file mode 100644 index 00000000000..7d47740aff8 --- /dev/null +++ b/public/locales/ko-KR/grafana.json @@ -0,0 +1,3996 @@ +{ + "_comment": "", + "access-control": { + "add-permission": { + "role-label": "", + "serviceaccount-label": "", + "team-label": "", + "title": "", + "user-label": "" + }, + "add-permissions": { + "save": "" + }, + "permission-list": { + "permission": "" + }, + "permission-list-item": { + "inherited": "" + }, + "permissions": { + "add-label": "", + "no-permissions": "", + "permissions-change-warning": "", + "role": "", + "serviceaccount": "", + "team": "", + "title": "", + "user": "" + } + }, + "action-editor": { + "modal": { + "cancel-button": "", + "save-button": "" + } + }, + "admin": { + "anon-users": { + "not-found": "" + }, + "edit-org": { + "access-denied": "", + "heading": "", + "update-button": "", + "users-heading": "" + }, + "feature-toggles": { + "sub-title": "" + }, + "get-enterprise": { + "contact-us": "", + "description": "", + "features-heading": "", + "included-description": "", + "included-heading": "", + "service-title": "", + "team-sync-details": "", + "title": "" + }, + "ldap": { + "test-mapping-heading": "", + "test-mapping-run-button": "" + }, + "ldap-permissions": { + "active": "", + "admin": "", + "inactive": "" + }, + "ldap-status": { + "title": "" + }, + "ldap-sync": { + "debug-button": "", + "external-sync-description": "", + "external-sync-label": "", + "next-sync-label": "", + "not-enabled": "", + "sync-button": "", + "title": "" + }, + "ldap-sync-info": { + "title": "" + }, + "ldap-user-groups": { + "no-org-found": "" + }, + "ldap-user-info": { + "no-team": "" + }, + "org-uers": { + "last-seen-never": "" + }, + "org-users": { + "not-editable": "" + }, + "orgs": { + "delete-body": "", + "id-header": "", + "name-header": "", + "new-org-button": "" + }, + "server-settings": { + "alerts-button": "", + "dashboards-button": "", + "data-sources-button": "", + "not-found": "", + "title": "", + "users-button": "" + }, + "settings": { + "info-description": "" + }, + "upgrade-info": { + "title": "" + }, + "user-orgs": { + "add-button": "", + "change-role-button": "", + "external-user-tooltip": "", + "remove-button": "", + "role-not-editable": "", + "title": "" + }, + "user-orgs-modal": { + "add-button": "", + "cancel-button": "" + }, + "user-permissions": { + "change-button": "", + "grafana-admin-key": "", + "grafana-admin-no": "", + "grafana-admin-yes": "", + "title": "" + }, + "user-profile": { + "delete-button": "", + "disable-button": "", + "edit-button": "", + "enable-button": "", + "title": "" + }, + "user-sessions": { + "browser-column": "", + "force-logout-all-button": "", + "force-logout-button": "", + "ip-column": "", + "last-seen-column": "", + "logged-on-column": "", + "title": "" + }, + "users-create": { + "create-button": "" + }, + "users-list": { + "create-button": "" + }, + "users-table": { + "last-seen-never": "", + "no-licensed-roles": "" + } + }, + "alert-labels": { + "button": { + "hide": "", + "show": { + "tooltip": "" + } + } + }, + "alerting": { + "alert": { + "alert-state": "", + "annotations": "", + "evaluation": "", + "evaluation-paused": "", + "evaluation-paused-description": "", + "last-evaluated": "", + "last-evaluation-duration": "", + "last-updated-at": "", + "last-updated-by": "", + "no-annotations": "", + "pending-period": "", + "rule": "", + "rule-identifier": "", + "rule-type": "", + "state-error-timeout": "", + "state-no-data": "", + "target-datasource-uid": "" + }, + "alert-recording-rule-form": { + "evaluation-behaviour": { + "description": { + "text": "" + } + } + }, + "alert-rules": { + "firing-for": "", + "next-evaluation": "", + "next-evaluation-in": "", + "rule-definition": "" + }, + "alertform": { + "labels": { + "alerting": "", + "recording": "" + } + }, + "alertVersionHistory": { + "alerting": "", + "alerting-change-description": "", + "annotations": "", + "compare": "", + "compare-with-latest": "", + "compareVersions": "", + "comparing-versions": "", + "condition": "", + "contactPointRouting": "", + "description": "", + "errorloading": "", + "execErrorState": "", + "intervalSeconds": "", + "labels": "", + "latest": "", + "name": "", + "namespace_uid": "", + "noDataState": "", + "noVersionsFound": "", + "paused": "", + "pendingPeriod": "", + "provisioning": "", + "provisioning-change-description": "", + "queryAndAlertCondition": "", + "restore": "", + "restore-manually": "", + "restore-modal": { + "body": "", + "confirm": "", + "error": "", + "summary": "", + "title": "" + }, + "restore-version": "", + "rule_group": "", + "unknown": "", + "unknown-change-description": "", + "user-id": "", + "warning-restore-manually": "", + "warning-restore-manually-title": "" + }, + "annotations": { + "description": "", + "title": "" + }, + "central-alert-history": { + "details": { + "error": "", + "header": { + "alert-rule": "", + "instance": "", + "state": "", + "timestamp": "" + }, + "loading": "", + "no-recognized-state": "", + "no-values": "", + "not-found": "", + "number-transitions": "", + "state": { + "alerting": "", + "error": "", + "no-data": "", + "normal": "", + "pending": "" + }, + "state-transitions": "", + "unknown-event-state": "", + "unknown-rule": "", + "value-in-transition": "" + }, + "error": "", + "filter": { + "clear": "", + "info": { + "label1": "", + "label2": "", + "label3": "", + "label4": "" + } + }, + "filterBy": "", + "too-many-events": { + "text": "", + "title": "" + } + }, + "common": { + "cancel": "", + "clear-filters": "", + "delete": "", + "edit": "", + "export": "", + "export-all": "", + "loading": "", + "search-by-matchers": "", + "titles": { + "notification-templates": "" + }, + "view": "" + }, + "contact-points": { + "create": "", + "custom-template-value": "", + "delete-reasons": { + "heading": "", + "no-permissions": "", + "policies": "", + "provisioned": "", + "rules": "" + }, + "delivered-to": "", + "delivery-duration": "", + "empty-state": { + "title": "" + }, + "key-value-map": { + "add": "", + "confirm-add": "" + }, + "last-delivery-attempt": "", + "last-delivery-failed": "", + "no-contact-points-found": "", + "no-delivery-attempts": "", + "no-integrations": "", + "only-firing": "", + "receiver-summary": { + "jira": "" + }, + "telegram": { + "parse-mode-warning-body": "", + "parse-mode-warning-title": "" + }, + "used-by_other": "", + "used-by-rules_other": "" + }, + "contactPointFilter": { + "label": "" + }, + "copy-to-clipboard": "", + "dag": { + "missing-reference": "", + "self-reference": "" + }, + "export": { + "subtitle": { + "formats": "", + "one-format": "" + } + }, + "folderAndGroup": { + "evaluation": { + "modal": { + "text": { + "alerting": "", + "recording": "" + } + } + } + }, + "group-actions": { + "actions-trigger": "", + "delete": "", + "edit": "", + "export": "", + "reorder": "" + }, + "list-view": { + "empty": { + "new-alert-rule": "", + "new-recording-rule": "", + "provisioning": "" + }, + "section": { + "dataSourceManaged": { + "title": "" + }, + "grafanaManaged": { + "export-new-rule": "", + "export-rules": "", + "loading": "", + "new-recording-rule": "", + "title": "" + } + } + }, + "manage-permissions": { + "button": "", + "title": "" + }, + "mute_timings": { + "error-loading": { + "description": "", + "title": "" + } + }, + "mute-timings": { + "add-mute-timing": "", + "description": "", + "save": "", + "saving": "" + }, + "notification-preview": { + "alertmanager": "", + "error": "", + "initialized": "", + "preview-routing": "", + "title": "", + "uninitialized": "" + }, + "notification-templates": { + "duplicate": { + "subTitle": "", + "title": "" + }, + "edit": { + "subTitle": "", + "title": "" + }, + "new": { + "subTitle": "", + "title": "" + } + }, + "policies": { + "default-policy": { + "description": "", + "title": "", + "update": "" + }, + "delete": { + "confirm": "", + "warning-1": "", + "warning-2": "" + }, + "filter-description": "", + "generated-policies": "", + "matchers": "", + "metadata": { + "active-time": "", + "delivered-to": "", + "grouped-by": "", + "grouping": { + "none": "", + "single-group": "" + }, + "inherited": "", + "mute-time": "", + "timingOptions": { + "groupInterval": { + "description": "", + "label": "" + }, + "groupWait": { + "description": "", + "label": "" + }, + "repeatInterval": { + "description": "", + "label": "" + } + }, + "n-instances_other": "" + }, + "new-child": "", + "new-policy": "", + "no-matchers": "", + "reload-policies": "", + "save-policy": "", + "update": { + "please-wait": "", + "update-policy": "", + "updating": "" + }, + "update-errors": { + "conflict": "", + "error-code": "", + "fallback": "", + "suffix": "", + "title": "" + }, + "n-more-policies_other": "" + }, + "provisioning": { + "badge-tooltip-provenance": "", + "badge-tooltip-standard": "" + }, + "queryAndExpressionsStep": { + "disableAdvancedOptions": { + "text": "" + }, + "preview": "", + "previewCondition": "" + }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, + "rule-form": { + "evaluation": { + "evaluation-group-and-interval": "", + "group": { + "cancel": "", + "create": "", + "interval": "" + }, + "group-name": "", + "group-text": "", + "new-group": "", + "pause": { + "alerting": "", + "recording": "" + }, + "select-folder-before": "" + }, + "evaluation-behaviour": { + "description": { + "text": "" + }, + "info-help": { + "text": "" + }, + "pending-period": "" + }, + "evaluation-behaviour-description1": "", + "evaluation-behaviour-description2": "", + "evaluation-behaviour-description3": "", + "evaluation-behaviour-for": { + "error-parsing": "", + "validation": "" + }, + "folder": { + "cancel": "", + "create": "", + "create-folder": "", + "creating-new-folder": "", + "label": "", + "name": "", + "new-folder": "", + "new-folder-or": "" + }, + "folder-and-labels": "", + "folders": { + "help-info": "" + }, + "labels": { + "help-info": "" + }, + "pause": { + "label": "" + }, + "threshold": { + "recovery": { + "stop-alerting-above": "", + "stop-alerting-bellow": "", + "stop-alerting-equal": "", + "stop-alerting-inside-range": "", + "stop-alerting-less": "", + "stop-alerting-more": "", + "stop-alerting-not-equal": "", + "stop-alerting-outside-range": "", + "title": "" + } + } + }, + "rule-groups": { + "delete": { + "success": "" + }, + "move": { + "success": "" + }, + "rename": { + "success": "" + }, + "update": { + "success": "" + } + }, + "rule-list": { + "configure-datasource": "", + "ds-error-boundary": { + "description": "", + "title": "" + }, + "filter-view": { + "no-more-results": "", + "no-rules-found": "" + }, + "new-alert-rule": "", + "pagination": { + "next-page": "", + "previous-page": "" + }, + "return-button": { + "title": "" + }, + "rulerrule-loading-error": "" + }, + "rule-state": { + "creating": "", + "deleting": "", + "paused": "", + "recording-rule": "" + }, + "rule-view": { + "query": { + "datasources-na": { + "description": "", + "title": "" + } + } + }, + "rule-viewer": { + "error-loading": "", + "prometheus-consistency-check": { + "alert-message": "", + "alert-title": "" + } + }, + "rules": { + "add-rule": { + "success": "" + }, + "delete-rule": { + "success": "" + }, + "pause-rule": { + "success": "" + }, + "resume-rule": { + "success": "" + }, + "update-rule": { + "success": "" + } + }, + "search": { + "property": { + "data-source": "", + "evaluation-group": "", + "labels": "", + "namespace": "", + "rule-health": "", + "rule-name": "", + "rule-type": "", + "state": "" + }, + "save-query": "" + }, + "silences": { + "affected-instances": "", + "only-firing-instances": "", + "preview-affected-instances": "" + }, + "simpleCondition": { + "alertCondition": "" + }, + "templates": { + "editor": { + "add-example": "", + "auto-complete": "", + "goto-docs": "" + }, + "help": { + "intro": "" + }, + "misconfigured-badge-text": "", + "misconfigured-warning": "", + "misconfigured-warning-details": "" + }, + "threshold": { + "to": "" + } + }, + "annotations": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + } + }, + "api-keys": { + "empty-state": { + "message": "" + } + }, + "app-chrome": { + "skip-content-button": "", + "top-bar": { + "sign-in": "" + } + }, + "app-notification": { + "item": { + "trace-id": "" + } + }, + "bookmarks-page": { + "empty": { + "message": "", + "tip": "" + } + }, + "bouncing-loader": { + "label": "" + }, + "browse-dashboards": { + "action": { + "cancel-button": "", + "cannot-move-folders": "", + "confirmation-text": "", + "delete-button": "", + "delete-modal-invalid-text": "", + "delete-modal-invalid-title": "", + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "delete-modal-title": "", + "deleting": "", + "manage-permissions-button": "", + "move-button": "", + "move-modal-alert": "", + "move-modal-field-label": "", + "move-modal-text": "", + "move-modal-title": "", + "moving": "", + "new-folder-name-required-phrase": "" + }, + "actions": { + "button-to-recently-deleted": "" + }, + "counts": { + "alertRule_other": "", + "dashboard_other": "", + "folder_other": "", + "libraryPanel_other": "", + "total_other": "" + }, + "dashboards-tree": { + "collapse-folder-button": "", + "expand-folder-button": "", + "name-column": "", + "select-all-header-checkbox": "", + "select-checkbox": "", + "tags-column": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "", + "title-folder": "" + }, + "folder-actions-button": { + "delete": "", + "folder-actions": "", + "manage-permissions": "", + "move": "" + }, + "folder-picker": { + "accessible-label": "", + "button-label": "", + "clear-selection": "", + "empty-message": "", + "error-title": "", + "non-folder-item": "", + "search-placeholder": "", + "unknown-error": "" + }, + "hard-delete": { + "success": "" + }, + "manage-folder-nav": { + "alert-rules": "", + "dashboards": "", + "panels": "" + }, + "new-folder-form": { + "cancel-label": "", + "create-label": "", + "name-label": "" + }, + "no-results": { + "clear": "", + "text": "" + }, + "soft-delete": { + "success": "" + } + }, + "clipboard-button": { + "inline-toast": { + "success": "" + } + }, + "combobox": { + "async": { + "error": "" + }, + "clear": { + "title": "" + }, + "custom-value": { + "description": "" + }, + "group": { + "undefined": "" + }, + "options": { + "no-found": "" + } + }, + "command-palette": { + "action": { + "change-theme": "", + "dark-theme": "", + "light-theme": "" + }, + "empty-state": { + "message": "" + }, + "search-box": { + "placeholder": "" + }, + "section": { + "actions": "", + "dashboard-search-results": "", + "folder-search-results": "", + "pages": "", + "preferences": "", + "recent-dashboards": "" + } + }, + "common": { + "apply": "", + "cancel": "", + "clear": "", + "close": "", + "collapse": "", + "edit": "", + "help": "", + "loading": "", + "locale": { + "default": "" + }, + "save": "", + "search": "", + "view": "" + }, + "configuration-tracker": { + "config-card": { + "complete": "" + } + }, + "connections": { + "connect-data": { + "category-header-label": "", + "empty-message": "", + "request-data-source": "", + "roadmap": "" + }, + "search": { + "placeholder": "" + } + }, + "core": { + "versionHistory": { + "comparison": { + "header": { + "hide-json-diff": "", + "show-json-diff": "", + "text": "" + }, + "select": "" + }, + "no-properties-changed": "", + "table": { + "updated": "", + "updatedBy": "", + "version": "" + }, + "view-json-diff": "" + } + }, + "correlations": { + "add-new": "", + "alert": { + "error-message": "", + "title": "" + }, + "basic-info-form": { + "description-description": "", + "description-label": "", + "label-description": "", + "label-label": "", + "label-placeholder": "", + "label-required": "", + "sub-text": "", + "title": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + }, + "list": { + "delete": "", + "label": "", + "loading": "", + "read-only": "", + "source": "", + "target": "" + }, + "navigation-form": { + "add-button": "", + "back-button": "", + "next-button": "", + "save-button": "" + }, + "page-content": "", + "page-heading": "", + "query-editor": { + "control-rules": "", + "data-source-text": "", + "data-source-title": "", + "error-text": "", + "error-title": "", + "loading": "", + "query-description": "", + "query-editor-title": "", + "query-label": "" + }, + "source-form": { + "control-required": "", + "description": "", + "description-external-pre": "", + "description-query-pre": "", + "external-title": "", + "heading-external": "", + "heading-query": "", + "query-title": "", + "results-description": "", + "results-label": "", + "results-required": "", + "source-description": "", + "source-label": "", + "sub-text": "" + }, + "sub-title": "", + "target-form": { + "control-rules": "", + "sub-text": "", + "target-description-external": "", + "target-description-query": "", + "target-label": "", + "target-type-description": "", + "title": "", + "type-label": "" + }, + "trans-details": { + "logfmt-description": "", + "logfmt-label": "", + "regex-description": "", + "regex-expression": "", + "regex-label": "", + "regex-map-values": "" + }, + "transform": { + "add-button": "", + "heading": "", + "no-transform": "" + }, + "transform-row": { + "expression-label": "", + "expression-required": "", + "expression-tooltip": "", + "field-input": "", + "field-label": "", + "field-tooltip": "", + "map-value-label": "", + "map-value-tooltip": "", + "remove-button": "", + "remove-tooltip": "", + "transform-required": "", + "type-label": "", + "type-tooltip": "" + } + }, + "dashboard": { + "add-menu": { + "import": "", + "paste-panel": "", + "row": "", + "visualization": "" + }, + "alert-rules-drawer": { + "redirect-link": "", + "subtitle": "" + }, + "default-layout": { + "description": "", + "item-options": { + "repeat": { + "direction": { + "horizontal": "", + "title": "", + "vertical": "" + }, + "max": "", + "title": "", + "variable": { + "description": "", + "title": "" + } + } + }, + "name": "", + "row-actions": { + "delete": "", + "modal": { + "alt-action": "", + "text": "", + "title": "" + } + }, + "row-options": { + "button": { + "label": "" + }, + "form": { + "cancel": "", + "repeat-for": { + "label": "", + "learn-more": "", + "warning": { + "text": "" + } + }, + "title": "", + "update": "" + }, + "modal": { + "title": "" + }, + "repeat": { + "title": "", + "variable": { + "title": "" + } + }, + "title": "" + } + }, + "edit-pane": { + "elements": { + "dashboard": "", + "objects": "", + "panel": "", + "panels": "", + "row": "", + "rows": "", + "tab": "", + "tabs": "" + }, + "open": "", + "row": { + "header": { + "hide": "", + "title": "" + } + } + }, + "editpane": { + "add": "", + "configure": "", + "outline": "" + }, + "empty": { + "add-library-panel-body": "", + "add-library-panel-button": "", + "add-library-panel-header": "", + "add-visualization-body": "", + "add-visualization-button": "", + "add-visualization-header": "", + "import-a-dashboard-body": "", + "import-a-dashboard-header": "", + "import-dashboard-button": "" + }, + "errors": { + "failed-to-load": "" + }, + "inspect": { + "data-tab": "", + "error-tab": "", + "json-tab": "", + "meta-tab": "", + "query-tab": "", + "stats-tab": "", + "subtitle": "", + "title": "" + }, + "inspect-data": { + "data-options": "", + "dataframe-aria-label": "", + "dataframe-label": "", + "download-csv": "", + "download-excel-description": "", + "download-excel-label": "", + "download-logs": "", + "download-service": "", + "download-traces": "", + "excel-header": "", + "formatted": "", + "formatted-data-description": "", + "formatted-data-label": "", + "panel-transforms": "", + "series-to-columns": "", + "transformation": "", + "transformations-description": "", + "transformations-label": "" + }, + "inspect-json": { + "dataframe-description": "", + "dataframe-label": "", + "panel-data-description": "", + "panel-data-label": "", + "panel-json-description": "", + "panel-json-label": "", + "select-source": "", + "unknown": "" + }, + "inspect-meta": { + "no-inspector": "" + }, + "inspect-stats": { + "data-title": "", + "data-traceids": "", + "processing-time": "", + "queries": "", + "request-time": "", + "rows": "", + "table-title": "" + }, + "layout": { + "common": { + "copy": "", + "copy-or-duplicate": "", + "delete": "", + "duplicate": "", + "layout": "" + } + }, + "options": { + "description": "", + "title-option": "" + }, + "outline": { + "tree": { + "item": { + "collapse": "", + "empty": "", + "expand": "" + } + } + }, + "panel-edit": { + "alerting-tab": { + "dashboard-not-saved": "", + "no-rules": "" + } + }, + "responsive-layout": { + "description": "", + "item-options": { + "hide-no-data": "", + "repeat": { + "variable": { + "description": "", + "title": "" + } + }, + "title": "" + }, + "name": "", + "options": { + "columns": "", + "fixed": "", + "min": "", + "one-column": "", + "rows": "", + "three-columns": "", + "two-columns": "" + } + }, + "rows-layout": { + "description": "", + "name": "", + "option": { + "height": "", + "hide-header": "", + "repeat": "", + "title": "" + }, + "options": { + "height-expand": "", + "height-min": "" + }, + "row": { + "collapse": "", + "expand": "", + "menu": { + "add": "", + "add-panel": "", + "add-row-above": "", + "add-row-below": "", + "move-down": "", + "move-row": "", + "move-up": "" + }, + "new": "", + "repeat": { + "learn-more": "", + "warning": "" + } + }, + "row-options": { + "title-option": "" + } + }, + "tabs-layout": { + "description": "", + "menu": { + "move-tab": "" + }, + "name": "", + "tab": { + "menu": { + "add": "", + "add-panel": "", + "add-tab-above": "", + "add-tab-after": "", + "add-tab-before": "", + "move-left": "", + "move-right": "" + }, + "new": "" + }, + "tab-options": { + "title-option": "" + } + }, + "toolbar": { + "add": "", + "add-panel": "", + "add-panel-description": "", + "add-panel-lib": "", + "add-row": "", + "add-tab": "", + "alert-rules": "", + "back-to-dashboard": "", + "dashboard-settings": { + "label": "", + "tooltip": "" + }, + "discard-library-panel-changes": "", + "discard-panel": "", + "discard-panel-new": "", + "edit": { + "label": "", + "tooltip": "" + }, + "edit-dashboard-v2-schema": "", + "enter-edit-mode": { + "label": "", + "tooltip": "" + }, + "exit-edit-mode": { + "label": "", + "tooltip": "" + }, + "libray-panel-description": "", + "mark-favorite": "", + "more-save-options": "", + "open-original": "", + "playlist-next": "", + "playlist-previous": "", + "playlist-stop": "", + "public-dashboard": "", + "refresh": "", + "row-description": "", + "save": "", + "save-dashboard": { + "label": "", + "tooltip": "" + }, + "save-dashboard-copy": { + "label": "", + "tooltip": "" + }, + "save-dashboard-short": "", + "save-library-panel": "", + "settings": "", + "share": { + "label": "", + "tooltip": "" + }, + "share-button": "", + "show-hidden-elements": "", + "switch-old-dashboard": "", + "tabs-description": "", + "unlink-library-panel": "", + "unmark-favorite": "" + }, + "validation": { + "invalid-dashboard-id": "", + "invalid-json": "", + "tags-expected-array": "", + "tags-expected-strings": "" + }, + "viz-panel": { + "options": { + "description": "", + "open-edit": "", + "plugin-type-image": "", + "title-option": "", + "transparent-background": "" + } + } + }, + "dashboard-import": { + "file-dropzone": { + "primary-text": "", + "secondary-text": "" + }, + "form-actions": { + "cancel": "", + "load": "" + }, + "gcom-field": { + "label": "", + "load-button": "", + "placeholder": "", + "validation-required": "" + }, + "json-field": { + "label": "", + "validation-required": "" + } + }, + "dashboard-links": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "title": "" + } + }, + "dashboard-settings": { + "annotations": { + "title": "" + }, + "dashboard-delete-button": "", + "delete-modal": { + "confirmation-text": "", + "delete-button": "", + "title": "" + }, + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "general": { + "auto-refresh-description": "", + "auto-refresh-label": "", + "description-label": "", + "editable-description": "", + "editable-label": "", + "folder-label": "", + "panel-options-graph-tooltip-description": "", + "panel-options-graph-tooltip-label": "", + "panel-options-label": "", + "panels-preload-description": "", + "panels-preload-label": "", + "tags-label": "", + "title": "", + "title-label": "" + }, + "json-editor": { + "save-button": "", + "subtitle": "", + "title": "" + }, + "links": { + "title": "" + }, + "permissions": { + "title": "" + }, + "provisioned-delete-modal": { + "confirm-button": "", + "text-1": "", + "text-2": "", + "text-3": "", + "text-link": "", + "title": "" + }, + "settings": { + "title": "" + }, + "time-picker": { + "hide-time-picker": "", + "now-delay-description": "", + "now-delay-label": "", + "refresh-live-dashboards-description": "", + "refresh-live-dashboards-label": "", + "time-options-label": "", + "time-zone-label": "", + "week-start-label": "" + }, + "time-regions": { + "advanced-description-cron": "", + "advanced-description-rest": "", + "advanced-description-use": "", + "advanced-label": "" + }, + "variables": { + "title": "" + }, + "versions": { + "title": "" + } + }, + "dashboards": { + "panel-edit": { + "angular-deprecation-button-open-panel-json": "", + "angular-deprecation-description": "", + "angular-deprecation-heading": "" + }, + "panel-queries": { + "add-query-from-library": "" + }, + "settings": { + "variables": { + "dependencies": { + "button": "", + "title": "" + } + } + } + }, + "data-source-list": { + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + } + }, + "data-source-picker": { + "add-new-data-source": "", + "built-in-list": { + "description-dashboard": "", + "description-grafana": "", + "description-mixed": "" + }, + "list": { + "no-data-source-message": "" + }, + "modal": { + "configure-new-data-source": "", + "input-placeholder": "", + "title": "" + }, + "open-advanced-button": "" + }, + "data-source-testing-status-page": { + "error-more-details-link": "", + "success-more-details-links": "" + }, + "data-sources": { + "datasource-add-button": { + "label": "" + }, + "empty-state": { + "message": "" + } + }, + "embed": { + "share": { + "time-range-description": "", + "time-range-label": "" + } + }, + "empty-list-cta": { + "pro-tip": "" + }, + "entity-not-found": { + "description": "" + }, + "errors": { + "dashboard-settings": { + "annotations": { + "datasource": "" + } + } + }, + "explore": { + "add-to-dashboard": "", + "drilldownInfo": { + "action": "", + "description": "", + "title": "" + }, + "logs": { + "logs-volume": { + "add-filters": "", + "decrease-timerange": "", + "much-data": "" + }, + "maximum-pinned-logs": "", + "no-logs-found": "", + "scan-for-older-logs": "", + "stop-scan": "" + }, + "rich-history": { + "close-tooltip": "", + "datasource-a-z": "", + "datasource-z-a": "", + "newest-first": "", + "oldest-first": "", + "query-history": "", + "query-library": "", + "settings": "", + "starred": "" + }, + "rich-history-card": { + "add-comment-form": "", + "add-comment-tooltip": "", + "add-to-library": "", + "cancel": "", + "confirm-delete": "", + "copy-query-tooltip": "", + "copy-shortened-link-tooltip": "", + "datasource-icon-label": "", + "datasource-name-label": "", + "datasource-not-exist": "", + "delete-query-confirmation-title": "", + "delete-query-title": "", + "delete-query-tooltip": "", + "delete-starred-query-confirmation-text": "", + "edit-comment-tooltip": "", + "optional-description": "", + "query-comment-label": "", + "query-text-label": "", + "save-comment": "", + "star-query-tooltip": "", + "unstar-query-tooltip": "", + "update-comment-form": "" + }, + "rich-history-container": { + "loading": "" + }, + "rich-history-notification": { + "query-copied": "", + "query-deleted": "" + }, + "rich-history-queries-tab": { + "displaying-partial-queries": "", + "displaying-queries": "", + "filter-aria-label": "", + "filter-history": "", + "filter-placeholder": "", + "history-local": "", + "loading": "", + "loading-results": "", + "search-placeholder": "", + "showing-queries": "", + "sort-aria-label": "", + "sort-placeholder": "" + }, + "rich-history-settings-tab": { + "alert-info": "", + "change-default-tab": "", + "clear-history-info": "", + "clear-query-history": "", + "clear-query-history-button": "", + "delete-confirm": "", + "delete-confirm-text": "", + "delete-title": "", + "history-time-span": "", + "history-time-span-description": "", + "only-show-active-datasource": "", + "query-history-deleted": "", + "retention-period": { + "1-week": "", + "2-days": "", + "2-weeks": "", + "5-days": "" + } + }, + "rich-history-starred-tab": { + "filter-queries-aria-label": "", + "filter-queries-placeholder": "", + "loading": "", + "loading-results": "", + "local-history-message": "", + "search-queries-placeholder": "", + "showing-queries": "", + "sort-queries-aria-label": "", + "sort-queries-placeholder": "" + }, + "rich-history-utils": { + "a-week-ago": "", + "days-ago": "", + "default-from": "", + "default-to": "", + "today": "", + "two-weeks-ago": "", + "yesterday": "" + }, + "rich-history-utils-notification": { + "saving-failed": "", + "update-failed": "" + }, + "run-query": { + "left-pane": "", + "right-pane": "", + "run-query-button": "", + "switch-datasource-button": "" + }, + "secondary-actions": { + "add-from-query-library": "", + "query-add-button": "", + "query-add-button-aria-label": "", + "query-history-button": "", + "query-history-button-aria-label": "", + "query-inspector-button": "", + "query-inspector-button-aria-label": "" + }, + "table": { + "no-data": "", + "title": "", + "title-with-name": "" + }, + "toolbar": { + "add-to-extensions": "", + "add-to-queryless-extensions": "", + "aria-label": "", + "copy-link": "", + "copy-link-abs-time": "", + "copy-links-absolute-category": "", + "copy-links-normal-category": "", + "copy-shortened-link": "", + "copy-shortened-link-abs-time": "", + "copy-shortened-link-label": "", + "copy-shortened-link-menu": "", + "refresh-picker-cancel": "", + "refresh-picker-run": "", + "split-close": "", + "split-close-tooltip": "", + "split-narrow": "", + "split-title": "", + "split-tooltip": "", + "split-widen": "" + } + }, + "explore-metrics": { + "breakdown": { + "clearFilter": "", + "labelSelect": "", + "missing-otel-labels": "", + "noMatchingValue": "", + "sortBy": "" + }, + "related-logs": { + "LrrDocsLink": "", + "openExploreLogs": "", + "relatedLogsUnavailable": "", + "warnExperimentalFeature": "" + }, + "viewBy": "" + }, + "export": { + "json": { + "cancel-button": "", + "copy-button": "", + "download-button": "", + "download-successful_toast_message": "", + "export-externally-label": "", + "info-text": "", + "title": "" + }, + "menu": { + "export-as-json-label": "", + "export-as-json-tooltip": "" + } + }, + "folder-filter": { + "clear-folder-button": "" + }, + "folder-picker": { + "create-instructions": "", + "loading": "" + }, + "forgot-password": { + "back-button": "", + "change-password": { + "skip-button": "", + "submit-button": "" + }, + "contact-admin": "", + "email-sent": "", + "reset-password-header": "", + "send-email-button": "" + }, + "form-prompt": { + "continue-button": "", + "description": "", + "discard-button": "" + }, + "gen-ai": { + "apply-suggestion": "", + "incomplete-request-error": "", + "send-custom-feedback": "" + }, + "get-enterprise": { + "requires-license": "", + "title": "" + }, + "grafana-ui": { + "action-editor": { + "button": { + "confirm": "", + "confirm-action": "" + }, + "inline": { + "add-action": "", + "edit-action": "" + }, + "modal": { + "action-body": "", + "action-method": "", + "action-query-params": "", + "action-title": "", + "action-title-placeholder": "", + "one-click-description": "" + } + }, + "alert": { + "close-button": "" + }, + "auto-save-field": { + "saved": "", + "saving": "" + }, + "card": { + "option": "" + }, + "cascader": { + "clear-button": "" + }, + "color-picker-popover": { + "palette-tab": "", + "spectrum-tab": "" + }, + "confirm-button": { + "cancel": "" + }, + "confirm-content": { + "placeholder": "" + }, + "data-link-editor": { + "info": "", + "new-tab-label": "", + "title-label": "", + "title-placeholder": "", + "url-label": "" + }, + "data-link-editor-modal": { + "cancel": "", + "one-click-description": "", + "save": "" + }, + "data-link-inline-editor": { + "one-click": "" + }, + "data-links-inline-editor": { + "add-link": "", + "edit-link": "", + "one-click": "", + "one-click-enabled": "", + "title-not-provided": "", + "tooltip-edit": "", + "tooltip-remove": "", + "url-not-provided": "" + }, + "data-source-basic-auth-settings": { + "user-label": "", + "user-placeholder": "" + }, + "data-source-http-proxy-settings": { + "oauth-identity-label": "", + "oauth-identity-tooltip": "", + "skip-tls-verify-label": "", + "ts-client-auth-label": "", + "with-ca-cert-label": "", + "with-ca-cert-tooltip": "" + }, + "data-source-http-settings": { + "access-help": "", + "access-help-details": "", + "access-label": "", + "access-options-browser": "", + "access-options-proxy": "", + "allowed-cookies": "", + "allowed-cookies-tooltip": "", + "auth": "", + "azure-auth-label": "", + "azure-auth-tooltip": "", + "basic-auth": "", + "basic-auth-label": "", + "browser-mode-description": "", + "browser-mode-title": "", + "default-url-access-select": "", + "default-url-tooltip": "", + "direct-url-tooltip": "", + "heading": "", + "proxy-url-tooltip": "", + "server-mode-description": "", + "server-mode-title": "", + "timeout-form-label": "", + "timeout-label": "", + "timeout-tooltip": "", + "url-label": "", + "with-credential-label": "", + "with-credential-tooltip": "" + }, + "data-source-settings": { + "alerting-settings-heading": "", + "alerting-settings-label": "", + "alerting-settings-tooltip": "", + "cert-key-reset": "", + "custom-headers-add": "", + "custom-headers-header": "", + "custom-headers-header-placeholder": "", + "custom-headers-header-remove": "", + "custom-headers-header-value": "", + "custom-headers-title": "", + "secure-socks-heading": "", + "secure-socks-label": "", + "secure-socks-tooltip": "", + "tls-certification-label": "", + "tls-certification-placeholder": "", + "tls-client-certification-label": "", + "tls-client-key-label": "", + "tls-client-key-placeholder": "", + "tls-heading": "", + "tls-server-name-label": "", + "tls-tooltip": "" + }, + "date-time-picker": { + "apply": "", + "calendar-icon-label": "", + "cancel": "", + "next-label": "", + "previous-label": "", + "select-placeholder": "" + }, + "drawer": { + "close": "" + }, + "feature-badge": { + "experimental": "", + "new": "", + "preview": "", + "private-preview": "" + }, + "field-link-list": { + "external-links-heading": "" + }, + "file-dropzone": { + "cancel-upload": "", + "file-too-large": "" + }, + "filter-input": { + "clear": "" + }, + "modal": { + "close-tooltip": "" + }, + "named-colors-palette": { + "text-color-swatch": "", + "transparent-swatch": "" + }, + "page-toolbar": { + "go-back": "", + "search-dashboard-name": "", + "search-links": "", + "search-parent-folder": "" + }, + "pagination": { + "next-page": "", + "previous-page": "" + }, + "secret-form-field": { + "reset": "" + }, + "segment-async": { + "error": "", + "loading": "", + "no-options": "" + }, + "select": { + "default-create-label": "", + "no-options-label": "", + "placeholder": "" + }, + "series-color-picker-popover": { + "y-axis-usage": "" + }, + "spinner": { + "aria-label": "" + }, + "table": { + "copy": "", + "csv-counts": "", + "filter-popup-apply": "", + "filter-popup-cancel": "", + "filter-popup-clear": "", + "filter-popup-heading": "", + "no-values-label": "", + "pagination-summary": "" + }, + "tags-input": { + "add": "" + }, + "user-icon": { + "active-text": "" + }, + "value-pill": { + "remove-button": "" + }, + "viz-legend": { + "right-axis-indicator": "" + }, + "viz-tooltip": { + "actions-confirmation-input-placeholder": "", + "actions-confirmation-label": "", + "actions-confirmation-message": "", + "footer-add-annotation": "", + "footer-click-to-action": "", + "footer-click-to-navigate": "" + } + }, + "graph": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "", + "title": "" + } + }, + "help-modal": { + "column-headers": { + "description": "", + "keys": "" + }, + "shortcuts-category": { + "dashboard": "", + "focused-panel": "", + "global": "", + "time-range": "" + }, + "shortcuts-description": { + "change-theme": "", + "collapse-all-rows": "", + "copy-time-range": "", + "dashboard-settings": "", + "duplicate-panel": "", + "exit-edit/setting-views": "", + "expand-all-rows": "", + "go-to-dashboards": "", + "go-to-explore": "", + "go-to-home-dashboard": "", + "go-to-profile": "", + "make-time-range-permanent": "", + "move-time-range-back": "", + "move-time-range-forward": "", + "open-search": "", + "open-shared-modal": "", + "paste-time-range": "", + "refresh-all-panels": "", + "remove-panel": "", + "save-dashboard": "", + "show-all-shortcuts": "", + "toggle-active-mode": "", + "toggle-all-panel-legends": "", + "toggle-auto-fit": "", + "toggle-exemplars": "", + "toggle-graph-crosshair": "", + "toggle-kiosk": "", + "toggle-panel-edit": "", + "toggle-panel-fullscreen": "", + "toggle-panel-legend": "", + "zoom-out-time-range": "" + }, + "title": "" + }, + "help-wizard": { + "download-snapshot": "", + "github-comment": "", + "support-bundle": "", + "troubleshooting-help": "" + }, + "inspector": { + "query": { + "collapse-all": "", + "copy-to-clipboard": "", + "description": "", + "expand-all": "", + "no-data": "", + "refresh": "" + } + }, + "ldap-drawer": { + "attributes-section": { + "description": "", + "email-label": "", + "label": "", + "member-of-label": "", + "name-label": "", + "surname-label": "", + "username-label": "" + }, + "extra-security-section": { + "client-cert-label": "", + "client-cert-placeholder": "", + "client-cert-value-label": "", + "client-cert-value-placeholder": "", + "client-key-label": "", + "client-key-placeholder": "", + "client-key-value-label": "", + "client-key-value-placeholder": "", + "encryption-provider-base-64": "", + "encryption-provider-description": "", + "encryption-provider-file-path": "", + "encryption-provider-label": "", + "label": "", + "min-tls-version-description": "", + "min-tls-version-label": "", + "root-ca-cert-label": "", + "root-ca-cert-placeholder": "", + "root-ca-cert-value-label": "", + "root-ca-cert-value-placeholder": "", + "start-tls-description": "", + "start-tls-label": "", + "tls-ciphers-label": "", + "tls-ciphers-placeholder": "", + "use-ssl-description": "", + "use-ssl-label": "", + "use-ssl-tooltip": "" + }, + "group-mapping": { + "grafana-admin": { + "description": "", + "label": "" + }, + "group-dn": { + "description": "", + "label": "" + }, + "org-id": { + "description": "", + "label": "" + }, + "org-role": { + "label": "" + }, + "remove": { + "button": "" + } + }, + "group-mapping-section": { + "add": { + "button": "" + }, + "description": "", + "group-search-base-dns-label": "", + "group-search-base-dns-placeholder": "", + "group-search-filter-description": "", + "group-search-filter-label": "", + "group-search-filter-user-attribute-description": "", + "group-search-filter-user-attribute-label": "", + "label": "", + "skip-org-role-sync-description": "", + "skip-org-role-sync-label": "" + }, + "misc-section": { + "allow-sign-up-descrition": "", + "allow-sign-up-label": "", + "label": "", + "port-description": "", + "port-label": "", + "timeout-description": "", + "timeout-label": "" + }, + "title": "" + }, + "ldap-settings-page": { + "advanced-settings-section": { + "edit-button": "", + "subtitle": "", + "title": "" + }, + "alert": { + "discard-success": "", + "error-fetching": "", + "error-saving": "", + "error-validate-form": "", + "feature-flag-disabled": "", + "saved": "" + }, + "bind-dn": { + "description": "", + "label": "", + "placeholder": "" + }, + "bind-password": { + "label": "" + }, + "buttons-section": { + "disable-button": "", + "discard-button": "", + "save-and-enable-button": "", + "save-button": "" + }, + "documentation": "", + "host": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "login-form-alert": { + "description": "", + "title": "" + }, + "search_filter": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "search-base-dns": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "subtitle": "", + "title": "" + }, + "library-panel": { + "add-modal": { + "cancel": "", + "create": "", + "error": "", + "folder": "", + "folder-description": "", + "name": "" + }, + "add-widget": { + "title": "" + }, + "empty-state": { + "message": "", + "more-info": "" + } + }, + "library-panels": { + "empty-state": { + "message": "" + }, + "loading-panel-text": "", + "modal": { + "button-cancel": "", + "button-view-panel1": "", + "button-view-panel2": "", + "panel-not-linked": "", + "select-no-options-message": "", + "select-placeholder": "", + "title": "", + "body_other": "" + }, + "save": { + "error": "", + "success": "" + } + }, + "link": { + "share": { + "config-alert-description": "", + "config-alert-title": "", + "config-description": "", + "copy-link-button": "", + "copy-to-clipboard": "", + "short-url-label": "", + "time-range-description": "", + "time-range-label": "" + }, + "share-panel": { + "config-description": "", + "download-image": "", + "render-image": "", + "render-image-error": "", + "render-image-error-description": "" + } + }, + "lock-icon": "", + "login": { + "divider": { + "connecting-text": "" + }, + "error": { + "blocked": "", + "invalid-user-or-password": "", + "title": "", + "unknown": "" + }, + "forgot-password": "", + "form": { + "confirmation-code": "", + "confirmation-code-label": "", + "confirmation-code-placeholder": "", + "email-label": "", + "email-placeholder": "", + "email-required": "", + "name-label": "", + "name-placeholder": "", + "password-label": "", + "password-placeholder": "", + "password-required": "", + "submit-label": "", + "submit-loading-label": "", + "username-label": "", + "username-placeholder": "", + "username-required": "", + "verify-email-label": "", + "verify-email-loading-label": "" + }, + "layout": { + "update-password": "" + }, + "services": { + "sing-in-with-prefix": "" + }, + "signup": { + "button-label": "", + "new-to-question": "" + } + }, + "logs": { + "infinite-scroll": { + "end-of-range": "", + "load-more": "", + "load-newer": "", + "load-older": "", + "older-logs": "" + }, + "log-details": { + "fields": "", + "links": "", + "log-line": "", + "no-details": "" + }, + "log-line-menu": { + "copy-link": "", + "copy-log": "", + "icon-label": "", + "pin-to-outline": "", + "show-context": "", + "unpin-from-outline": "" + }, + "log-row-message": { + "ellipsis": "", + "more": "", + "see-details": "" + }, + "log-rows": { + "disable-popover": { + "confirm": "", + "message": "", + "title": "" + }, + "disable-popover-message": { + "shortcut": "" + } + }, + "logs-navigation": { + "newer-logs": "", + "older-logs": "", + "scroll-bottom": "", + "scroll-top": "", + "start-of-range": "" + }, + "popover-menu": { + "copy": "", + "disable-menu": "", + "line-contains": "", + "line-contains-not": "" + } + }, + "migrate-to-cloud": { + "build-snapshot": { + "description": "", + "title": "", + "when-complete": "" + }, + "building-snapshot": { + "description": "", + "description-eta": "", + "title": "" + }, + "can-i-move": { + "body": "", + "link-title": "", + "title": "" + }, + "connect-modal": { + "body-cloud-stack": "", + "body-get-started": "", + "body-sign-up": "", + "body-token": "", + "body-token-field": "", + "body-token-field-placeholder": "", + "body-token-instructions": "", + "body-view-stacks": "", + "cancel": "", + "connect": "", + "connecting": "", + "title": "", + "token-error-title": "", + "token-errors": { + "instance-request-error": "", + "instance-unreachable": "", + "migration-disabled": "", + "session-creation-failure": "", + "token-invalid": "", + "token-not-saved": "", + "token-request-error": "", + "token-validation-failure": "" + }, + "token-required-error": "" + }, + "cta": { + "button": "", + "header": "" + }, + "delete-migration-token-confirm": { + "body": "", + "confirm-button": "", + "error-title": "", + "title": "" + }, + "disconnect-modal": { + "body": "", + "cancel": "", + "disconnect": "", + "disconnecting": "", + "error": "", + "title": "" + }, + "get-started": { + "body": "", + "configure-pdc-link": "", + "link-title": "", + "step-1": "", + "step-2": "", + "step-3": "", + "step-4": "", + "step-5": "", + "title": "" + }, + "is-it-secure": { + "body": "", + "link-title": "", + "title": "" + }, + "migrate-to-this-stack": { + "body": "", + "link-title": "", + "title": "" + }, + "migrated-counts": { + "alert_rule_groups": "", + "alert_rules": "", + "contact_points": "", + "dashboards": "", + "datasources": "", + "folders": "", + "library_elements": "", + "mute_timings": "", + "notification_policies": "", + "notification_templates": "", + "plugins": "" + }, + "migration-token": { + "delete-button": "", + "delete-modal-body": "", + "delete-modal-cancel": "", + "delete-modal-confirm": "", + "delete-modal-deleting": "", + "delete-modal-title": "", + "error-body": "", + "error-title": "", + "generate-button": "", + "generate-button-loading": "", + "modal-close": "", + "modal-copy-and-close": "", + "modal-copy-button": "", + "modal-field-description": "", + "modal-field-label": "", + "modal-title": "", + "status": "" + }, + "onprem": { + "cancel-snapshot-error-title": "", + "create-snapshot-error-title": "", + "disconnect-error-title": "", + "error-see-server-logs": "", + "get-session-error-title": "", + "get-snapshot-error-title": "", + "migration-finished-with-caveat-title": "", + "migration-finished-with-errors-body": "", + "migration-finished-with-warnings-body": "", + "snapshot-error-status-body": "", + "snapshot-error-status-title": "", + "success-message": "", + "success-message-generic": "", + "success-title": "", + "upload-snapshot-error-title": "" + }, + "pdc": { + "body": "", + "link-title": "", + "title": "" + }, + "pricing": { + "body": "", + "link-title": "", + "title": "" + }, + "public-preview": { + "button-text": "", + "message": "", + "message-cloud": "", + "title": "" + }, + "resource-details": { + "dismiss-button": "", + "error-messages": { + "dashboard-already-managed": "", + "datasource-already-managed": "", + "datasource-invalid-url": "", + "datasource-name-conflict": "", + "folder-name-conflict": "", + "generic-error": "", + "internal-service-error": "", + "library-element-name-conflict": "", + "resource-conflict": "", + "unexpected-error": "", + "unsupported-data-type": "" + }, + "error-title": "", + "generic-title": "", + "missing-message": "", + "resource-summary": "", + "title": "", + "warning-title": "" + }, + "resource-status": { + "error-details-button": "", + "failed": "", + "migrated": "", + "migrating": "", + "not-migrated": "", + "unknown": "", + "warning": "", + "warning-details-button": "" + }, + "resource-table": { + "dashboard-load-error": "", + "error-library-element-sub": "", + "error-library-element-title": "", + "unknown-datasource-title": "", + "unknown-datasource-type": "" + }, + "resource-type": { + "alert_rule": "", + "alert_rule_group": "", + "contact_point": "", + "dashboard": "", + "datasource": "", + "folder": "", + "library_element": "", + "mute_timing": "", + "notification_policy": "", + "notification_template": "", + "plugin": "", + "unknown": "" + }, + "summary": { + "cancel-snapshot": "", + "disconnect": "", + "errored-resource-count": "", + "page-loading": "", + "rebuild-snapshot": "", + "snapshot-date": "", + "snapshot-not-created": "", + "start-migration": "", + "successful-resource-count": "", + "target-stack-title": "", + "total-resource-count": "", + "upload-migration": "" + }, + "support-types-disclosure": { + "text": "" + }, + "token-status": { + "active": "", + "no-active": "", + "unknown": "", + "unknown-error": "" + }, + "what-is-cloud": { + "body": "", + "link-title": "", + "title": "" + }, + "why-host": { + "body": "", + "link-title": "", + "title": "" + } + }, + "multicombobox": { + "all": { + "title": "", + "title-filtered": "" + }, + "clear": { + "title": "" + } + }, + "nav": { + "add-new-connections": { + "title": "" + }, + "admin": { + "subtitle": "", + "title": "" + }, + "alert-list-legacy": { + "title": "" + }, + "alerting": { + "subtitle": "", + "title": "" + }, + "alerting-admin": { + "subtitle": "", + "title": "" + }, + "alerting-am-routes": { + "subtitle": "", + "title": "" + }, + "alerting-channels": { + "title": "" + }, + "alerting-groups": { + "subtitle": "", + "title": "" + }, + "alerting-home": { + "title": "" + }, + "alerting-legacy": { + "title": "" + }, + "alerting-list": { + "subtitle": "", + "title": "" + }, + "alerting-receivers": { + "subtitle": "", + "title": "" + }, + "alerting-silences": { + "subtitle": "", + "title": "" + }, + "alerting-upgrade": { + "subtitle": "", + "title": "" + }, + "alerts-and-incidents": { + "subtitle": "", + "title": "" + }, + "api-keys": { + "subtitle": "", + "title": "" + }, + "application": { + "title": "" + }, + "apps": { + "subtitle": "", + "title": "" + }, + "authentication": { + "title": "" + }, + "bookmarks": { + "title": "" + }, + "bookmarks-empty": { + "title": "" + }, + "collector": { + "title": "" + }, + "config": { + "title": "" + }, + "config-access": { + "subtitle": "", + "title": "" + }, + "config-general": { + "subtitle": "", + "title": "" + }, + "config-plugins": { + "subtitle": "", + "title": "" + }, + "connect-data": { + "title": "" + }, + "connections": { + "subtitle": "", + "title": "" + }, + "correlations": { + "subtitle": "", + "title": "" + }, + "create": { + "title": "" + }, + "create-alert": { + "title": "" + }, + "create-dashboard": { + "title": "" + }, + "create-folder": { + "title": "" + }, + "create-import": { + "title": "" + }, + "dashboards": { + "subtitle": "", + "title": "" + }, + "data-sources": { + "subtitle": "", + "title": "" + }, + "databases": { + "title": "" + }, + "datasources": { + "subtitle": "", + "title": "" + }, + "detect": { + "title": "" + }, + "drilldown": { + "title": "" + }, + "explore": { + "title": "" + }, + "frontend": { + "subtitle": "", + "title": "" + }, + "frontend-app": { + "title": "" + }, + "global-orgs": { + "subtitle": "", + "title": "" + }, + "global-users": { + "subtitle": "", + "title": "" + }, + "grafana-quaderno": { + "title": "" + }, + "groupsync": { + "subtitle": "" + }, + "help": { + "title": "" + }, + "help/community": "", + "help/documentation": "", + "help/keyboard-shortcuts": "", + "help/support": "", + "history-container": { + "drawer-tittle": "" + }, + "history-wrapper": { + "collapse": "", + "expand": "", + "icon-selected": "", + "icon-unselected": "", + "show-more": "", + "today": "", + "yesterday": "" + }, + "home": { + "title": "" + }, + "incidents": { + "title": "" + }, + "infrastructure": { + "subtitle": "", + "title": "" + }, + "integrations": { + "title": "" + }, + "k6": { + "title": "" + }, + "kubernetes": { + "title": "" + }, + "library-panels": { + "subtitle": "", + "title": "" + }, + "machine-learning": { + "title": "" + }, + "manage-folder": { + "subtitle": "" + }, + "migrate-to-cloud": { + "subtitle": "", + "title": "" + }, + "monitoring": { + "subtitle": "", + "title": "" + }, + "new": { + "title": "" + }, + "new-dashboard": { + "title": "" + }, + "new-folder": { + "title": "" + }, + "oncall": { + "title": "" + }, + "org-settings": { + "subtitle": "", + "title": "" + }, + "playlists": { + "subtitle": "", + "title": "" + }, + "plugins": { + "subtitle": "", + "title": "" + }, + "private-data-source-connections": { + "subtitle": "", + "title": "" + }, + "profile/notifications": { + "title": "" + }, + "profile/password": { + "title": "" + }, + "profile/settings": { + "title": "" + }, + "profiles": { + "title": "" + }, + "public": { + "title": "" + }, + "recently-deleted": { + "subtitle": "", + "title": "" + }, + "recorded-queries": { + "title": "" + }, + "reporting": { + "title": "" + }, + "scenes": { + "title": "" + }, + "search": { + "placeholderCommandPalette": "" + }, + "search-dashboards": { + "title": "" + }, + "server-settings": { + "subtitle": "", + "title": "" + }, + "service-accounts": { + "subtitle": "", + "title": "" + }, + "setup-guide": { + "title": "" + }, + "shared-dashboard": { + "subtitle": "", + "title": "" + }, + "sign-out": { + "title": "" + }, + "slo": { + "title": "" + }, + "snapshots": { + "subtitle": "", + "title": "" + }, + "starred": { + "title": "" + }, + "starred-empty": { + "title": "" + }, + "statistics-and-licensing": { + "title": "" + }, + "storage": { + "subtitle": "", + "title": "" + }, + "support-bundles": { + "subtitle": "", + "title": "" + }, + "synthetics": { + "title": "" + }, + "teams": { + "subtitle": "", + "title": "" + }, + "testing-and-synthetics": { + "subtitle": "", + "title": "" + }, + "upgrading": { + "title": "" + }, + "users": { + "subtitle": "", + "title": "" + } + }, + "navigation": { + "invite-user": { + "invite-button": "", + "invite-tooltip": "" + }, + "item": { + "add-bookmark": "", + "remove-bookmark": "" + }, + "kiosk": { + "tv-alert": "" + }, + "megamenu": { + "close": "", + "dock": "", + "list-label": "", + "open": "", + "undock": "" + }, + "rss-button": "" + }, + "news": { + "drawer": { + "close": "" + }, + "title": "" + }, + "notifications": { + "empty-state": { + "description": "", + "title": "" + }, + "starred-dashboard": "", + "unstarred-dashboard": "" + }, + "oauth": { + "form": { + "server-discovery-action-button": "", + "server-discovery-modal-close": "", + "server-discovery-modal-loading": "", + "server-discovery-modal-submit": "" + }, + "login": { + "error": "" + } + }, + "panel": { + "header-menu": { + "copy": "", + "create-library-panel": "", + "duplicate": "", + "edit": "", + "explore": "", + "get-help": "", + "hide-legend": "", + "inspect": "", + "inspect-data": "", + "inspect-json": "", + "more": "", + "new-alert-rule": "", + "query": "", + "remove": "", + "replace-library-panel": "", + "share": "", + "show-legend": "", + "unlink-library-panel": "", + "view": "" + } + }, + "panel-search": { + "no-matches": "", + "unsupported-layout": "" + }, + "panel-type-filter": { + "clear-button": "" + }, + "playlist-edit": { + "error-prefix": "", + "form": { + "add-tag-label": "", + "add-tag-placeholder": "", + "add-title-label": "", + "cancel": "", + "heading": "", + "interval-label": "", + "interval-placeholder": "", + "interval-required": "", + "name-label": "", + "name-placeholder": "", + "name-required": "", + "save": "", + "table-delete": "", + "table-drag": "", + "table-empty": "", + "table-heading": "" + }, + "sub-title": "", + "title": "" + }, + "playlist-page": { + "card": { + "delete": "", + "edit": "", + "start": "", + "tooltip": "" + }, + "create-button": { + "title": "" + }, + "delete-modal": { + "body": "", + "confirm-text": "" + }, + "empty": { + "button": "", + "pro-tip": "", + "title": "" + } + }, + "playlists": { + "empty-state": { + "message": "" + } + }, + "plugins": { + "catalog": { + "no-updates-available": "", + "update-all": { + "all-plugins-updated": "", + "available-header": "", + "button": "", + "cloud-update-message": "", + "error": "", + "error-status-text": "", + "header": "", + "installed-header": "", + "modal-confirmation": "", + "modal-dismiss": "", + "modal-in-progress": "", + "modal-title": "", + "name-header": "", + "update-header": "", + "update-status-text": "" + }, + "versions": { + "confirmation-text-1": "", + "confirmation-text-2": "", + "downgrade-confirm": "", + "downgrade-title": "" + } + }, + "details": { + "connections-tab": { + "description": "" + }, + "labels": { + "contactGrafanaLabs": "", + "customLinks": "", + "customLinksTooltip": "", + "dependencies": "", + "documentation": "", + "downloads": "", + "from": "", + "installedVersion": "", + "lastCommitDate": "", + "latestVersion": "", + "license": "", + "raiseAnIssue": "", + "reportAbuse": "", + "reportAbuseTooltip": "", + "repository": "", + "signature": "", + "status": "", + "updatedAt": "" + }, + "modal": { + "cancel": "", + "copyEmail": "", + "description": "", + "node": "", + "title": "" + } + }, + "empty-state": { + "message": "" + }, + "filter": { + "disabled": "", + "sort": "", + "sort-list": "", + "state": "" + }, + "plugin-help": { + "error": "", + "not-found": "" + } + }, + "profile": { + "change-password": { + "cancel-button": "", + "cannot-change-password-message": "", + "change-password-button": "", + "confirm-password-label": "", + "confirm-password-required": "", + "ldap-auth-proxy-message": "", + "new-password-label": "", + "new-password-required": "", + "new-password-same-as-old": "", + "old-password-label": "", + "old-password-required": "", + "passwords-must-match": "", + "strong-password-validation-register": "" + } + }, + "public-dashboard": { + "acknowledgment-checkboxes": { + "ack-title": "", + "data-src-ack-desc": "", + "data-src-ack-tooltip": "", + "public-ack-desc": "", + "public-ack-tooltip": "", + "usage-ack-desc": "", + "usage-ack-desc-tooltip": "" + }, + "config": { + "can-view-dashboard-radio-button-label": "", + "copy-button": "", + "dashboard-url-field-label": "", + "email-share-type-option-label": "", + "pause-sharing-dashboard-label": "", + "public-share-type-option-label": "", + "revoke-public-URL-button": "", + "revoke-public-URL-button-title": "", + "settings-title": "" + }, + "configuration": { + "display-annotations-description": "", + "display-annotations-label": "", + "enable-time-range-description": "", + "enable-time-range-label": "", + "settings-label": "", + "success-pause": "", + "success-resume": "", + "success-update": "", + "success-update-old": "", + "time-range-label": "", + "time-range-tooltip": "" + }, + "create-page": { + "generate-public-url-button": "", + "unsupported-features-desc": "", + "welcome-title": "" + }, + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "email-sharing": { + "accept-button": "", + "alert-text": "", + "bill-ack": "", + "cancel-button": "", + "input-invalid-email-text": "", + "input-required-email-text": "", + "invite-button": "", + "invite-field-desc": "", + "invite-field-label": "", + "learn-more-button": "", + "recipient-email-placeholder": "", + "recipient-invalid-email-text": "", + "recipient-invitation-button": "", + "recipient-invitation-description": "", + "recipient-invitation-tooltip": "", + "recipient-list-description": "", + "recipient-list-title": "", + "recipient-required-email-text": "", + "resend-button": "", + "resend-button-title": "", + "resend-invite-label": "", + "revoke-access-label": "", + "revoke-button": "", + "revoke-button-title": "", + "success-creation": "", + "success-share-type-change": "" + }, + "modal-alerts": { + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "save-dashboard-changes-alert-title": "", + "unsupport-data-source-alert-readmore-link": "", + "unsupported-data-source-alert-desc": "", + "unsupported-data-source-alert-title": "", + "unsupported-template-variable-alert-desc": "", + "unsupported-template-variable-alert-title": "" + }, + "public-sharing": { + "accept-button": "", + "alert-text": "", + "cancel-button": "", + "learn-more-button": "", + "public-ack": "", + "success-creation": "", + "success-share-type-change": "" + }, + "settings-bar-header": { + "collapse-settings-tooltip": "", + "expand-settings-tooltip": "" + }, + "settings-configuration": { + "default-time-range-label": "", + "default-time-range-label-desc": "", + "show-annotations-label": "", + "show-annotations-label-desc": "", + "time-range-picker-label": "", + "time-range-picker-label-desc": "" + }, + "settings-summary": { + "annotations-hide-text": "", + "annotations-show-text": "", + "time-range-picker-disabled-text": "", + "time-range-picker-enabled-text": "", + "time-range-text": "" + }, + "share": { + "success-delete": "", + "success-delete-old": "" + }, + "share-configuration": { + "share-type-label": "" + }, + "share-externally": { + "copy-link-button": "", + "email-share-type-option-description": "", + "email-share-type-option-label": "", + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "pause-access-button": "", + "pause-access-tooltip": "", + "public-share-type-option-description": "", + "public-share-type-option-label": "", + "resume-access-button": "", + "revoke-access-button": "", + "revoke-access-description": "", + "unsupported-data-source-alert-desc": "" + }, + "sharing": { + "success-creation": "" + } + }, + "public-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "public-dashboard-users-access-list": { + "dashboard-modal": { + "external-link": "", + "loading-text": "", + "open-dashboard-list-text": "", + "public-dashboard-link": "", + "public-dashboard-setting": "", + "sharing-setting": "" + }, + "delete-user-modal": { + "delete-user-button-text": "", + "delete-user-cancel-button": "", + "delete-user-revoke-access-button": "", + "revoke-access-title": "", + "revoke-user-access-modal-desc-line1": "", + "revoke-user-access-modal-desc-line2": "" + }, + "delete-user-shared-dashboards-modal": { + "revoke-user-access-modal-desc-line2": "" + }, + "modal": { + "dashboard-modal-title": "", + "shared-dashboard-modal-title": "" + }, + "table-body": { + "dashboard-count_other": "" + }, + "table-header": { + "activated-label": "", + "activated-tooltip": "", + "email-label": "", + "last-active-label": "", + "origin-label": "", + "role-label": "" + } + }, + "query-operation": { + "header": { + "collapse-row": "", + "datasource-help": "", + "drag-and-drop": "", + "duplicate-query": "", + "expand-row": "", + "hide-response": "", + "remove-query": "", + "show-response": "", + "toggle-edit-mode": "" + }, + "query-editor-not-exported": "" + }, + "recently-deleted": { + "buttons": { + "delete": "", + "restore": "" + }, + "page": { + "no-deleted-dashboards": "", + "no-deleted-dashboards-text": "", + "no-search-result": "" + }, + "permanently-delete-modal": { + "confirm-text": "", + "delete-button": "", + "delete-loading": "", + "title": "", + "text_other": "" + }, + "restore-modal": { + "restore-button": "", + "restore-loading": "", + "title": "", + "folder-picker-text_other": "", + "text_other": "" + } + }, + "recentlyDeleted": { + "filter": { + "placeholder": "" + } + }, + "reduce": { + "strictMode": { + "description": "", + "title": "" + } + }, + "refresh-picker": { + "aria-label": { + "choose-interval": "", + "duration-selected": "" + }, + "auto-option": { + "aria-label": "", + "label": "" + }, + "live-option": { + "aria-label": "", + "label": "" + }, + "off-option": { + "aria-label": "", + "label": "" + }, + "tooltip": { + "interval-selected": "", + "turned-off": "" + } + }, + "return-to-previous": { + "button": { + "label": "" + }, + "dismissable-button": "" + }, + "role-picker": { + "built-in": { + "basic-roles": "" + }, + "input": { + "no-roles": "" + }, + "menu": { + "clear-button": "", + "tooltip": "" + }, + "sub-menu": { + "clear-button": "" + }, + "title": { + "description": "" + } + }, + "role-picker-drawer": { + "basic-roles": { + "label": "" + } + }, + "route-error": { + "description": "", + "reload-button": "", + "title": "" + }, + "save-dashboards": { + "message-length": { + "info": "", + "title": "" + }, + "name-exists": { + "message-info": "", + "message-suggestion": "", + "title": "" + } + }, + "scopes": { + "dashboards": { + "collapse": "", + "expand": "", + "loading": "", + "noResultsForFilter": "", + "noResultsForFilterClear": "", + "noResultsForScopes": "", + "noResultsNoScopes": "", + "search": "", + "toggle": { + "collapse": "", + "disabled": "", + "expand": "" + } + }, + "selector": { + "apply": "", + "cancel": "", + "input": { + "placeholder": "", + "removeAll": "" + }, + "title": "" + }, + "tree": { + "collapse": "", + "expand": "", + "headline": { + "noResults": "", + "recommended": "", + "results": "" + }, + "search": "" + } + }, + "search": { + "actions": { + "include-panels": "", + "remove-datasource-filter": "", + "sort-placeholder": "", + "starred": "", + "view-as-folders": "", + "view-as-list": "" + }, + "dashboard-actions": { + "import": "", + "new": "", + "new-dashboard": "", + "new-folder": "" + }, + "results-table": { + "datasource-header": "", + "deleted-less-than-1-min": "", + "deleted-remaining-header": "", + "location-header": "", + "name-header": "", + "tags-header": "", + "type-dashboard": "", + "type-folder": "", + "type-header": "" + }, + "search-input": { + "include-panels-placeholder": "", + "placeholder": "" + } + }, + "select": { + "select-menu": { + "selected-count": "" + } + }, + "service-account-create-page": { + "create": { + "button": "" + }, + "name": { + "label": "", + "required-error": "" + }, + "page-nav": { + "label": "" + }, + "role": { + "label": "" + } + }, + "service-accounts": { + "empty-state": { + "button-title": "", + "message": "", + "more-info": "", + "title": "" + } + }, + "share-dashboard": { + "menu": { + "export-json-title": "", + "share-externally-title": "", + "share-internally-title": "", + "share-snapshot-title": "" + }, + "share-button": "", + "share-button-tooltip": "" + }, + "share-drawer": { + "confirm-action": { + "back-arrow-button": "", + "cancel-button": "" + } + }, + "share-modal": { + "dashboard": { + "title": "" + }, + "embed": { + "copy": "", + "html": "", + "html-description": "", + "info": "", + "time-range": "" + }, + "export": { + "back-button": "", + "cancel-button": "", + "info-text": "", + "loading": "", + "save-button": "", + "share-externally-label": "", + "view-button": "" + }, + "library": { + "info": "" + }, + "link": { + "copy-link-button": "", + "info-text": "", + "link-url": "", + "render-alert": "", + "render-instructions": "", + "rendered-image": "", + "save-alert": "", + "save-dashboard": "", + "shorten-url": "", + "time-range-description": "", + "time-range-label": "" + }, + "panel": { + "title": "" + }, + "snapshot": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "deleted-message": "", + "expire": "", + "expire-day": "", + "expire-hour": "", + "expire-never": "", + "expire-week": "", + "info-text-1": "", + "info-text-2": "", + "local-button": "", + "mistake-message": "", + "name": "", + "timeout": "", + "timeout-description": "", + "url-label": "" + }, + "tab-title": { + "embed": "", + "export": "", + "library-panel": "", + "link": "", + "panel-embed": "", + "public-dashboard": "", + "public-dashboard-title": "", + "snapshot": "" + }, + "theme-picker": { + "current": "", + "dark": "", + "field-name": "", + "light": "" + }, + "view-json": { + "copy-button": "" + } + }, + "share-panel": { + "drawer": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "" + }, + "menu": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "", + "share-snapshot-title": "" + }, + "new-library-panel": { + "cancel-button": "", + "create-button": "" + } + }, + "share-panel-image": { + "preview": { + "title": "" + }, + "settings": { + "height-label": "", + "height-min": "", + "height-placeholder": "", + "height-required": "", + "max-warning": "", + "scale-factor-label": "", + "scale-factor-min": "", + "scale-factor-placeholder": "", + "scale-factor-required": "", + "title": "", + "width-label": "", + "width-min": "", + "width-placeholder": "", + "width-required": "" + } + }, + "share-playlist": { + "checkbox-description": "", + "checkbox-label": "", + "copy-link-button": "", + "link-url-label": "", + "mode": "", + "mode-kiosk": "", + "mode-normal": "", + "title": "" + }, + "shared": { + "preferences": { + "theme": { + "dark-label": "", + "light-label": "", + "system-label": "" + } + } + }, + "shared-dashboard": { + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "fields": { + "timezone-label": "" + } + }, + "shared-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "shared-preferences": { + "fields": { + "home-dashboard-label": "", + "home-dashboard-placeholder": "", + "locale-label": "", + "locale-placeholder": "", + "theme-description": "", + "theme-label": "", + "week-start-label": "" + }, + "theme": { + "default-label": "" + }, + "title": "" + }, + "sign-up": { + "back-button": "", + "submit-button": "", + "verify": { + "back-button": "", + "complete-button": "", + "header": "", + "info": "", + "send-button": "" + } + }, + "silences": { + "empty-state": { + "button-title": "", + "title": "" + }, + "table": { + "add-silence-button": "", + "edit-button": "", + "expired-silences": "", + "no-matching-silences": "", + "noConfig": "", + "recreate-button": "", + "unsilence-button": "" + } + }, + "silences-table": { + "header": { + "alert-name": "", + "state": "" + } + }, + "snapshot": { + "empty-state": { + "message": "", + "more-info": "" + }, + "external-badge": "", + "name-column-header": "", + "share": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "delete-description": "", + "delete-permission-tooltip": "", + "delete-title": "", + "deleted-alert": "", + "expiration-label": "", + "info-alert": "", + "learn-more-button": "", + "local-button": "", + "name-label": "", + "new-snapshot-button": "", + "success-creation": "", + "success-delete": "", + "view-all-button": "" + }, + "share-panel": { + "info-alert": "" + }, + "url-column-header": "", + "view-button": "" + }, + "table": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "" + } + }, + "tag-filter": { + "clear-button": "", + "loading": "", + "no-tags": "", + "placeholder": "" + }, + "teams": { + "empty-state": { + "button-title": "", + "message": "", + "pro-tip": "", + "title": "" + } + }, + "theme-preview": { + "breadcrumbs": { + "dashboards": "", + "home": "" + }, + "panel": { + "form-label": "", + "title": "" + } + }, + "time-picker": { + "absolute": { + "recent-title": "", + "title": "" + }, + "calendar": { + "apply-button": "", + "cancel-button": "", + "close": "", + "next-month": "", + "previous-month": "", + "select-time": "" + }, + "content": { + "empty-recent-list-docs": "", + "empty-recent-list-info": "", + "filter-placeholder": "" + }, + "copy-paste": { + "copy-success-message": "", + "default-error-message": "", + "default-error-title": "", + "tooltip-copy": "", + "tooltip-paste": "" + }, + "footer": { + "change-settings-button": "", + "fiscal-year-option": "", + "fiscal-year-start": "", + "time-zone-option": "", + "time-zone-selection": "" + }, + "range-content": { + "apply-button": "", + "default-error": "", + "fiscal-year": "", + "from-input": "", + "open-input-calendar": "", + "range-error": "", + "to-input": "" + }, + "range-picker": { + "backwards-time-aria-label": "", + "current-time-selected": "", + "forwards-time-aria-label": "", + "to": "", + "zoom-out-button": "", + "zoom-out-tooltip": "" + }, + "time-range": { + "apply": "", + "aria-role": "", + "default-title": "", + "example": "", + "example-details": "", + "example-title": "", + "from-label": "", + "from-to": "", + "more-info": "", + "specify": "", + "submit-button-label": "", + "supported-formats": "", + "to-label": "" + }, + "zone": { + "select-aria-label": "", + "select-search-input": "" + } + }, + "trails": { + "bookmarks": { + "or-view-bookmarks": "" + }, + "card": { + "date-created": "" + }, + "home": { + "learn-more": "", + "lets-start": "", + "start-your-metrics-exploration": "", + "subtitle": "" + }, + "metric-select": { + "filter-by": "", + "native-histogram": "", + "new-badge": "", + "otel-switch": "" + }, + "native-histogram-banner": { + "ch-heatmap": "", + "ch-histogram": "", + "click-histogram": "", + "hide-examples": "", + "learn-more": "", + "metric-examples": "", + "nh-heatmap": "", + "nh-histogram": "", + "now": "", + "previously": "", + "see-examples": "", + "sentence": "" + }, + "recent-metrics": { + "or-view-a-recent-exploration": "" + }, + "settings": { + "always-keep-selected-metric-graph-in-view": "", + "show-previews-of-metric-graphs": "" + } + }, + "transformations": { + "empty": { + "add-transformation-body": "", + "add-transformation-header": "" + } + }, + "upgrade-box": { + "discovery-text": "", + "discovery-text-continued": "", + "get-started": "", + "learn-more": "", + "upgrade-button": "" + }, + "user-orgs": { + "current-org-button": "", + "name-column": "", + "role-column": "", + "select-org-button": "", + "title": "" + }, + "user-profile": { + "fields": { + "email-error": "", + "email-label": "", + "name-error": "", + "name-label": "", + "username-label": "" + }, + "tabs": { + "general": "" + } + }, + "user-session": { + "auth-module-column": "", + "browser-column": "", + "created-at-column": "", + "identity-provider-column": "", + "ip-column": "", + "revoke": "", + "seen-at-column": "" + }, + "user-sessions": { + "loading": "" + }, + "users": { + "empty-state": { + "message": "" + } + }, + "users-access-list": { + "tabs": { + "public-dashboard-users-tab-title": "", + "shared-dashboard-users-tab-title": "" + } + }, + "variable": { + "adhoc": { + "placeholder": "" + }, + "dropdown": { + "placeholder": "" + }, + "picker": { + "link-all": "", + "option-all": "", + "option-selected-values": "", + "option-tooltip": "" + }, + "textbox": { + "placeholder": "" + } + }, + "variables": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + }, + "unknown-table": { + "loading": "", + "no-unknowns": "", + "renamed-or-missing-variables": "", + "variable": "" + } + } +} \ No newline at end of file diff --git a/public/locales/nl-NL/grafana.json b/public/locales/nl-NL/grafana.json new file mode 100644 index 00000000000..f3a7ee625b6 --- /dev/null +++ b/public/locales/nl-NL/grafana.json @@ -0,0 +1,4010 @@ +{ + "_comment": "", + "access-control": { + "add-permission": { + "role-label": "", + "serviceaccount-label": "", + "team-label": "", + "title": "", + "user-label": "" + }, + "add-permissions": { + "save": "" + }, + "permission-list": { + "permission": "" + }, + "permission-list-item": { + "inherited": "" + }, + "permissions": { + "add-label": "", + "no-permissions": "", + "permissions-change-warning": "", + "role": "", + "serviceaccount": "", + "team": "", + "title": "", + "user": "" + } + }, + "action-editor": { + "modal": { + "cancel-button": "", + "save-button": "" + } + }, + "admin": { + "anon-users": { + "not-found": "" + }, + "edit-org": { + "access-denied": "", + "heading": "", + "update-button": "", + "users-heading": "" + }, + "feature-toggles": { + "sub-title": "" + }, + "get-enterprise": { + "contact-us": "", + "description": "", + "features-heading": "", + "included-description": "", + "included-heading": "", + "service-title": "", + "team-sync-details": "", + "title": "" + }, + "ldap": { + "test-mapping-heading": "", + "test-mapping-run-button": "" + }, + "ldap-permissions": { + "active": "", + "admin": "", + "inactive": "" + }, + "ldap-status": { + "title": "" + }, + "ldap-sync": { + "debug-button": "", + "external-sync-description": "", + "external-sync-label": "", + "next-sync-label": "", + "not-enabled": "", + "sync-button": "", + "title": "" + }, + "ldap-sync-info": { + "title": "" + }, + "ldap-user-groups": { + "no-org-found": "" + }, + "ldap-user-info": { + "no-team": "" + }, + "org-uers": { + "last-seen-never": "" + }, + "org-users": { + "not-editable": "" + }, + "orgs": { + "delete-body": "", + "id-header": "", + "name-header": "", + "new-org-button": "" + }, + "server-settings": { + "alerts-button": "", + "dashboards-button": "", + "data-sources-button": "", + "not-found": "", + "title": "", + "users-button": "" + }, + "settings": { + "info-description": "" + }, + "upgrade-info": { + "title": "" + }, + "user-orgs": { + "add-button": "", + "change-role-button": "", + "external-user-tooltip": "", + "remove-button": "", + "role-not-editable": "", + "title": "" + }, + "user-orgs-modal": { + "add-button": "", + "cancel-button": "" + }, + "user-permissions": { + "change-button": "", + "grafana-admin-key": "", + "grafana-admin-no": "", + "grafana-admin-yes": "", + "title": "" + }, + "user-profile": { + "delete-button": "", + "disable-button": "", + "edit-button": "", + "enable-button": "", + "title": "" + }, + "user-sessions": { + "browser-column": "", + "force-logout-all-button": "", + "force-logout-button": "", + "ip-column": "", + "last-seen-column": "", + "logged-on-column": "", + "title": "" + }, + "users-create": { + "create-button": "" + }, + "users-list": { + "create-button": "" + }, + "users-table": { + "last-seen-never": "", + "no-licensed-roles": "" + } + }, + "alert-labels": { + "button": { + "hide": "", + "show": { + "tooltip": "" + } + } + }, + "alerting": { + "alert": { + "alert-state": "", + "annotations": "", + "evaluation": "", + "evaluation-paused": "", + "evaluation-paused-description": "", + "last-evaluated": "", + "last-evaluation-duration": "", + "last-updated-at": "", + "last-updated-by": "", + "no-annotations": "", + "pending-period": "", + "rule": "", + "rule-identifier": "", + "rule-type": "", + "state-error-timeout": "", + "state-no-data": "", + "target-datasource-uid": "" + }, + "alert-recording-rule-form": { + "evaluation-behaviour": { + "description": { + "text": "" + } + } + }, + "alert-rules": { + "firing-for": "", + "next-evaluation": "", + "next-evaluation-in": "", + "rule-definition": "" + }, + "alertform": { + "labels": { + "alerting": "", + "recording": "" + } + }, + "alertVersionHistory": { + "alerting": "", + "alerting-change-description": "", + "annotations": "", + "compare": "", + "compare-with-latest": "", + "compareVersions": "", + "comparing-versions": "", + "condition": "", + "contactPointRouting": "", + "description": "", + "errorloading": "", + "execErrorState": "", + "intervalSeconds": "", + "labels": "", + "latest": "", + "name": "", + "namespace_uid": "", + "noDataState": "", + "noVersionsFound": "", + "paused": "", + "pendingPeriod": "", + "provisioning": "", + "provisioning-change-description": "", + "queryAndAlertCondition": "", + "restore": "", + "restore-manually": "", + "restore-modal": { + "body": "", + "confirm": "", + "error": "", + "summary": "", + "title": "" + }, + "restore-version": "", + "rule_group": "", + "unknown": "", + "unknown-change-description": "", + "user-id": "", + "warning-restore-manually": "", + "warning-restore-manually-title": "" + }, + "annotations": { + "description": "", + "title": "" + }, + "central-alert-history": { + "details": { + "error": "", + "header": { + "alert-rule": "", + "instance": "", + "state": "", + "timestamp": "" + }, + "loading": "", + "no-recognized-state": "", + "no-values": "", + "not-found": "", + "number-transitions": "", + "state": { + "alerting": "", + "error": "", + "no-data": "", + "normal": "", + "pending": "" + }, + "state-transitions": "", + "unknown-event-state": "", + "unknown-rule": "", + "value-in-transition": "" + }, + "error": "", + "filter": { + "clear": "", + "info": { + "label1": "", + "label2": "", + "label3": "", + "label4": "" + } + }, + "filterBy": "", + "too-many-events": { + "text": "", + "title": "" + } + }, + "common": { + "cancel": "", + "clear-filters": "", + "delete": "", + "edit": "", + "export": "", + "export-all": "", + "loading": "", + "search-by-matchers": "", + "titles": { + "notification-templates": "" + }, + "view": "" + }, + "contact-points": { + "create": "", + "custom-template-value": "", + "delete-reasons": { + "heading": "", + "no-permissions": "", + "policies": "", + "provisioned": "", + "rules": "" + }, + "delivered-to": "", + "delivery-duration": "", + "empty-state": { + "title": "" + }, + "key-value-map": { + "add": "", + "confirm-add": "" + }, + "last-delivery-attempt": "", + "last-delivery-failed": "", + "no-contact-points-found": "", + "no-delivery-attempts": "", + "no-integrations": "", + "only-firing": "", + "receiver-summary": { + "jira": "" + }, + "telegram": { + "parse-mode-warning-body": "", + "parse-mode-warning-title": "" + }, + "used-by_one": "", + "used-by_other": "", + "used-by-rules_one": "", + "used-by-rules_other": "" + }, + "contactPointFilter": { + "label": "" + }, + "copy-to-clipboard": "", + "dag": { + "missing-reference": "", + "self-reference": "" + }, + "export": { + "subtitle": { + "formats": "", + "one-format": "" + } + }, + "folderAndGroup": { + "evaluation": { + "modal": { + "text": { + "alerting": "", + "recording": "" + } + } + } + }, + "group-actions": { + "actions-trigger": "", + "delete": "", + "edit": "", + "export": "", + "reorder": "" + }, + "list-view": { + "empty": { + "new-alert-rule": "", + "new-recording-rule": "", + "provisioning": "" + }, + "section": { + "dataSourceManaged": { + "title": "" + }, + "grafanaManaged": { + "export-new-rule": "", + "export-rules": "", + "loading": "", + "new-recording-rule": "", + "title": "" + } + } + }, + "manage-permissions": { + "button": "", + "title": "" + }, + "mute_timings": { + "error-loading": { + "description": "", + "title": "" + } + }, + "mute-timings": { + "add-mute-timing": "", + "description": "", + "save": "", + "saving": "" + }, + "notification-preview": { + "alertmanager": "", + "error": "", + "initialized": "", + "preview-routing": "", + "title": "", + "uninitialized": "" + }, + "notification-templates": { + "duplicate": { + "subTitle": "", + "title": "" + }, + "edit": { + "subTitle": "", + "title": "" + }, + "new": { + "subTitle": "", + "title": "" + } + }, + "policies": { + "default-policy": { + "description": "", + "title": "", + "update": "" + }, + "delete": { + "confirm": "", + "warning-1": "", + "warning-2": "" + }, + "filter-description": "", + "generated-policies": "", + "matchers": "", + "metadata": { + "active-time": "", + "delivered-to": "", + "grouped-by": "", + "grouping": { + "none": "", + "single-group": "" + }, + "inherited": "", + "mute-time": "", + "timingOptions": { + "groupInterval": { + "description": "", + "label": "" + }, + "groupWait": { + "description": "", + "label": "" + }, + "repeatInterval": { + "description": "", + "label": "" + } + }, + "n-instances_one": "", + "n-instances_other": "" + }, + "new-child": "", + "new-policy": "", + "no-matchers": "", + "reload-policies": "", + "save-policy": "", + "update": { + "please-wait": "", + "update-policy": "", + "updating": "" + }, + "update-errors": { + "conflict": "", + "error-code": "", + "fallback": "", + "suffix": "", + "title": "" + }, + "n-more-policies_one": "", + "n-more-policies_other": "" + }, + "provisioning": { + "badge-tooltip-provenance": "", + "badge-tooltip-standard": "" + }, + "queryAndExpressionsStep": { + "disableAdvancedOptions": { + "text": "" + }, + "preview": "", + "previewCondition": "" + }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, + "rule-form": { + "evaluation": { + "evaluation-group-and-interval": "", + "group": { + "cancel": "", + "create": "", + "interval": "" + }, + "group-name": "", + "group-text": "", + "new-group": "", + "pause": { + "alerting": "", + "recording": "" + }, + "select-folder-before": "" + }, + "evaluation-behaviour": { + "description": { + "text": "" + }, + "info-help": { + "text": "" + }, + "pending-period": "" + }, + "evaluation-behaviour-description1": "", + "evaluation-behaviour-description2": "", + "evaluation-behaviour-description3": "", + "evaluation-behaviour-for": { + "error-parsing": "", + "validation": "" + }, + "folder": { + "cancel": "", + "create": "", + "create-folder": "", + "creating-new-folder": "", + "label": "", + "name": "", + "new-folder": "", + "new-folder-or": "" + }, + "folder-and-labels": "", + "folders": { + "help-info": "" + }, + "labels": { + "help-info": "" + }, + "pause": { + "label": "" + }, + "threshold": { + "recovery": { + "stop-alerting-above": "", + "stop-alerting-bellow": "", + "stop-alerting-equal": "", + "stop-alerting-inside-range": "", + "stop-alerting-less": "", + "stop-alerting-more": "", + "stop-alerting-not-equal": "", + "stop-alerting-outside-range": "", + "title": "" + } + } + }, + "rule-groups": { + "delete": { + "success": "" + }, + "move": { + "success": "" + }, + "rename": { + "success": "" + }, + "update": { + "success": "" + } + }, + "rule-list": { + "configure-datasource": "", + "ds-error-boundary": { + "description": "", + "title": "" + }, + "filter-view": { + "no-more-results": "", + "no-rules-found": "" + }, + "new-alert-rule": "", + "pagination": { + "next-page": "", + "previous-page": "" + }, + "return-button": { + "title": "" + }, + "rulerrule-loading-error": "" + }, + "rule-state": { + "creating": "", + "deleting": "", + "paused": "", + "recording-rule": "" + }, + "rule-view": { + "query": { + "datasources-na": { + "description": "", + "title": "" + } + } + }, + "rule-viewer": { + "error-loading": "", + "prometheus-consistency-check": { + "alert-message": "", + "alert-title": "" + } + }, + "rules": { + "add-rule": { + "success": "" + }, + "delete-rule": { + "success": "" + }, + "pause-rule": { + "success": "" + }, + "resume-rule": { + "success": "" + }, + "update-rule": { + "success": "" + } + }, + "search": { + "property": { + "data-source": "", + "evaluation-group": "", + "labels": "", + "namespace": "", + "rule-health": "", + "rule-name": "", + "rule-type": "", + "state": "" + }, + "save-query": "" + }, + "silences": { + "affected-instances": "", + "only-firing-instances": "", + "preview-affected-instances": "" + }, + "simpleCondition": { + "alertCondition": "" + }, + "templates": { + "editor": { + "add-example": "", + "auto-complete": "", + "goto-docs": "" + }, + "help": { + "intro": "" + }, + "misconfigured-badge-text": "", + "misconfigured-warning": "", + "misconfigured-warning-details": "" + }, + "threshold": { + "to": "" + } + }, + "annotations": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + } + }, + "api-keys": { + "empty-state": { + "message": "" + } + }, + "app-chrome": { + "skip-content-button": "", + "top-bar": { + "sign-in": "" + } + }, + "app-notification": { + "item": { + "trace-id": "" + } + }, + "bookmarks-page": { + "empty": { + "message": "", + "tip": "" + } + }, + "bouncing-loader": { + "label": "" + }, + "browse-dashboards": { + "action": { + "cancel-button": "", + "cannot-move-folders": "", + "confirmation-text": "", + "delete-button": "", + "delete-modal-invalid-text": "", + "delete-modal-invalid-title": "", + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "delete-modal-title": "", + "deleting": "", + "manage-permissions-button": "", + "move-button": "", + "move-modal-alert": "", + "move-modal-field-label": "", + "move-modal-text": "", + "move-modal-title": "", + "moving": "", + "new-folder-name-required-phrase": "" + }, + "actions": { + "button-to-recently-deleted": "" + }, + "counts": { + "alertRule_one": "", + "alertRule_other": "", + "dashboard_one": "", + "dashboard_other": "", + "folder_one": "", + "folder_other": "", + "libraryPanel_one": "", + "libraryPanel_other": "", + "total_one": "", + "total_other": "" + }, + "dashboards-tree": { + "collapse-folder-button": "", + "expand-folder-button": "", + "name-column": "", + "select-all-header-checkbox": "", + "select-checkbox": "", + "tags-column": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "", + "title-folder": "" + }, + "folder-actions-button": { + "delete": "", + "folder-actions": "", + "manage-permissions": "", + "move": "" + }, + "folder-picker": { + "accessible-label": "", + "button-label": "", + "clear-selection": "", + "empty-message": "", + "error-title": "", + "non-folder-item": "", + "search-placeholder": "", + "unknown-error": "" + }, + "hard-delete": { + "success": "" + }, + "manage-folder-nav": { + "alert-rules": "", + "dashboards": "", + "panels": "" + }, + "new-folder-form": { + "cancel-label": "", + "create-label": "", + "name-label": "" + }, + "no-results": { + "clear": "", + "text": "" + }, + "soft-delete": { + "success": "" + } + }, + "clipboard-button": { + "inline-toast": { + "success": "" + } + }, + "combobox": { + "async": { + "error": "" + }, + "clear": { + "title": "" + }, + "custom-value": { + "description": "" + }, + "group": { + "undefined": "" + }, + "options": { + "no-found": "" + } + }, + "command-palette": { + "action": { + "change-theme": "", + "dark-theme": "", + "light-theme": "" + }, + "empty-state": { + "message": "" + }, + "search-box": { + "placeholder": "" + }, + "section": { + "actions": "", + "dashboard-search-results": "", + "folder-search-results": "", + "pages": "", + "preferences": "", + "recent-dashboards": "" + } + }, + "common": { + "apply": "", + "cancel": "", + "clear": "", + "close": "", + "collapse": "", + "edit": "", + "help": "", + "loading": "", + "locale": { + "default": "" + }, + "save": "", + "search": "", + "view": "" + }, + "configuration-tracker": { + "config-card": { + "complete": "" + } + }, + "connections": { + "connect-data": { + "category-header-label": "", + "empty-message": "", + "request-data-source": "", + "roadmap": "" + }, + "search": { + "placeholder": "" + } + }, + "core": { + "versionHistory": { + "comparison": { + "header": { + "hide-json-diff": "", + "show-json-diff": "", + "text": "" + }, + "select": "" + }, + "no-properties-changed": "", + "table": { + "updated": "", + "updatedBy": "", + "version": "" + }, + "view-json-diff": "" + } + }, + "correlations": { + "add-new": "", + "alert": { + "error-message": "", + "title": "" + }, + "basic-info-form": { + "description-description": "", + "description-label": "", + "label-description": "", + "label-label": "", + "label-placeholder": "", + "label-required": "", + "sub-text": "", + "title": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + }, + "list": { + "delete": "", + "label": "", + "loading": "", + "read-only": "", + "source": "", + "target": "" + }, + "navigation-form": { + "add-button": "", + "back-button": "", + "next-button": "", + "save-button": "" + }, + "page-content": "", + "page-heading": "", + "query-editor": { + "control-rules": "", + "data-source-text": "", + "data-source-title": "", + "error-text": "", + "error-title": "", + "loading": "", + "query-description": "", + "query-editor-title": "", + "query-label": "" + }, + "source-form": { + "control-required": "", + "description": "", + "description-external-pre": "", + "description-query-pre": "", + "external-title": "", + "heading-external": "", + "heading-query": "", + "query-title": "", + "results-description": "", + "results-label": "", + "results-required": "", + "source-description": "", + "source-label": "", + "sub-text": "" + }, + "sub-title": "", + "target-form": { + "control-rules": "", + "sub-text": "", + "target-description-external": "", + "target-description-query": "", + "target-label": "", + "target-type-description": "", + "title": "", + "type-label": "" + }, + "trans-details": { + "logfmt-description": "", + "logfmt-label": "", + "regex-description": "", + "regex-expression": "", + "regex-label": "", + "regex-map-values": "" + }, + "transform": { + "add-button": "", + "heading": "", + "no-transform": "" + }, + "transform-row": { + "expression-label": "", + "expression-required": "", + "expression-tooltip": "", + "field-input": "", + "field-label": "", + "field-tooltip": "", + "map-value-label": "", + "map-value-tooltip": "", + "remove-button": "", + "remove-tooltip": "", + "transform-required": "", + "type-label": "", + "type-tooltip": "" + } + }, + "dashboard": { + "add-menu": { + "import": "", + "paste-panel": "", + "row": "", + "visualization": "" + }, + "alert-rules-drawer": { + "redirect-link": "", + "subtitle": "" + }, + "default-layout": { + "description": "", + "item-options": { + "repeat": { + "direction": { + "horizontal": "", + "title": "", + "vertical": "" + }, + "max": "", + "title": "", + "variable": { + "description": "", + "title": "" + } + } + }, + "name": "", + "row-actions": { + "delete": "", + "modal": { + "alt-action": "", + "text": "", + "title": "" + } + }, + "row-options": { + "button": { + "label": "" + }, + "form": { + "cancel": "", + "repeat-for": { + "label": "", + "learn-more": "", + "warning": { + "text": "" + } + }, + "title": "", + "update": "" + }, + "modal": { + "title": "" + }, + "repeat": { + "title": "", + "variable": { + "title": "" + } + }, + "title": "" + } + }, + "edit-pane": { + "elements": { + "dashboard": "", + "objects": "", + "panel": "", + "panels": "", + "row": "", + "rows": "", + "tab": "", + "tabs": "" + }, + "open": "", + "row": { + "header": { + "hide": "", + "title": "" + } + } + }, + "editpane": { + "add": "", + "configure": "", + "outline": "" + }, + "empty": { + "add-library-panel-body": "", + "add-library-panel-button": "", + "add-library-panel-header": "", + "add-visualization-body": "", + "add-visualization-button": "", + "add-visualization-header": "", + "import-a-dashboard-body": "", + "import-a-dashboard-header": "", + "import-dashboard-button": "" + }, + "errors": { + "failed-to-load": "" + }, + "inspect": { + "data-tab": "", + "error-tab": "", + "json-tab": "", + "meta-tab": "", + "query-tab": "", + "stats-tab": "", + "subtitle": "", + "title": "" + }, + "inspect-data": { + "data-options": "", + "dataframe-aria-label": "", + "dataframe-label": "", + "download-csv": "", + "download-excel-description": "", + "download-excel-label": "", + "download-logs": "", + "download-service": "", + "download-traces": "", + "excel-header": "", + "formatted": "", + "formatted-data-description": "", + "formatted-data-label": "", + "panel-transforms": "", + "series-to-columns": "", + "transformation": "", + "transformations-description": "", + "transformations-label": "" + }, + "inspect-json": { + "dataframe-description": "", + "dataframe-label": "", + "panel-data-description": "", + "panel-data-label": "", + "panel-json-description": "", + "panel-json-label": "", + "select-source": "", + "unknown": "" + }, + "inspect-meta": { + "no-inspector": "" + }, + "inspect-stats": { + "data-title": "", + "data-traceids": "", + "processing-time": "", + "queries": "", + "request-time": "", + "rows": "", + "table-title": "" + }, + "layout": { + "common": { + "copy": "", + "copy-or-duplicate": "", + "delete": "", + "duplicate": "", + "layout": "" + } + }, + "options": { + "description": "", + "title-option": "" + }, + "outline": { + "tree": { + "item": { + "collapse": "", + "empty": "", + "expand": "" + } + } + }, + "panel-edit": { + "alerting-tab": { + "dashboard-not-saved": "", + "no-rules": "" + } + }, + "responsive-layout": { + "description": "", + "item-options": { + "hide-no-data": "", + "repeat": { + "variable": { + "description": "", + "title": "" + } + }, + "title": "" + }, + "name": "", + "options": { + "columns": "", + "fixed": "", + "min": "", + "one-column": "", + "rows": "", + "three-columns": "", + "two-columns": "" + } + }, + "rows-layout": { + "description": "", + "name": "", + "option": { + "height": "", + "hide-header": "", + "repeat": "", + "title": "" + }, + "options": { + "height-expand": "", + "height-min": "" + }, + "row": { + "collapse": "", + "expand": "", + "menu": { + "add": "", + "add-panel": "", + "add-row-above": "", + "add-row-below": "", + "move-down": "", + "move-row": "", + "move-up": "" + }, + "new": "", + "repeat": { + "learn-more": "", + "warning": "" + } + }, + "row-options": { + "title-option": "" + } + }, + "tabs-layout": { + "description": "", + "menu": { + "move-tab": "" + }, + "name": "", + "tab": { + "menu": { + "add": "", + "add-panel": "", + "add-tab-above": "", + "add-tab-after": "", + "add-tab-before": "", + "move-left": "", + "move-right": "" + }, + "new": "" + }, + "tab-options": { + "title-option": "" + } + }, + "toolbar": { + "add": "", + "add-panel": "", + "add-panel-description": "", + "add-panel-lib": "", + "add-row": "", + "add-tab": "", + "alert-rules": "", + "back-to-dashboard": "", + "dashboard-settings": { + "label": "", + "tooltip": "" + }, + "discard-library-panel-changes": "", + "discard-panel": "", + "discard-panel-new": "", + "edit": { + "label": "", + "tooltip": "" + }, + "edit-dashboard-v2-schema": "", + "enter-edit-mode": { + "label": "", + "tooltip": "" + }, + "exit-edit-mode": { + "label": "", + "tooltip": "" + }, + "libray-panel-description": "", + "mark-favorite": "", + "more-save-options": "", + "open-original": "", + "playlist-next": "", + "playlist-previous": "", + "playlist-stop": "", + "public-dashboard": "", + "refresh": "", + "row-description": "", + "save": "", + "save-dashboard": { + "label": "", + "tooltip": "" + }, + "save-dashboard-copy": { + "label": "", + "tooltip": "" + }, + "save-dashboard-short": "", + "save-library-panel": "", + "settings": "", + "share": { + "label": "", + "tooltip": "" + }, + "share-button": "", + "show-hidden-elements": "", + "switch-old-dashboard": "", + "tabs-description": "", + "unlink-library-panel": "", + "unmark-favorite": "" + }, + "validation": { + "invalid-dashboard-id": "", + "invalid-json": "", + "tags-expected-array": "", + "tags-expected-strings": "" + }, + "viz-panel": { + "options": { + "description": "", + "open-edit": "", + "plugin-type-image": "", + "title-option": "", + "transparent-background": "" + } + } + }, + "dashboard-import": { + "file-dropzone": { + "primary-text": "", + "secondary-text": "" + }, + "form-actions": { + "cancel": "", + "load": "" + }, + "gcom-field": { + "label": "", + "load-button": "", + "placeholder": "", + "validation-required": "" + }, + "json-field": { + "label": "", + "validation-required": "" + } + }, + "dashboard-links": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "title": "" + } + }, + "dashboard-settings": { + "annotations": { + "title": "" + }, + "dashboard-delete-button": "", + "delete-modal": { + "confirmation-text": "", + "delete-button": "", + "title": "" + }, + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "general": { + "auto-refresh-description": "", + "auto-refresh-label": "", + "description-label": "", + "editable-description": "", + "editable-label": "", + "folder-label": "", + "panel-options-graph-tooltip-description": "", + "panel-options-graph-tooltip-label": "", + "panel-options-label": "", + "panels-preload-description": "", + "panels-preload-label": "", + "tags-label": "", + "title": "", + "title-label": "" + }, + "json-editor": { + "save-button": "", + "subtitle": "", + "title": "" + }, + "links": { + "title": "" + }, + "permissions": { + "title": "" + }, + "provisioned-delete-modal": { + "confirm-button": "", + "text-1": "", + "text-2": "", + "text-3": "", + "text-link": "", + "title": "" + }, + "settings": { + "title": "" + }, + "time-picker": { + "hide-time-picker": "", + "now-delay-description": "", + "now-delay-label": "", + "refresh-live-dashboards-description": "", + "refresh-live-dashboards-label": "", + "time-options-label": "", + "time-zone-label": "", + "week-start-label": "" + }, + "time-regions": { + "advanced-description-cron": "", + "advanced-description-rest": "", + "advanced-description-use": "", + "advanced-label": "" + }, + "variables": { + "title": "" + }, + "versions": { + "title": "" + } + }, + "dashboards": { + "panel-edit": { + "angular-deprecation-button-open-panel-json": "", + "angular-deprecation-description": "", + "angular-deprecation-heading": "" + }, + "panel-queries": { + "add-query-from-library": "" + }, + "settings": { + "variables": { + "dependencies": { + "button": "", + "title": "" + } + } + } + }, + "data-source-list": { + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + } + }, + "data-source-picker": { + "add-new-data-source": "", + "built-in-list": { + "description-dashboard": "", + "description-grafana": "", + "description-mixed": "" + }, + "list": { + "no-data-source-message": "" + }, + "modal": { + "configure-new-data-source": "", + "input-placeholder": "", + "title": "" + }, + "open-advanced-button": "" + }, + "data-source-testing-status-page": { + "error-more-details-link": "", + "success-more-details-links": "" + }, + "data-sources": { + "datasource-add-button": { + "label": "" + }, + "empty-state": { + "message": "" + } + }, + "embed": { + "share": { + "time-range-description": "", + "time-range-label": "" + } + }, + "empty-list-cta": { + "pro-tip": "" + }, + "entity-not-found": { + "description": "" + }, + "errors": { + "dashboard-settings": { + "annotations": { + "datasource": "" + } + } + }, + "explore": { + "add-to-dashboard": "", + "drilldownInfo": { + "action": "", + "description": "", + "title": "" + }, + "logs": { + "logs-volume": { + "add-filters": "", + "decrease-timerange": "", + "much-data": "" + }, + "maximum-pinned-logs": "", + "no-logs-found": "", + "scan-for-older-logs": "", + "stop-scan": "" + }, + "rich-history": { + "close-tooltip": "", + "datasource-a-z": "", + "datasource-z-a": "", + "newest-first": "", + "oldest-first": "", + "query-history": "", + "query-library": "", + "settings": "", + "starred": "" + }, + "rich-history-card": { + "add-comment-form": "", + "add-comment-tooltip": "", + "add-to-library": "", + "cancel": "", + "confirm-delete": "", + "copy-query-tooltip": "", + "copy-shortened-link-tooltip": "", + "datasource-icon-label": "", + "datasource-name-label": "", + "datasource-not-exist": "", + "delete-query-confirmation-title": "", + "delete-query-title": "", + "delete-query-tooltip": "", + "delete-starred-query-confirmation-text": "", + "edit-comment-tooltip": "", + "optional-description": "", + "query-comment-label": "", + "query-text-label": "", + "save-comment": "", + "star-query-tooltip": "", + "unstar-query-tooltip": "", + "update-comment-form": "" + }, + "rich-history-container": { + "loading": "" + }, + "rich-history-notification": { + "query-copied": "", + "query-deleted": "" + }, + "rich-history-queries-tab": { + "displaying-partial-queries": "", + "displaying-queries": "", + "filter-aria-label": "", + "filter-history": "", + "filter-placeholder": "", + "history-local": "", + "loading": "", + "loading-results": "", + "search-placeholder": "", + "showing-queries": "", + "sort-aria-label": "", + "sort-placeholder": "" + }, + "rich-history-settings-tab": { + "alert-info": "", + "change-default-tab": "", + "clear-history-info": "", + "clear-query-history": "", + "clear-query-history-button": "", + "delete-confirm": "", + "delete-confirm-text": "", + "delete-title": "", + "history-time-span": "", + "history-time-span-description": "", + "only-show-active-datasource": "", + "query-history-deleted": "", + "retention-period": { + "1-week": "", + "2-days": "", + "2-weeks": "", + "5-days": "" + } + }, + "rich-history-starred-tab": { + "filter-queries-aria-label": "", + "filter-queries-placeholder": "", + "loading": "", + "loading-results": "", + "local-history-message": "", + "search-queries-placeholder": "", + "showing-queries": "", + "sort-queries-aria-label": "", + "sort-queries-placeholder": "" + }, + "rich-history-utils": { + "a-week-ago": "", + "days-ago": "", + "default-from": "", + "default-to": "", + "today": "", + "two-weeks-ago": "", + "yesterday": "" + }, + "rich-history-utils-notification": { + "saving-failed": "", + "update-failed": "" + }, + "run-query": { + "left-pane": "", + "right-pane": "", + "run-query-button": "", + "switch-datasource-button": "" + }, + "secondary-actions": { + "add-from-query-library": "", + "query-add-button": "", + "query-add-button-aria-label": "", + "query-history-button": "", + "query-history-button-aria-label": "", + "query-inspector-button": "", + "query-inspector-button-aria-label": "" + }, + "table": { + "no-data": "", + "title": "", + "title-with-name": "" + }, + "toolbar": { + "add-to-extensions": "", + "add-to-queryless-extensions": "", + "aria-label": "", + "copy-link": "", + "copy-link-abs-time": "", + "copy-links-absolute-category": "", + "copy-links-normal-category": "", + "copy-shortened-link": "", + "copy-shortened-link-abs-time": "", + "copy-shortened-link-label": "", + "copy-shortened-link-menu": "", + "refresh-picker-cancel": "", + "refresh-picker-run": "", + "split-close": "", + "split-close-tooltip": "", + "split-narrow": "", + "split-title": "", + "split-tooltip": "", + "split-widen": "" + } + }, + "explore-metrics": { + "breakdown": { + "clearFilter": "", + "labelSelect": "", + "missing-otel-labels": "", + "noMatchingValue": "", + "sortBy": "" + }, + "related-logs": { + "LrrDocsLink": "", + "openExploreLogs": "", + "relatedLogsUnavailable": "", + "warnExperimentalFeature": "" + }, + "viewBy": "" + }, + "export": { + "json": { + "cancel-button": "", + "copy-button": "", + "download-button": "", + "download-successful_toast_message": "", + "export-externally-label": "", + "info-text": "", + "title": "" + }, + "menu": { + "export-as-json-label": "", + "export-as-json-tooltip": "" + } + }, + "folder-filter": { + "clear-folder-button": "" + }, + "folder-picker": { + "create-instructions": "", + "loading": "" + }, + "forgot-password": { + "back-button": "", + "change-password": { + "skip-button": "", + "submit-button": "" + }, + "contact-admin": "", + "email-sent": "", + "reset-password-header": "", + "send-email-button": "" + }, + "form-prompt": { + "continue-button": "", + "description": "", + "discard-button": "" + }, + "gen-ai": { + "apply-suggestion": "", + "incomplete-request-error": "", + "send-custom-feedback": "" + }, + "get-enterprise": { + "requires-license": "", + "title": "" + }, + "grafana-ui": { + "action-editor": { + "button": { + "confirm": "", + "confirm-action": "" + }, + "inline": { + "add-action": "", + "edit-action": "" + }, + "modal": { + "action-body": "", + "action-method": "", + "action-query-params": "", + "action-title": "", + "action-title-placeholder": "", + "one-click-description": "" + } + }, + "alert": { + "close-button": "" + }, + "auto-save-field": { + "saved": "", + "saving": "" + }, + "card": { + "option": "" + }, + "cascader": { + "clear-button": "" + }, + "color-picker-popover": { + "palette-tab": "", + "spectrum-tab": "" + }, + "confirm-button": { + "cancel": "" + }, + "confirm-content": { + "placeholder": "" + }, + "data-link-editor": { + "info": "", + "new-tab-label": "", + "title-label": "", + "title-placeholder": "", + "url-label": "" + }, + "data-link-editor-modal": { + "cancel": "", + "one-click-description": "", + "save": "" + }, + "data-link-inline-editor": { + "one-click": "" + }, + "data-links-inline-editor": { + "add-link": "", + "edit-link": "", + "one-click": "", + "one-click-enabled": "", + "title-not-provided": "", + "tooltip-edit": "", + "tooltip-remove": "", + "url-not-provided": "" + }, + "data-source-basic-auth-settings": { + "user-label": "", + "user-placeholder": "" + }, + "data-source-http-proxy-settings": { + "oauth-identity-label": "", + "oauth-identity-tooltip": "", + "skip-tls-verify-label": "", + "ts-client-auth-label": "", + "with-ca-cert-label": "", + "with-ca-cert-tooltip": "" + }, + "data-source-http-settings": { + "access-help": "", + "access-help-details": "", + "access-label": "", + "access-options-browser": "", + "access-options-proxy": "", + "allowed-cookies": "", + "allowed-cookies-tooltip": "", + "auth": "", + "azure-auth-label": "", + "azure-auth-tooltip": "", + "basic-auth": "", + "basic-auth-label": "", + "browser-mode-description": "", + "browser-mode-title": "", + "default-url-access-select": "", + "default-url-tooltip": "", + "direct-url-tooltip": "", + "heading": "", + "proxy-url-tooltip": "", + "server-mode-description": "", + "server-mode-title": "", + "timeout-form-label": "", + "timeout-label": "", + "timeout-tooltip": "", + "url-label": "", + "with-credential-label": "", + "with-credential-tooltip": "" + }, + "data-source-settings": { + "alerting-settings-heading": "", + "alerting-settings-label": "", + "alerting-settings-tooltip": "", + "cert-key-reset": "", + "custom-headers-add": "", + "custom-headers-header": "", + "custom-headers-header-placeholder": "", + "custom-headers-header-remove": "", + "custom-headers-header-value": "", + "custom-headers-title": "", + "secure-socks-heading": "", + "secure-socks-label": "", + "secure-socks-tooltip": "", + "tls-certification-label": "", + "tls-certification-placeholder": "", + "tls-client-certification-label": "", + "tls-client-key-label": "", + "tls-client-key-placeholder": "", + "tls-heading": "", + "tls-server-name-label": "", + "tls-tooltip": "" + }, + "date-time-picker": { + "apply": "", + "calendar-icon-label": "", + "cancel": "", + "next-label": "", + "previous-label": "", + "select-placeholder": "" + }, + "drawer": { + "close": "" + }, + "feature-badge": { + "experimental": "", + "new": "", + "preview": "", + "private-preview": "" + }, + "field-link-list": { + "external-links-heading": "" + }, + "file-dropzone": { + "cancel-upload": "", + "file-too-large": "" + }, + "filter-input": { + "clear": "" + }, + "modal": { + "close-tooltip": "" + }, + "named-colors-palette": { + "text-color-swatch": "", + "transparent-swatch": "" + }, + "page-toolbar": { + "go-back": "", + "search-dashboard-name": "", + "search-links": "", + "search-parent-folder": "" + }, + "pagination": { + "next-page": "", + "previous-page": "" + }, + "secret-form-field": { + "reset": "" + }, + "segment-async": { + "error": "", + "loading": "", + "no-options": "" + }, + "select": { + "default-create-label": "", + "no-options-label": "", + "placeholder": "" + }, + "series-color-picker-popover": { + "y-axis-usage": "" + }, + "spinner": { + "aria-label": "" + }, + "table": { + "copy": "", + "csv-counts": "", + "filter-popup-apply": "", + "filter-popup-cancel": "", + "filter-popup-clear": "", + "filter-popup-heading": "", + "no-values-label": "", + "pagination-summary": "" + }, + "tags-input": { + "add": "" + }, + "user-icon": { + "active-text": "" + }, + "value-pill": { + "remove-button": "" + }, + "viz-legend": { + "right-axis-indicator": "" + }, + "viz-tooltip": { + "actions-confirmation-input-placeholder": "", + "actions-confirmation-label": "", + "actions-confirmation-message": "", + "footer-add-annotation": "", + "footer-click-to-action": "", + "footer-click-to-navigate": "" + } + }, + "graph": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "", + "title": "" + } + }, + "help-modal": { + "column-headers": { + "description": "", + "keys": "" + }, + "shortcuts-category": { + "dashboard": "", + "focused-panel": "", + "global": "", + "time-range": "" + }, + "shortcuts-description": { + "change-theme": "", + "collapse-all-rows": "", + "copy-time-range": "", + "dashboard-settings": "", + "duplicate-panel": "", + "exit-edit/setting-views": "", + "expand-all-rows": "", + "go-to-dashboards": "", + "go-to-explore": "", + "go-to-home-dashboard": "", + "go-to-profile": "", + "make-time-range-permanent": "", + "move-time-range-back": "", + "move-time-range-forward": "", + "open-search": "", + "open-shared-modal": "", + "paste-time-range": "", + "refresh-all-panels": "", + "remove-panel": "", + "save-dashboard": "", + "show-all-shortcuts": "", + "toggle-active-mode": "", + "toggle-all-panel-legends": "", + "toggle-auto-fit": "", + "toggle-exemplars": "", + "toggle-graph-crosshair": "", + "toggle-kiosk": "", + "toggle-panel-edit": "", + "toggle-panel-fullscreen": "", + "toggle-panel-legend": "", + "zoom-out-time-range": "" + }, + "title": "" + }, + "help-wizard": { + "download-snapshot": "", + "github-comment": "", + "support-bundle": "", + "troubleshooting-help": "" + }, + "inspector": { + "query": { + "collapse-all": "", + "copy-to-clipboard": "", + "description": "", + "expand-all": "", + "no-data": "", + "refresh": "" + } + }, + "ldap-drawer": { + "attributes-section": { + "description": "", + "email-label": "", + "label": "", + "member-of-label": "", + "name-label": "", + "surname-label": "", + "username-label": "" + }, + "extra-security-section": { + "client-cert-label": "", + "client-cert-placeholder": "", + "client-cert-value-label": "", + "client-cert-value-placeholder": "", + "client-key-label": "", + "client-key-placeholder": "", + "client-key-value-label": "", + "client-key-value-placeholder": "", + "encryption-provider-base-64": "", + "encryption-provider-description": "", + "encryption-provider-file-path": "", + "encryption-provider-label": "", + "label": "", + "min-tls-version-description": "", + "min-tls-version-label": "", + "root-ca-cert-label": "", + "root-ca-cert-placeholder": "", + "root-ca-cert-value-label": "", + "root-ca-cert-value-placeholder": "", + "start-tls-description": "", + "start-tls-label": "", + "tls-ciphers-label": "", + "tls-ciphers-placeholder": "", + "use-ssl-description": "", + "use-ssl-label": "", + "use-ssl-tooltip": "" + }, + "group-mapping": { + "grafana-admin": { + "description": "", + "label": "" + }, + "group-dn": { + "description": "", + "label": "" + }, + "org-id": { + "description": "", + "label": "" + }, + "org-role": { + "label": "" + }, + "remove": { + "button": "" + } + }, + "group-mapping-section": { + "add": { + "button": "" + }, + "description": "", + "group-search-base-dns-label": "", + "group-search-base-dns-placeholder": "", + "group-search-filter-description": "", + "group-search-filter-label": "", + "group-search-filter-user-attribute-description": "", + "group-search-filter-user-attribute-label": "", + "label": "", + "skip-org-role-sync-description": "", + "skip-org-role-sync-label": "" + }, + "misc-section": { + "allow-sign-up-descrition": "", + "allow-sign-up-label": "", + "label": "", + "port-description": "", + "port-label": "", + "timeout-description": "", + "timeout-label": "" + }, + "title": "" + }, + "ldap-settings-page": { + "advanced-settings-section": { + "edit-button": "", + "subtitle": "", + "title": "" + }, + "alert": { + "discard-success": "", + "error-fetching": "", + "error-saving": "", + "error-validate-form": "", + "feature-flag-disabled": "", + "saved": "" + }, + "bind-dn": { + "description": "", + "label": "", + "placeholder": "" + }, + "bind-password": { + "label": "" + }, + "buttons-section": { + "disable-button": "", + "discard-button": "", + "save-and-enable-button": "", + "save-button": "" + }, + "documentation": "", + "host": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "login-form-alert": { + "description": "", + "title": "" + }, + "search_filter": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "search-base-dns": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "subtitle": "", + "title": "" + }, + "library-panel": { + "add-modal": { + "cancel": "", + "create": "", + "error": "", + "folder": "", + "folder-description": "", + "name": "" + }, + "add-widget": { + "title": "" + }, + "empty-state": { + "message": "", + "more-info": "" + } + }, + "library-panels": { + "empty-state": { + "message": "" + }, + "loading-panel-text": "", + "modal": { + "button-cancel": "", + "button-view-panel1": "", + "button-view-panel2": "", + "panel-not-linked": "", + "select-no-options-message": "", + "select-placeholder": "", + "title": "", + "body_one": "", + "body_other": "" + }, + "save": { + "error": "", + "success": "" + } + }, + "link": { + "share": { + "config-alert-description": "", + "config-alert-title": "", + "config-description": "", + "copy-link-button": "", + "copy-to-clipboard": "", + "short-url-label": "", + "time-range-description": "", + "time-range-label": "" + }, + "share-panel": { + "config-description": "", + "download-image": "", + "render-image": "", + "render-image-error": "", + "render-image-error-description": "" + } + }, + "lock-icon": "", + "login": { + "divider": { + "connecting-text": "" + }, + "error": { + "blocked": "", + "invalid-user-or-password": "", + "title": "", + "unknown": "" + }, + "forgot-password": "", + "form": { + "confirmation-code": "", + "confirmation-code-label": "", + "confirmation-code-placeholder": "", + "email-label": "", + "email-placeholder": "", + "email-required": "", + "name-label": "", + "name-placeholder": "", + "password-label": "", + "password-placeholder": "", + "password-required": "", + "submit-label": "", + "submit-loading-label": "", + "username-label": "", + "username-placeholder": "", + "username-required": "", + "verify-email-label": "", + "verify-email-loading-label": "" + }, + "layout": { + "update-password": "" + }, + "services": { + "sing-in-with-prefix": "" + }, + "signup": { + "button-label": "", + "new-to-question": "" + } + }, + "logs": { + "infinite-scroll": { + "end-of-range": "", + "load-more": "", + "load-newer": "", + "load-older": "", + "older-logs": "" + }, + "log-details": { + "fields": "", + "links": "", + "log-line": "", + "no-details": "" + }, + "log-line-menu": { + "copy-link": "", + "copy-log": "", + "icon-label": "", + "pin-to-outline": "", + "show-context": "", + "unpin-from-outline": "" + }, + "log-row-message": { + "ellipsis": "", + "more": "", + "see-details": "" + }, + "log-rows": { + "disable-popover": { + "confirm": "", + "message": "", + "title": "" + }, + "disable-popover-message": { + "shortcut": "" + } + }, + "logs-navigation": { + "newer-logs": "", + "older-logs": "", + "scroll-bottom": "", + "scroll-top": "", + "start-of-range": "" + }, + "popover-menu": { + "copy": "", + "disable-menu": "", + "line-contains": "", + "line-contains-not": "" + } + }, + "migrate-to-cloud": { + "build-snapshot": { + "description": "", + "title": "", + "when-complete": "" + }, + "building-snapshot": { + "description": "", + "description-eta": "", + "title": "" + }, + "can-i-move": { + "body": "", + "link-title": "", + "title": "" + }, + "connect-modal": { + "body-cloud-stack": "", + "body-get-started": "", + "body-sign-up": "", + "body-token": "", + "body-token-field": "", + "body-token-field-placeholder": "", + "body-token-instructions": "", + "body-view-stacks": "", + "cancel": "", + "connect": "", + "connecting": "", + "title": "", + "token-error-title": "", + "token-errors": { + "instance-request-error": "", + "instance-unreachable": "", + "migration-disabled": "", + "session-creation-failure": "", + "token-invalid": "", + "token-not-saved": "", + "token-request-error": "", + "token-validation-failure": "" + }, + "token-required-error": "" + }, + "cta": { + "button": "", + "header": "" + }, + "delete-migration-token-confirm": { + "body": "", + "confirm-button": "", + "error-title": "", + "title": "" + }, + "disconnect-modal": { + "body": "", + "cancel": "", + "disconnect": "", + "disconnecting": "", + "error": "", + "title": "" + }, + "get-started": { + "body": "", + "configure-pdc-link": "", + "link-title": "", + "step-1": "", + "step-2": "", + "step-3": "", + "step-4": "", + "step-5": "", + "title": "" + }, + "is-it-secure": { + "body": "", + "link-title": "", + "title": "" + }, + "migrate-to-this-stack": { + "body": "", + "link-title": "", + "title": "" + }, + "migrated-counts": { + "alert_rule_groups": "", + "alert_rules": "", + "contact_points": "", + "dashboards": "", + "datasources": "", + "folders": "", + "library_elements": "", + "mute_timings": "", + "notification_policies": "", + "notification_templates": "", + "plugins": "" + }, + "migration-token": { + "delete-button": "", + "delete-modal-body": "", + "delete-modal-cancel": "", + "delete-modal-confirm": "", + "delete-modal-deleting": "", + "delete-modal-title": "", + "error-body": "", + "error-title": "", + "generate-button": "", + "generate-button-loading": "", + "modal-close": "", + "modal-copy-and-close": "", + "modal-copy-button": "", + "modal-field-description": "", + "modal-field-label": "", + "modal-title": "", + "status": "" + }, + "onprem": { + "cancel-snapshot-error-title": "", + "create-snapshot-error-title": "", + "disconnect-error-title": "", + "error-see-server-logs": "", + "get-session-error-title": "", + "get-snapshot-error-title": "", + "migration-finished-with-caveat-title": "", + "migration-finished-with-errors-body": "", + "migration-finished-with-warnings-body": "", + "snapshot-error-status-body": "", + "snapshot-error-status-title": "", + "success-message": "", + "success-message-generic": "", + "success-title": "", + "upload-snapshot-error-title": "" + }, + "pdc": { + "body": "", + "link-title": "", + "title": "" + }, + "pricing": { + "body": "", + "link-title": "", + "title": "" + }, + "public-preview": { + "button-text": "", + "message": "", + "message-cloud": "", + "title": "" + }, + "resource-details": { + "dismiss-button": "", + "error-messages": { + "dashboard-already-managed": "", + "datasource-already-managed": "", + "datasource-invalid-url": "", + "datasource-name-conflict": "", + "folder-name-conflict": "", + "generic-error": "", + "internal-service-error": "", + "library-element-name-conflict": "", + "resource-conflict": "", + "unexpected-error": "", + "unsupported-data-type": "" + }, + "error-title": "", + "generic-title": "", + "missing-message": "", + "resource-summary": "", + "title": "", + "warning-title": "" + }, + "resource-status": { + "error-details-button": "", + "failed": "", + "migrated": "", + "migrating": "", + "not-migrated": "", + "unknown": "", + "warning": "", + "warning-details-button": "" + }, + "resource-table": { + "dashboard-load-error": "", + "error-library-element-sub": "", + "error-library-element-title": "", + "unknown-datasource-title": "", + "unknown-datasource-type": "" + }, + "resource-type": { + "alert_rule": "", + "alert_rule_group": "", + "contact_point": "", + "dashboard": "", + "datasource": "", + "folder": "", + "library_element": "", + "mute_timing": "", + "notification_policy": "", + "notification_template": "", + "plugin": "", + "unknown": "" + }, + "summary": { + "cancel-snapshot": "", + "disconnect": "", + "errored-resource-count": "", + "page-loading": "", + "rebuild-snapshot": "", + "snapshot-date": "", + "snapshot-not-created": "", + "start-migration": "", + "successful-resource-count": "", + "target-stack-title": "", + "total-resource-count": "", + "upload-migration": "" + }, + "support-types-disclosure": { + "text": "" + }, + "token-status": { + "active": "", + "no-active": "", + "unknown": "", + "unknown-error": "" + }, + "what-is-cloud": { + "body": "", + "link-title": "", + "title": "" + }, + "why-host": { + "body": "", + "link-title": "", + "title": "" + } + }, + "multicombobox": { + "all": { + "title": "", + "title-filtered": "" + }, + "clear": { + "title": "" + } + }, + "nav": { + "add-new-connections": { + "title": "" + }, + "admin": { + "subtitle": "", + "title": "" + }, + "alert-list-legacy": { + "title": "" + }, + "alerting": { + "subtitle": "", + "title": "" + }, + "alerting-admin": { + "subtitle": "", + "title": "" + }, + "alerting-am-routes": { + "subtitle": "", + "title": "" + }, + "alerting-channels": { + "title": "" + }, + "alerting-groups": { + "subtitle": "", + "title": "" + }, + "alerting-home": { + "title": "" + }, + "alerting-legacy": { + "title": "" + }, + "alerting-list": { + "subtitle": "", + "title": "" + }, + "alerting-receivers": { + "subtitle": "", + "title": "" + }, + "alerting-silences": { + "subtitle": "", + "title": "" + }, + "alerting-upgrade": { + "subtitle": "", + "title": "" + }, + "alerts-and-incidents": { + "subtitle": "", + "title": "" + }, + "api-keys": { + "subtitle": "", + "title": "" + }, + "application": { + "title": "" + }, + "apps": { + "subtitle": "", + "title": "" + }, + "authentication": { + "title": "" + }, + "bookmarks": { + "title": "" + }, + "bookmarks-empty": { + "title": "" + }, + "collector": { + "title": "" + }, + "config": { + "title": "" + }, + "config-access": { + "subtitle": "", + "title": "" + }, + "config-general": { + "subtitle": "", + "title": "" + }, + "config-plugins": { + "subtitle": "", + "title": "" + }, + "connect-data": { + "title": "" + }, + "connections": { + "subtitle": "", + "title": "" + }, + "correlations": { + "subtitle": "", + "title": "" + }, + "create": { + "title": "" + }, + "create-alert": { + "title": "" + }, + "create-dashboard": { + "title": "" + }, + "create-folder": { + "title": "" + }, + "create-import": { + "title": "" + }, + "dashboards": { + "subtitle": "", + "title": "" + }, + "data-sources": { + "subtitle": "", + "title": "" + }, + "databases": { + "title": "" + }, + "datasources": { + "subtitle": "", + "title": "" + }, + "detect": { + "title": "" + }, + "drilldown": { + "title": "" + }, + "explore": { + "title": "" + }, + "frontend": { + "subtitle": "", + "title": "" + }, + "frontend-app": { + "title": "" + }, + "global-orgs": { + "subtitle": "", + "title": "" + }, + "global-users": { + "subtitle": "", + "title": "" + }, + "grafana-quaderno": { + "title": "" + }, + "groupsync": { + "subtitle": "" + }, + "help": { + "title": "" + }, + "help/community": "", + "help/documentation": "", + "help/keyboard-shortcuts": "", + "help/support": "", + "history-container": { + "drawer-tittle": "" + }, + "history-wrapper": { + "collapse": "", + "expand": "", + "icon-selected": "", + "icon-unselected": "", + "show-more": "", + "today": "", + "yesterday": "" + }, + "home": { + "title": "" + }, + "incidents": { + "title": "" + }, + "infrastructure": { + "subtitle": "", + "title": "" + }, + "integrations": { + "title": "" + }, + "k6": { + "title": "" + }, + "kubernetes": { + "title": "" + }, + "library-panels": { + "subtitle": "", + "title": "" + }, + "machine-learning": { + "title": "" + }, + "manage-folder": { + "subtitle": "" + }, + "migrate-to-cloud": { + "subtitle": "", + "title": "" + }, + "monitoring": { + "subtitle": "", + "title": "" + }, + "new": { + "title": "" + }, + "new-dashboard": { + "title": "" + }, + "new-folder": { + "title": "" + }, + "oncall": { + "title": "" + }, + "org-settings": { + "subtitle": "", + "title": "" + }, + "playlists": { + "subtitle": "", + "title": "" + }, + "plugins": { + "subtitle": "", + "title": "" + }, + "private-data-source-connections": { + "subtitle": "", + "title": "" + }, + "profile/notifications": { + "title": "" + }, + "profile/password": { + "title": "" + }, + "profile/settings": { + "title": "" + }, + "profiles": { + "title": "" + }, + "public": { + "title": "" + }, + "recently-deleted": { + "subtitle": "", + "title": "" + }, + "recorded-queries": { + "title": "" + }, + "reporting": { + "title": "" + }, + "scenes": { + "title": "" + }, + "search": { + "placeholderCommandPalette": "" + }, + "search-dashboards": { + "title": "" + }, + "server-settings": { + "subtitle": "", + "title": "" + }, + "service-accounts": { + "subtitle": "", + "title": "" + }, + "setup-guide": { + "title": "" + }, + "shared-dashboard": { + "subtitle": "", + "title": "" + }, + "sign-out": { + "title": "" + }, + "slo": { + "title": "" + }, + "snapshots": { + "subtitle": "", + "title": "" + }, + "starred": { + "title": "" + }, + "starred-empty": { + "title": "" + }, + "statistics-and-licensing": { + "title": "" + }, + "storage": { + "subtitle": "", + "title": "" + }, + "support-bundles": { + "subtitle": "", + "title": "" + }, + "synthetics": { + "title": "" + }, + "teams": { + "subtitle": "", + "title": "" + }, + "testing-and-synthetics": { + "subtitle": "", + "title": "" + }, + "upgrading": { + "title": "" + }, + "users": { + "subtitle": "", + "title": "" + } + }, + "navigation": { + "invite-user": { + "invite-button": "", + "invite-tooltip": "" + }, + "item": { + "add-bookmark": "", + "remove-bookmark": "" + }, + "kiosk": { + "tv-alert": "" + }, + "megamenu": { + "close": "", + "dock": "", + "list-label": "", + "open": "", + "undock": "" + }, + "rss-button": "" + }, + "news": { + "drawer": { + "close": "" + }, + "title": "" + }, + "notifications": { + "empty-state": { + "description": "", + "title": "" + }, + "starred-dashboard": "", + "unstarred-dashboard": "" + }, + "oauth": { + "form": { + "server-discovery-action-button": "", + "server-discovery-modal-close": "", + "server-discovery-modal-loading": "", + "server-discovery-modal-submit": "" + }, + "login": { + "error": "" + } + }, + "panel": { + "header-menu": { + "copy": "", + "create-library-panel": "", + "duplicate": "", + "edit": "", + "explore": "", + "get-help": "", + "hide-legend": "", + "inspect": "", + "inspect-data": "", + "inspect-json": "", + "more": "", + "new-alert-rule": "", + "query": "", + "remove": "", + "replace-library-panel": "", + "share": "", + "show-legend": "", + "unlink-library-panel": "", + "view": "" + } + }, + "panel-search": { + "no-matches": "", + "unsupported-layout": "" + }, + "panel-type-filter": { + "clear-button": "" + }, + "playlist-edit": { + "error-prefix": "", + "form": { + "add-tag-label": "", + "add-tag-placeholder": "", + "add-title-label": "", + "cancel": "", + "heading": "", + "interval-label": "", + "interval-placeholder": "", + "interval-required": "", + "name-label": "", + "name-placeholder": "", + "name-required": "", + "save": "", + "table-delete": "", + "table-drag": "", + "table-empty": "", + "table-heading": "" + }, + "sub-title": "", + "title": "" + }, + "playlist-page": { + "card": { + "delete": "", + "edit": "", + "start": "", + "tooltip": "" + }, + "create-button": { + "title": "" + }, + "delete-modal": { + "body": "", + "confirm-text": "" + }, + "empty": { + "button": "", + "pro-tip": "", + "title": "" + } + }, + "playlists": { + "empty-state": { + "message": "" + } + }, + "plugins": { + "catalog": { + "no-updates-available": "", + "update-all": { + "all-plugins-updated": "", + "available-header": "", + "button": "", + "cloud-update-message": "", + "error": "", + "error-status-text": "", + "header": "", + "installed-header": "", + "modal-confirmation": "", + "modal-dismiss": "", + "modal-in-progress": "", + "modal-title": "", + "name-header": "", + "update-header": "", + "update-status-text": "" + }, + "versions": { + "confirmation-text-1": "", + "confirmation-text-2": "", + "downgrade-confirm": "", + "downgrade-title": "" + } + }, + "details": { + "connections-tab": { + "description": "" + }, + "labels": { + "contactGrafanaLabs": "", + "customLinks": "", + "customLinksTooltip": "", + "dependencies": "", + "documentation": "", + "downloads": "", + "from": "", + "installedVersion": "", + "lastCommitDate": "", + "latestVersion": "", + "license": "", + "raiseAnIssue": "", + "reportAbuse": "", + "reportAbuseTooltip": "", + "repository": "", + "signature": "", + "status": "", + "updatedAt": "" + }, + "modal": { + "cancel": "", + "copyEmail": "", + "description": "", + "node": "", + "title": "" + } + }, + "empty-state": { + "message": "" + }, + "filter": { + "disabled": "", + "sort": "", + "sort-list": "", + "state": "" + }, + "plugin-help": { + "error": "", + "not-found": "" + } + }, + "profile": { + "change-password": { + "cancel-button": "", + "cannot-change-password-message": "", + "change-password-button": "", + "confirm-password-label": "", + "confirm-password-required": "", + "ldap-auth-proxy-message": "", + "new-password-label": "", + "new-password-required": "", + "new-password-same-as-old": "", + "old-password-label": "", + "old-password-required": "", + "passwords-must-match": "", + "strong-password-validation-register": "" + } + }, + "public-dashboard": { + "acknowledgment-checkboxes": { + "ack-title": "", + "data-src-ack-desc": "", + "data-src-ack-tooltip": "", + "public-ack-desc": "", + "public-ack-tooltip": "", + "usage-ack-desc": "", + "usage-ack-desc-tooltip": "" + }, + "config": { + "can-view-dashboard-radio-button-label": "", + "copy-button": "", + "dashboard-url-field-label": "", + "email-share-type-option-label": "", + "pause-sharing-dashboard-label": "", + "public-share-type-option-label": "", + "revoke-public-URL-button": "", + "revoke-public-URL-button-title": "", + "settings-title": "" + }, + "configuration": { + "display-annotations-description": "", + "display-annotations-label": "", + "enable-time-range-description": "", + "enable-time-range-label": "", + "settings-label": "", + "success-pause": "", + "success-resume": "", + "success-update": "", + "success-update-old": "", + "time-range-label": "", + "time-range-tooltip": "" + }, + "create-page": { + "generate-public-url-button": "", + "unsupported-features-desc": "", + "welcome-title": "" + }, + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "email-sharing": { + "accept-button": "", + "alert-text": "", + "bill-ack": "", + "cancel-button": "", + "input-invalid-email-text": "", + "input-required-email-text": "", + "invite-button": "", + "invite-field-desc": "", + "invite-field-label": "", + "learn-more-button": "", + "recipient-email-placeholder": "", + "recipient-invalid-email-text": "", + "recipient-invitation-button": "", + "recipient-invitation-description": "", + "recipient-invitation-tooltip": "", + "recipient-list-description": "", + "recipient-list-title": "", + "recipient-required-email-text": "", + "resend-button": "", + "resend-button-title": "", + "resend-invite-label": "", + "revoke-access-label": "", + "revoke-button": "", + "revoke-button-title": "", + "success-creation": "", + "success-share-type-change": "" + }, + "modal-alerts": { + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "save-dashboard-changes-alert-title": "", + "unsupport-data-source-alert-readmore-link": "", + "unsupported-data-source-alert-desc": "", + "unsupported-data-source-alert-title": "", + "unsupported-template-variable-alert-desc": "", + "unsupported-template-variable-alert-title": "" + }, + "public-sharing": { + "accept-button": "", + "alert-text": "", + "cancel-button": "", + "learn-more-button": "", + "public-ack": "", + "success-creation": "", + "success-share-type-change": "" + }, + "settings-bar-header": { + "collapse-settings-tooltip": "", + "expand-settings-tooltip": "" + }, + "settings-configuration": { + "default-time-range-label": "", + "default-time-range-label-desc": "", + "show-annotations-label": "", + "show-annotations-label-desc": "", + "time-range-picker-label": "", + "time-range-picker-label-desc": "" + }, + "settings-summary": { + "annotations-hide-text": "", + "annotations-show-text": "", + "time-range-picker-disabled-text": "", + "time-range-picker-enabled-text": "", + "time-range-text": "" + }, + "share": { + "success-delete": "", + "success-delete-old": "" + }, + "share-configuration": { + "share-type-label": "" + }, + "share-externally": { + "copy-link-button": "", + "email-share-type-option-description": "", + "email-share-type-option-label": "", + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "pause-access-button": "", + "pause-access-tooltip": "", + "public-share-type-option-description": "", + "public-share-type-option-label": "", + "resume-access-button": "", + "revoke-access-button": "", + "revoke-access-description": "", + "unsupported-data-source-alert-desc": "" + }, + "sharing": { + "success-creation": "" + } + }, + "public-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "public-dashboard-users-access-list": { + "dashboard-modal": { + "external-link": "", + "loading-text": "", + "open-dashboard-list-text": "", + "public-dashboard-link": "", + "public-dashboard-setting": "", + "sharing-setting": "" + }, + "delete-user-modal": { + "delete-user-button-text": "", + "delete-user-cancel-button": "", + "delete-user-revoke-access-button": "", + "revoke-access-title": "", + "revoke-user-access-modal-desc-line1": "", + "revoke-user-access-modal-desc-line2": "" + }, + "delete-user-shared-dashboards-modal": { + "revoke-user-access-modal-desc-line2": "" + }, + "modal": { + "dashboard-modal-title": "", + "shared-dashboard-modal-title": "" + }, + "table-body": { + "dashboard-count_one": "", + "dashboard-count_other": "" + }, + "table-header": { + "activated-label": "", + "activated-tooltip": "", + "email-label": "", + "last-active-label": "", + "origin-label": "", + "role-label": "" + } + }, + "query-operation": { + "header": { + "collapse-row": "", + "datasource-help": "", + "drag-and-drop": "", + "duplicate-query": "", + "expand-row": "", + "hide-response": "", + "remove-query": "", + "show-response": "", + "toggle-edit-mode": "" + }, + "query-editor-not-exported": "" + }, + "recently-deleted": { + "buttons": { + "delete": "", + "restore": "" + }, + "page": { + "no-deleted-dashboards": "", + "no-deleted-dashboards-text": "", + "no-search-result": "" + }, + "permanently-delete-modal": { + "confirm-text": "", + "delete-button": "", + "delete-loading": "", + "title": "", + "text_one": "", + "text_other": "" + }, + "restore-modal": { + "restore-button": "", + "restore-loading": "", + "title": "", + "folder-picker-text_one": "", + "folder-picker-text_other": "", + "text_one": "", + "text_other": "" + } + }, + "recentlyDeleted": { + "filter": { + "placeholder": "" + } + }, + "reduce": { + "strictMode": { + "description": "", + "title": "" + } + }, + "refresh-picker": { + "aria-label": { + "choose-interval": "", + "duration-selected": "" + }, + "auto-option": { + "aria-label": "", + "label": "" + }, + "live-option": { + "aria-label": "", + "label": "" + }, + "off-option": { + "aria-label": "", + "label": "" + }, + "tooltip": { + "interval-selected": "", + "turned-off": "" + } + }, + "return-to-previous": { + "button": { + "label": "" + }, + "dismissable-button": "" + }, + "role-picker": { + "built-in": { + "basic-roles": "" + }, + "input": { + "no-roles": "" + }, + "menu": { + "clear-button": "", + "tooltip": "" + }, + "sub-menu": { + "clear-button": "" + }, + "title": { + "description": "" + } + }, + "role-picker-drawer": { + "basic-roles": { + "label": "" + } + }, + "route-error": { + "description": "", + "reload-button": "", + "title": "" + }, + "save-dashboards": { + "message-length": { + "info": "", + "title": "" + }, + "name-exists": { + "message-info": "", + "message-suggestion": "", + "title": "" + } + }, + "scopes": { + "dashboards": { + "collapse": "", + "expand": "", + "loading": "", + "noResultsForFilter": "", + "noResultsForFilterClear": "", + "noResultsForScopes": "", + "noResultsNoScopes": "", + "search": "", + "toggle": { + "collapse": "", + "disabled": "", + "expand": "" + } + }, + "selector": { + "apply": "", + "cancel": "", + "input": { + "placeholder": "", + "removeAll": "" + }, + "title": "" + }, + "tree": { + "collapse": "", + "expand": "", + "headline": { + "noResults": "", + "recommended": "", + "results": "" + }, + "search": "" + } + }, + "search": { + "actions": { + "include-panels": "", + "remove-datasource-filter": "", + "sort-placeholder": "", + "starred": "", + "view-as-folders": "", + "view-as-list": "" + }, + "dashboard-actions": { + "import": "", + "new": "", + "new-dashboard": "", + "new-folder": "" + }, + "results-table": { + "datasource-header": "", + "deleted-less-than-1-min": "", + "deleted-remaining-header": "", + "location-header": "", + "name-header": "", + "tags-header": "", + "type-dashboard": "", + "type-folder": "", + "type-header": "" + }, + "search-input": { + "include-panels-placeholder": "", + "placeholder": "" + } + }, + "select": { + "select-menu": { + "selected-count": "" + } + }, + "service-account-create-page": { + "create": { + "button": "" + }, + "name": { + "label": "", + "required-error": "" + }, + "page-nav": { + "label": "" + }, + "role": { + "label": "" + } + }, + "service-accounts": { + "empty-state": { + "button-title": "", + "message": "", + "more-info": "", + "title": "" + } + }, + "share-dashboard": { + "menu": { + "export-json-title": "", + "share-externally-title": "", + "share-internally-title": "", + "share-snapshot-title": "" + }, + "share-button": "", + "share-button-tooltip": "" + }, + "share-drawer": { + "confirm-action": { + "back-arrow-button": "", + "cancel-button": "" + } + }, + "share-modal": { + "dashboard": { + "title": "" + }, + "embed": { + "copy": "", + "html": "", + "html-description": "", + "info": "", + "time-range": "" + }, + "export": { + "back-button": "", + "cancel-button": "", + "info-text": "", + "loading": "", + "save-button": "", + "share-externally-label": "", + "view-button": "" + }, + "library": { + "info": "" + }, + "link": { + "copy-link-button": "", + "info-text": "", + "link-url": "", + "render-alert": "", + "render-instructions": "", + "rendered-image": "", + "save-alert": "", + "save-dashboard": "", + "shorten-url": "", + "time-range-description": "", + "time-range-label": "" + }, + "panel": { + "title": "" + }, + "snapshot": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "deleted-message": "", + "expire": "", + "expire-day": "", + "expire-hour": "", + "expire-never": "", + "expire-week": "", + "info-text-1": "", + "info-text-2": "", + "local-button": "", + "mistake-message": "", + "name": "", + "timeout": "", + "timeout-description": "", + "url-label": "" + }, + "tab-title": { + "embed": "", + "export": "", + "library-panel": "", + "link": "", + "panel-embed": "", + "public-dashboard": "", + "public-dashboard-title": "", + "snapshot": "" + }, + "theme-picker": { + "current": "", + "dark": "", + "field-name": "", + "light": "" + }, + "view-json": { + "copy-button": "" + } + }, + "share-panel": { + "drawer": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "" + }, + "menu": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "", + "share-snapshot-title": "" + }, + "new-library-panel": { + "cancel-button": "", + "create-button": "" + } + }, + "share-panel-image": { + "preview": { + "title": "" + }, + "settings": { + "height-label": "", + "height-min": "", + "height-placeholder": "", + "height-required": "", + "max-warning": "", + "scale-factor-label": "", + "scale-factor-min": "", + "scale-factor-placeholder": "", + "scale-factor-required": "", + "title": "", + "width-label": "", + "width-min": "", + "width-placeholder": "", + "width-required": "" + } + }, + "share-playlist": { + "checkbox-description": "", + "checkbox-label": "", + "copy-link-button": "", + "link-url-label": "", + "mode": "", + "mode-kiosk": "", + "mode-normal": "", + "title": "" + }, + "shared": { + "preferences": { + "theme": { + "dark-label": "", + "light-label": "", + "system-label": "" + } + } + }, + "shared-dashboard": { + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "fields": { + "timezone-label": "" + } + }, + "shared-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "shared-preferences": { + "fields": { + "home-dashboard-label": "", + "home-dashboard-placeholder": "", + "locale-label": "", + "locale-placeholder": "", + "theme-description": "", + "theme-label": "", + "week-start-label": "" + }, + "theme": { + "default-label": "" + }, + "title": "" + }, + "sign-up": { + "back-button": "", + "submit-button": "", + "verify": { + "back-button": "", + "complete-button": "", + "header": "", + "info": "", + "send-button": "" + } + }, + "silences": { + "empty-state": { + "button-title": "", + "title": "" + }, + "table": { + "add-silence-button": "", + "edit-button": "", + "expired-silences": "", + "no-matching-silences": "", + "noConfig": "", + "recreate-button": "", + "unsilence-button": "" + } + }, + "silences-table": { + "header": { + "alert-name": "", + "state": "" + } + }, + "snapshot": { + "empty-state": { + "message": "", + "more-info": "" + }, + "external-badge": "", + "name-column-header": "", + "share": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "delete-description": "", + "delete-permission-tooltip": "", + "delete-title": "", + "deleted-alert": "", + "expiration-label": "", + "info-alert": "", + "learn-more-button": "", + "local-button": "", + "name-label": "", + "new-snapshot-button": "", + "success-creation": "", + "success-delete": "", + "view-all-button": "" + }, + "share-panel": { + "info-alert": "" + }, + "url-column-header": "", + "view-button": "" + }, + "table": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "" + } + }, + "tag-filter": { + "clear-button": "", + "loading": "", + "no-tags": "", + "placeholder": "" + }, + "teams": { + "empty-state": { + "button-title": "", + "message": "", + "pro-tip": "", + "title": "" + } + }, + "theme-preview": { + "breadcrumbs": { + "dashboards": "", + "home": "" + }, + "panel": { + "form-label": "", + "title": "" + } + }, + "time-picker": { + "absolute": { + "recent-title": "", + "title": "" + }, + "calendar": { + "apply-button": "", + "cancel-button": "", + "close": "", + "next-month": "", + "previous-month": "", + "select-time": "" + }, + "content": { + "empty-recent-list-docs": "", + "empty-recent-list-info": "", + "filter-placeholder": "" + }, + "copy-paste": { + "copy-success-message": "", + "default-error-message": "", + "default-error-title": "", + "tooltip-copy": "", + "tooltip-paste": "" + }, + "footer": { + "change-settings-button": "", + "fiscal-year-option": "", + "fiscal-year-start": "", + "time-zone-option": "", + "time-zone-selection": "" + }, + "range-content": { + "apply-button": "", + "default-error": "", + "fiscal-year": "", + "from-input": "", + "open-input-calendar": "", + "range-error": "", + "to-input": "" + }, + "range-picker": { + "backwards-time-aria-label": "", + "current-time-selected": "", + "forwards-time-aria-label": "", + "to": "", + "zoom-out-button": "", + "zoom-out-tooltip": "" + }, + "time-range": { + "apply": "", + "aria-role": "", + "default-title": "", + "example": "", + "example-details": "", + "example-title": "", + "from-label": "", + "from-to": "", + "more-info": "", + "specify": "", + "submit-button-label": "", + "supported-formats": "", + "to-label": "" + }, + "zone": { + "select-aria-label": "", + "select-search-input": "" + } + }, + "trails": { + "bookmarks": { + "or-view-bookmarks": "" + }, + "card": { + "date-created": "" + }, + "home": { + "learn-more": "", + "lets-start": "", + "start-your-metrics-exploration": "", + "subtitle": "" + }, + "metric-select": { + "filter-by": "", + "native-histogram": "", + "new-badge": "", + "otel-switch": "" + }, + "native-histogram-banner": { + "ch-heatmap": "", + "ch-histogram": "", + "click-histogram": "", + "hide-examples": "", + "learn-more": "", + "metric-examples": "", + "nh-heatmap": "", + "nh-histogram": "", + "now": "", + "previously": "", + "see-examples": "", + "sentence": "" + }, + "recent-metrics": { + "or-view-a-recent-exploration": "" + }, + "settings": { + "always-keep-selected-metric-graph-in-view": "", + "show-previews-of-metric-graphs": "" + } + }, + "transformations": { + "empty": { + "add-transformation-body": "", + "add-transformation-header": "" + } + }, + "upgrade-box": { + "discovery-text": "", + "discovery-text-continued": "", + "get-started": "", + "learn-more": "", + "upgrade-button": "" + }, + "user-orgs": { + "current-org-button": "", + "name-column": "", + "role-column": "", + "select-org-button": "", + "title": "" + }, + "user-profile": { + "fields": { + "email-error": "", + "email-label": "", + "name-error": "", + "name-label": "", + "username-label": "" + }, + "tabs": { + "general": "" + } + }, + "user-session": { + "auth-module-column": "", + "browser-column": "", + "created-at-column": "", + "identity-provider-column": "", + "ip-column": "", + "revoke": "", + "seen-at-column": "" + }, + "user-sessions": { + "loading": "" + }, + "users": { + "empty-state": { + "message": "" + } + }, + "users-access-list": { + "tabs": { + "public-dashboard-users-tab-title": "", + "shared-dashboard-users-tab-title": "" + } + }, + "variable": { + "adhoc": { + "placeholder": "" + }, + "dropdown": { + "placeholder": "" + }, + "picker": { + "link-all": "", + "option-all": "", + "option-selected-values": "", + "option-tooltip": "" + }, + "textbox": { + "placeholder": "" + } + }, + "variables": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + }, + "unknown-table": { + "loading": "", + "no-unknowns": "", + "renamed-or-missing-variables": "", + "variable": "" + } + } +} \ No newline at end of file diff --git a/public/locales/pl-PL/grafana.json b/public/locales/pl-PL/grafana.json new file mode 100644 index 00000000000..af5d7e65575 --- /dev/null +++ b/public/locales/pl-PL/grafana.json @@ -0,0 +1,4038 @@ +{ + "_comment": "", + "access-control": { + "add-permission": { + "role-label": "", + "serviceaccount-label": "", + "team-label": "", + "title": "", + "user-label": "" + }, + "add-permissions": { + "save": "" + }, + "permission-list": { + "permission": "" + }, + "permission-list-item": { + "inherited": "" + }, + "permissions": { + "add-label": "", + "no-permissions": "", + "permissions-change-warning": "", + "role": "", + "serviceaccount": "", + "team": "", + "title": "", + "user": "" + } + }, + "action-editor": { + "modal": { + "cancel-button": "", + "save-button": "" + } + }, + "admin": { + "anon-users": { + "not-found": "" + }, + "edit-org": { + "access-denied": "", + "heading": "", + "update-button": "", + "users-heading": "" + }, + "feature-toggles": { + "sub-title": "" + }, + "get-enterprise": { + "contact-us": "", + "description": "", + "features-heading": "", + "included-description": "", + "included-heading": "", + "service-title": "", + "team-sync-details": "", + "title": "" + }, + "ldap": { + "test-mapping-heading": "", + "test-mapping-run-button": "" + }, + "ldap-permissions": { + "active": "", + "admin": "", + "inactive": "" + }, + "ldap-status": { + "title": "" + }, + "ldap-sync": { + "debug-button": "", + "external-sync-description": "", + "external-sync-label": "", + "next-sync-label": "", + "not-enabled": "", + "sync-button": "", + "title": "" + }, + "ldap-sync-info": { + "title": "" + }, + "ldap-user-groups": { + "no-org-found": "" + }, + "ldap-user-info": { + "no-team": "" + }, + "org-uers": { + "last-seen-never": "" + }, + "org-users": { + "not-editable": "" + }, + "orgs": { + "delete-body": "", + "id-header": "", + "name-header": "", + "new-org-button": "" + }, + "server-settings": { + "alerts-button": "", + "dashboards-button": "", + "data-sources-button": "", + "not-found": "", + "title": "", + "users-button": "" + }, + "settings": { + "info-description": "" + }, + "upgrade-info": { + "title": "" + }, + "user-orgs": { + "add-button": "", + "change-role-button": "", + "external-user-tooltip": "", + "remove-button": "", + "role-not-editable": "", + "title": "" + }, + "user-orgs-modal": { + "add-button": "", + "cancel-button": "" + }, + "user-permissions": { + "change-button": "", + "grafana-admin-key": "", + "grafana-admin-no": "", + "grafana-admin-yes": "", + "title": "" + }, + "user-profile": { + "delete-button": "", + "disable-button": "", + "edit-button": "", + "enable-button": "", + "title": "" + }, + "user-sessions": { + "browser-column": "", + "force-logout-all-button": "", + "force-logout-button": "", + "ip-column": "", + "last-seen-column": "", + "logged-on-column": "", + "title": "" + }, + "users-create": { + "create-button": "" + }, + "users-list": { + "create-button": "" + }, + "users-table": { + "last-seen-never": "", + "no-licensed-roles": "" + } + }, + "alert-labels": { + "button": { + "hide": "", + "show": { + "tooltip": "" + } + } + }, + "alerting": { + "alert": { + "alert-state": "", + "annotations": "", + "evaluation": "", + "evaluation-paused": "", + "evaluation-paused-description": "", + "last-evaluated": "", + "last-evaluation-duration": "", + "last-updated-at": "", + "last-updated-by": "", + "no-annotations": "", + "pending-period": "", + "rule": "", + "rule-identifier": "", + "rule-type": "", + "state-error-timeout": "", + "state-no-data": "", + "target-datasource-uid": "" + }, + "alert-recording-rule-form": { + "evaluation-behaviour": { + "description": { + "text": "" + } + } + }, + "alert-rules": { + "firing-for": "", + "next-evaluation": "", + "next-evaluation-in": "", + "rule-definition": "" + }, + "alertform": { + "labels": { + "alerting": "", + "recording": "" + } + }, + "alertVersionHistory": { + "alerting": "", + "alerting-change-description": "", + "annotations": "", + "compare": "", + "compare-with-latest": "", + "compareVersions": "", + "comparing-versions": "", + "condition": "", + "contactPointRouting": "", + "description": "", + "errorloading": "", + "execErrorState": "", + "intervalSeconds": "", + "labels": "", + "latest": "", + "name": "", + "namespace_uid": "", + "noDataState": "", + "noVersionsFound": "", + "paused": "", + "pendingPeriod": "", + "provisioning": "", + "provisioning-change-description": "", + "queryAndAlertCondition": "", + "restore": "", + "restore-manually": "", + "restore-modal": { + "body": "", + "confirm": "", + "error": "", + "summary": "", + "title": "" + }, + "restore-version": "", + "rule_group": "", + "unknown": "", + "unknown-change-description": "", + "user-id": "", + "warning-restore-manually": "", + "warning-restore-manually-title": "" + }, + "annotations": { + "description": "", + "title": "" + }, + "central-alert-history": { + "details": { + "error": "", + "header": { + "alert-rule": "", + "instance": "", + "state": "", + "timestamp": "" + }, + "loading": "", + "no-recognized-state": "", + "no-values": "", + "not-found": "", + "number-transitions": "", + "state": { + "alerting": "", + "error": "", + "no-data": "", + "normal": "", + "pending": "" + }, + "state-transitions": "", + "unknown-event-state": "", + "unknown-rule": "", + "value-in-transition": "" + }, + "error": "", + "filter": { + "clear": "", + "info": { + "label1": "", + "label2": "", + "label3": "", + "label4": "" + } + }, + "filterBy": "", + "too-many-events": { + "text": "", + "title": "" + } + }, + "common": { + "cancel": "", + "clear-filters": "", + "delete": "", + "edit": "", + "export": "", + "export-all": "", + "loading": "", + "search-by-matchers": "", + "titles": { + "notification-templates": "" + }, + "view": "" + }, + "contact-points": { + "create": "", + "custom-template-value": "", + "delete-reasons": { + "heading": "", + "no-permissions": "", + "policies": "", + "provisioned": "", + "rules": "" + }, + "delivered-to": "", + "delivery-duration": "", + "empty-state": { + "title": "" + }, + "key-value-map": { + "add": "", + "confirm-add": "" + }, + "last-delivery-attempt": "", + "last-delivery-failed": "", + "no-contact-points-found": "", + "no-delivery-attempts": "", + "no-integrations": "", + "only-firing": "", + "receiver-summary": { + "jira": "" + }, + "telegram": { + "parse-mode-warning-body": "", + "parse-mode-warning-title": "" + }, + "used-by_one": "", + "used-by_few": "", + "used-by_many": "", + "used-by_other": "", + "used-by-rules_one": "", + "used-by-rules_few": "", + "used-by-rules_many": "", + "used-by-rules_other": "" + }, + "contactPointFilter": { + "label": "" + }, + "copy-to-clipboard": "", + "dag": { + "missing-reference": "", + "self-reference": "" + }, + "export": { + "subtitle": { + "formats": "", + "one-format": "" + } + }, + "folderAndGroup": { + "evaluation": { + "modal": { + "text": { + "alerting": "", + "recording": "" + } + } + } + }, + "group-actions": { + "actions-trigger": "", + "delete": "", + "edit": "", + "export": "", + "reorder": "" + }, + "list-view": { + "empty": { + "new-alert-rule": "", + "new-recording-rule": "", + "provisioning": "" + }, + "section": { + "dataSourceManaged": { + "title": "" + }, + "grafanaManaged": { + "export-new-rule": "", + "export-rules": "", + "loading": "", + "new-recording-rule": "", + "title": "" + } + } + }, + "manage-permissions": { + "button": "", + "title": "" + }, + "mute_timings": { + "error-loading": { + "description": "", + "title": "" + } + }, + "mute-timings": { + "add-mute-timing": "", + "description": "", + "save": "", + "saving": "" + }, + "notification-preview": { + "alertmanager": "", + "error": "", + "initialized": "", + "preview-routing": "", + "title": "", + "uninitialized": "" + }, + "notification-templates": { + "duplicate": { + "subTitle": "", + "title": "" + }, + "edit": { + "subTitle": "", + "title": "" + }, + "new": { + "subTitle": "", + "title": "" + } + }, + "policies": { + "default-policy": { + "description": "", + "title": "", + "update": "" + }, + "delete": { + "confirm": "", + "warning-1": "", + "warning-2": "" + }, + "filter-description": "", + "generated-policies": "", + "matchers": "", + "metadata": { + "active-time": "", + "delivered-to": "", + "grouped-by": "", + "grouping": { + "none": "", + "single-group": "" + }, + "inherited": "", + "mute-time": "", + "timingOptions": { + "groupInterval": { + "description": "", + "label": "" + }, + "groupWait": { + "description": "", + "label": "" + }, + "repeatInterval": { + "description": "", + "label": "" + } + }, + "n-instances_one": "", + "n-instances_few": "", + "n-instances_many": "", + "n-instances_other": "" + }, + "new-child": "", + "new-policy": "", + "no-matchers": "", + "reload-policies": "", + "save-policy": "", + "update": { + "please-wait": "", + "update-policy": "", + "updating": "" + }, + "update-errors": { + "conflict": "", + "error-code": "", + "fallback": "", + "suffix": "", + "title": "" + }, + "n-more-policies_one": "", + "n-more-policies_few": "", + "n-more-policies_many": "", + "n-more-policies_other": "" + }, + "provisioning": { + "badge-tooltip-provenance": "", + "badge-tooltip-standard": "" + }, + "queryAndExpressionsStep": { + "disableAdvancedOptions": { + "text": "" + }, + "preview": "", + "previewCondition": "" + }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, + "rule-form": { + "evaluation": { + "evaluation-group-and-interval": "", + "group": { + "cancel": "", + "create": "", + "interval": "" + }, + "group-name": "", + "group-text": "", + "new-group": "", + "pause": { + "alerting": "", + "recording": "" + }, + "select-folder-before": "" + }, + "evaluation-behaviour": { + "description": { + "text": "" + }, + "info-help": { + "text": "" + }, + "pending-period": "" + }, + "evaluation-behaviour-description1": "", + "evaluation-behaviour-description2": "", + "evaluation-behaviour-description3": "", + "evaluation-behaviour-for": { + "error-parsing": "", + "validation": "" + }, + "folder": { + "cancel": "", + "create": "", + "create-folder": "", + "creating-new-folder": "", + "label": "", + "name": "", + "new-folder": "", + "new-folder-or": "" + }, + "folder-and-labels": "", + "folders": { + "help-info": "" + }, + "labels": { + "help-info": "" + }, + "pause": { + "label": "" + }, + "threshold": { + "recovery": { + "stop-alerting-above": "", + "stop-alerting-bellow": "", + "stop-alerting-equal": "", + "stop-alerting-inside-range": "", + "stop-alerting-less": "", + "stop-alerting-more": "", + "stop-alerting-not-equal": "", + "stop-alerting-outside-range": "", + "title": "" + } + } + }, + "rule-groups": { + "delete": { + "success": "" + }, + "move": { + "success": "" + }, + "rename": { + "success": "" + }, + "update": { + "success": "" + } + }, + "rule-list": { + "configure-datasource": "", + "ds-error-boundary": { + "description": "", + "title": "" + }, + "filter-view": { + "no-more-results": "", + "no-rules-found": "" + }, + "new-alert-rule": "", + "pagination": { + "next-page": "", + "previous-page": "" + }, + "return-button": { + "title": "" + }, + "rulerrule-loading-error": "" + }, + "rule-state": { + "creating": "", + "deleting": "", + "paused": "", + "recording-rule": "" + }, + "rule-view": { + "query": { + "datasources-na": { + "description": "", + "title": "" + } + } + }, + "rule-viewer": { + "error-loading": "", + "prometheus-consistency-check": { + "alert-message": "", + "alert-title": "" + } + }, + "rules": { + "add-rule": { + "success": "" + }, + "delete-rule": { + "success": "" + }, + "pause-rule": { + "success": "" + }, + "resume-rule": { + "success": "" + }, + "update-rule": { + "success": "" + } + }, + "search": { + "property": { + "data-source": "", + "evaluation-group": "", + "labels": "", + "namespace": "", + "rule-health": "", + "rule-name": "", + "rule-type": "", + "state": "" + }, + "save-query": "" + }, + "silences": { + "affected-instances": "", + "only-firing-instances": "", + "preview-affected-instances": "" + }, + "simpleCondition": { + "alertCondition": "" + }, + "templates": { + "editor": { + "add-example": "", + "auto-complete": "", + "goto-docs": "" + }, + "help": { + "intro": "" + }, + "misconfigured-badge-text": "", + "misconfigured-warning": "", + "misconfigured-warning-details": "" + }, + "threshold": { + "to": "" + } + }, + "annotations": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + } + }, + "api-keys": { + "empty-state": { + "message": "" + } + }, + "app-chrome": { + "skip-content-button": "", + "top-bar": { + "sign-in": "" + } + }, + "app-notification": { + "item": { + "trace-id": "" + } + }, + "bookmarks-page": { + "empty": { + "message": "", + "tip": "" + } + }, + "bouncing-loader": { + "label": "" + }, + "browse-dashboards": { + "action": { + "cancel-button": "", + "cannot-move-folders": "", + "confirmation-text": "", + "delete-button": "", + "delete-modal-invalid-text": "", + "delete-modal-invalid-title": "", + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "delete-modal-title": "", + "deleting": "", + "manage-permissions-button": "", + "move-button": "", + "move-modal-alert": "", + "move-modal-field-label": "", + "move-modal-text": "", + "move-modal-title": "", + "moving": "", + "new-folder-name-required-phrase": "" + }, + "actions": { + "button-to-recently-deleted": "" + }, + "counts": { + "alertRule_one": "", + "alertRule_few": "", + "alertRule_many": "", + "alertRule_other": "", + "dashboard_one": "", + "dashboard_few": "", + "dashboard_many": "", + "dashboard_other": "", + "folder_one": "", + "folder_few": "", + "folder_many": "", + "folder_other": "", + "libraryPanel_one": "", + "libraryPanel_few": "", + "libraryPanel_many": "", + "libraryPanel_other": "", + "total_one": "", + "total_few": "", + "total_many": "", + "total_other": "" + }, + "dashboards-tree": { + "collapse-folder-button": "", + "expand-folder-button": "", + "name-column": "", + "select-all-header-checkbox": "", + "select-checkbox": "", + "tags-column": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "", + "title-folder": "" + }, + "folder-actions-button": { + "delete": "", + "folder-actions": "", + "manage-permissions": "", + "move": "" + }, + "folder-picker": { + "accessible-label": "", + "button-label": "", + "clear-selection": "", + "empty-message": "", + "error-title": "", + "non-folder-item": "", + "search-placeholder": "", + "unknown-error": "" + }, + "hard-delete": { + "success": "" + }, + "manage-folder-nav": { + "alert-rules": "", + "dashboards": "", + "panels": "" + }, + "new-folder-form": { + "cancel-label": "", + "create-label": "", + "name-label": "" + }, + "no-results": { + "clear": "", + "text": "" + }, + "soft-delete": { + "success": "" + } + }, + "clipboard-button": { + "inline-toast": { + "success": "" + } + }, + "combobox": { + "async": { + "error": "" + }, + "clear": { + "title": "" + }, + "custom-value": { + "description": "" + }, + "group": { + "undefined": "" + }, + "options": { + "no-found": "" + } + }, + "command-palette": { + "action": { + "change-theme": "", + "dark-theme": "", + "light-theme": "" + }, + "empty-state": { + "message": "" + }, + "search-box": { + "placeholder": "" + }, + "section": { + "actions": "", + "dashboard-search-results": "", + "folder-search-results": "", + "pages": "", + "preferences": "", + "recent-dashboards": "" + } + }, + "common": { + "apply": "", + "cancel": "", + "clear": "", + "close": "", + "collapse": "", + "edit": "", + "help": "", + "loading": "", + "locale": { + "default": "" + }, + "save": "", + "search": "", + "view": "" + }, + "configuration-tracker": { + "config-card": { + "complete": "" + } + }, + "connections": { + "connect-data": { + "category-header-label": "", + "empty-message": "", + "request-data-source": "", + "roadmap": "" + }, + "search": { + "placeholder": "" + } + }, + "core": { + "versionHistory": { + "comparison": { + "header": { + "hide-json-diff": "", + "show-json-diff": "", + "text": "" + }, + "select": "" + }, + "no-properties-changed": "", + "table": { + "updated": "", + "updatedBy": "", + "version": "" + }, + "view-json-diff": "" + } + }, + "correlations": { + "add-new": "", + "alert": { + "error-message": "", + "title": "" + }, + "basic-info-form": { + "description-description": "", + "description-label": "", + "label-description": "", + "label-label": "", + "label-placeholder": "", + "label-required": "", + "sub-text": "", + "title": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + }, + "list": { + "delete": "", + "label": "", + "loading": "", + "read-only": "", + "source": "", + "target": "" + }, + "navigation-form": { + "add-button": "", + "back-button": "", + "next-button": "", + "save-button": "" + }, + "page-content": "", + "page-heading": "", + "query-editor": { + "control-rules": "", + "data-source-text": "", + "data-source-title": "", + "error-text": "", + "error-title": "", + "loading": "", + "query-description": "", + "query-editor-title": "", + "query-label": "" + }, + "source-form": { + "control-required": "", + "description": "", + "description-external-pre": "", + "description-query-pre": "", + "external-title": "", + "heading-external": "", + "heading-query": "", + "query-title": "", + "results-description": "", + "results-label": "", + "results-required": "", + "source-description": "", + "source-label": "", + "sub-text": "" + }, + "sub-title": "", + "target-form": { + "control-rules": "", + "sub-text": "", + "target-description-external": "", + "target-description-query": "", + "target-label": "", + "target-type-description": "", + "title": "", + "type-label": "" + }, + "trans-details": { + "logfmt-description": "", + "logfmt-label": "", + "regex-description": "", + "regex-expression": "", + "regex-label": "", + "regex-map-values": "" + }, + "transform": { + "add-button": "", + "heading": "", + "no-transform": "" + }, + "transform-row": { + "expression-label": "", + "expression-required": "", + "expression-tooltip": "", + "field-input": "", + "field-label": "", + "field-tooltip": "", + "map-value-label": "", + "map-value-tooltip": "", + "remove-button": "", + "remove-tooltip": "", + "transform-required": "", + "type-label": "", + "type-tooltip": "" + } + }, + "dashboard": { + "add-menu": { + "import": "", + "paste-panel": "", + "row": "", + "visualization": "" + }, + "alert-rules-drawer": { + "redirect-link": "", + "subtitle": "" + }, + "default-layout": { + "description": "", + "item-options": { + "repeat": { + "direction": { + "horizontal": "", + "title": "", + "vertical": "" + }, + "max": "", + "title": "", + "variable": { + "description": "", + "title": "" + } + } + }, + "name": "", + "row-actions": { + "delete": "", + "modal": { + "alt-action": "", + "text": "", + "title": "" + } + }, + "row-options": { + "button": { + "label": "" + }, + "form": { + "cancel": "", + "repeat-for": { + "label": "", + "learn-more": "", + "warning": { + "text": "" + } + }, + "title": "", + "update": "" + }, + "modal": { + "title": "" + }, + "repeat": { + "title": "", + "variable": { + "title": "" + } + }, + "title": "" + } + }, + "edit-pane": { + "elements": { + "dashboard": "", + "objects": "", + "panel": "", + "panels": "", + "row": "", + "rows": "", + "tab": "", + "tabs": "" + }, + "open": "", + "row": { + "header": { + "hide": "", + "title": "" + } + } + }, + "editpane": { + "add": "", + "configure": "", + "outline": "" + }, + "empty": { + "add-library-panel-body": "", + "add-library-panel-button": "", + "add-library-panel-header": "", + "add-visualization-body": "", + "add-visualization-button": "", + "add-visualization-header": "", + "import-a-dashboard-body": "", + "import-a-dashboard-header": "", + "import-dashboard-button": "" + }, + "errors": { + "failed-to-load": "" + }, + "inspect": { + "data-tab": "", + "error-tab": "", + "json-tab": "", + "meta-tab": "", + "query-tab": "", + "stats-tab": "", + "subtitle": "", + "title": "" + }, + "inspect-data": { + "data-options": "", + "dataframe-aria-label": "", + "dataframe-label": "", + "download-csv": "", + "download-excel-description": "", + "download-excel-label": "", + "download-logs": "", + "download-service": "", + "download-traces": "", + "excel-header": "", + "formatted": "", + "formatted-data-description": "", + "formatted-data-label": "", + "panel-transforms": "", + "series-to-columns": "", + "transformation": "", + "transformations-description": "", + "transformations-label": "" + }, + "inspect-json": { + "dataframe-description": "", + "dataframe-label": "", + "panel-data-description": "", + "panel-data-label": "", + "panel-json-description": "", + "panel-json-label": "", + "select-source": "", + "unknown": "" + }, + "inspect-meta": { + "no-inspector": "" + }, + "inspect-stats": { + "data-title": "", + "data-traceids": "", + "processing-time": "", + "queries": "", + "request-time": "", + "rows": "", + "table-title": "" + }, + "layout": { + "common": { + "copy": "", + "copy-or-duplicate": "", + "delete": "", + "duplicate": "", + "layout": "" + } + }, + "options": { + "description": "", + "title-option": "" + }, + "outline": { + "tree": { + "item": { + "collapse": "", + "empty": "", + "expand": "" + } + } + }, + "panel-edit": { + "alerting-tab": { + "dashboard-not-saved": "", + "no-rules": "" + } + }, + "responsive-layout": { + "description": "", + "item-options": { + "hide-no-data": "", + "repeat": { + "variable": { + "description": "", + "title": "" + } + }, + "title": "" + }, + "name": "", + "options": { + "columns": "", + "fixed": "", + "min": "", + "one-column": "", + "rows": "", + "three-columns": "", + "two-columns": "" + } + }, + "rows-layout": { + "description": "", + "name": "", + "option": { + "height": "", + "hide-header": "", + "repeat": "", + "title": "" + }, + "options": { + "height-expand": "", + "height-min": "" + }, + "row": { + "collapse": "", + "expand": "", + "menu": { + "add": "", + "add-panel": "", + "add-row-above": "", + "add-row-below": "", + "move-down": "", + "move-row": "", + "move-up": "" + }, + "new": "", + "repeat": { + "learn-more": "", + "warning": "" + } + }, + "row-options": { + "title-option": "" + } + }, + "tabs-layout": { + "description": "", + "menu": { + "move-tab": "" + }, + "name": "", + "tab": { + "menu": { + "add": "", + "add-panel": "", + "add-tab-above": "", + "add-tab-after": "", + "add-tab-before": "", + "move-left": "", + "move-right": "" + }, + "new": "" + }, + "tab-options": { + "title-option": "" + } + }, + "toolbar": { + "add": "", + "add-panel": "", + "add-panel-description": "", + "add-panel-lib": "", + "add-row": "", + "add-tab": "", + "alert-rules": "", + "back-to-dashboard": "", + "dashboard-settings": { + "label": "", + "tooltip": "" + }, + "discard-library-panel-changes": "", + "discard-panel": "", + "discard-panel-new": "", + "edit": { + "label": "", + "tooltip": "" + }, + "edit-dashboard-v2-schema": "", + "enter-edit-mode": { + "label": "", + "tooltip": "" + }, + "exit-edit-mode": { + "label": "", + "tooltip": "" + }, + "libray-panel-description": "", + "mark-favorite": "", + "more-save-options": "", + "open-original": "", + "playlist-next": "", + "playlist-previous": "", + "playlist-stop": "", + "public-dashboard": "", + "refresh": "", + "row-description": "", + "save": "", + "save-dashboard": { + "label": "", + "tooltip": "" + }, + "save-dashboard-copy": { + "label": "", + "tooltip": "" + }, + "save-dashboard-short": "", + "save-library-panel": "", + "settings": "", + "share": { + "label": "", + "tooltip": "" + }, + "share-button": "", + "show-hidden-elements": "", + "switch-old-dashboard": "", + "tabs-description": "", + "unlink-library-panel": "", + "unmark-favorite": "" + }, + "validation": { + "invalid-dashboard-id": "", + "invalid-json": "", + "tags-expected-array": "", + "tags-expected-strings": "" + }, + "viz-panel": { + "options": { + "description": "", + "open-edit": "", + "plugin-type-image": "", + "title-option": "", + "transparent-background": "" + } + } + }, + "dashboard-import": { + "file-dropzone": { + "primary-text": "", + "secondary-text": "" + }, + "form-actions": { + "cancel": "", + "load": "" + }, + "gcom-field": { + "label": "", + "load-button": "", + "placeholder": "", + "validation-required": "" + }, + "json-field": { + "label": "", + "validation-required": "" + } + }, + "dashboard-links": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "title": "" + } + }, + "dashboard-settings": { + "annotations": { + "title": "" + }, + "dashboard-delete-button": "", + "delete-modal": { + "confirmation-text": "", + "delete-button": "", + "title": "" + }, + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "general": { + "auto-refresh-description": "", + "auto-refresh-label": "", + "description-label": "", + "editable-description": "", + "editable-label": "", + "folder-label": "", + "panel-options-graph-tooltip-description": "", + "panel-options-graph-tooltip-label": "", + "panel-options-label": "", + "panels-preload-description": "", + "panels-preload-label": "", + "tags-label": "", + "title": "", + "title-label": "" + }, + "json-editor": { + "save-button": "", + "subtitle": "", + "title": "" + }, + "links": { + "title": "" + }, + "permissions": { + "title": "" + }, + "provisioned-delete-modal": { + "confirm-button": "", + "text-1": "", + "text-2": "", + "text-3": "", + "text-link": "", + "title": "" + }, + "settings": { + "title": "" + }, + "time-picker": { + "hide-time-picker": "", + "now-delay-description": "", + "now-delay-label": "", + "refresh-live-dashboards-description": "", + "refresh-live-dashboards-label": "", + "time-options-label": "", + "time-zone-label": "", + "week-start-label": "" + }, + "time-regions": { + "advanced-description-cron": "", + "advanced-description-rest": "", + "advanced-description-use": "", + "advanced-label": "" + }, + "variables": { + "title": "" + }, + "versions": { + "title": "" + } + }, + "dashboards": { + "panel-edit": { + "angular-deprecation-button-open-panel-json": "", + "angular-deprecation-description": "", + "angular-deprecation-heading": "" + }, + "panel-queries": { + "add-query-from-library": "" + }, + "settings": { + "variables": { + "dependencies": { + "button": "", + "title": "" + } + } + } + }, + "data-source-list": { + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + } + }, + "data-source-picker": { + "add-new-data-source": "", + "built-in-list": { + "description-dashboard": "", + "description-grafana": "", + "description-mixed": "" + }, + "list": { + "no-data-source-message": "" + }, + "modal": { + "configure-new-data-source": "", + "input-placeholder": "", + "title": "" + }, + "open-advanced-button": "" + }, + "data-source-testing-status-page": { + "error-more-details-link": "", + "success-more-details-links": "" + }, + "data-sources": { + "datasource-add-button": { + "label": "" + }, + "empty-state": { + "message": "" + } + }, + "embed": { + "share": { + "time-range-description": "", + "time-range-label": "" + } + }, + "empty-list-cta": { + "pro-tip": "" + }, + "entity-not-found": { + "description": "" + }, + "errors": { + "dashboard-settings": { + "annotations": { + "datasource": "" + } + } + }, + "explore": { + "add-to-dashboard": "", + "drilldownInfo": { + "action": "", + "description": "", + "title": "" + }, + "logs": { + "logs-volume": { + "add-filters": "", + "decrease-timerange": "", + "much-data": "" + }, + "maximum-pinned-logs": "", + "no-logs-found": "", + "scan-for-older-logs": "", + "stop-scan": "" + }, + "rich-history": { + "close-tooltip": "", + "datasource-a-z": "", + "datasource-z-a": "", + "newest-first": "", + "oldest-first": "", + "query-history": "", + "query-library": "", + "settings": "", + "starred": "" + }, + "rich-history-card": { + "add-comment-form": "", + "add-comment-tooltip": "", + "add-to-library": "", + "cancel": "", + "confirm-delete": "", + "copy-query-tooltip": "", + "copy-shortened-link-tooltip": "", + "datasource-icon-label": "", + "datasource-name-label": "", + "datasource-not-exist": "", + "delete-query-confirmation-title": "", + "delete-query-title": "", + "delete-query-tooltip": "", + "delete-starred-query-confirmation-text": "", + "edit-comment-tooltip": "", + "optional-description": "", + "query-comment-label": "", + "query-text-label": "", + "save-comment": "", + "star-query-tooltip": "", + "unstar-query-tooltip": "", + "update-comment-form": "" + }, + "rich-history-container": { + "loading": "" + }, + "rich-history-notification": { + "query-copied": "", + "query-deleted": "" + }, + "rich-history-queries-tab": { + "displaying-partial-queries": "", + "displaying-queries": "", + "filter-aria-label": "", + "filter-history": "", + "filter-placeholder": "", + "history-local": "", + "loading": "", + "loading-results": "", + "search-placeholder": "", + "showing-queries": "", + "sort-aria-label": "", + "sort-placeholder": "" + }, + "rich-history-settings-tab": { + "alert-info": "", + "change-default-tab": "", + "clear-history-info": "", + "clear-query-history": "", + "clear-query-history-button": "", + "delete-confirm": "", + "delete-confirm-text": "", + "delete-title": "", + "history-time-span": "", + "history-time-span-description": "", + "only-show-active-datasource": "", + "query-history-deleted": "", + "retention-period": { + "1-week": "", + "2-days": "", + "2-weeks": "", + "5-days": "" + } + }, + "rich-history-starred-tab": { + "filter-queries-aria-label": "", + "filter-queries-placeholder": "", + "loading": "", + "loading-results": "", + "local-history-message": "", + "search-queries-placeholder": "", + "showing-queries": "", + "sort-queries-aria-label": "", + "sort-queries-placeholder": "" + }, + "rich-history-utils": { + "a-week-ago": "", + "days-ago": "", + "default-from": "", + "default-to": "", + "today": "", + "two-weeks-ago": "", + "yesterday": "" + }, + "rich-history-utils-notification": { + "saving-failed": "", + "update-failed": "" + }, + "run-query": { + "left-pane": "", + "right-pane": "", + "run-query-button": "", + "switch-datasource-button": "" + }, + "secondary-actions": { + "add-from-query-library": "", + "query-add-button": "", + "query-add-button-aria-label": "", + "query-history-button": "", + "query-history-button-aria-label": "", + "query-inspector-button": "", + "query-inspector-button-aria-label": "" + }, + "table": { + "no-data": "", + "title": "", + "title-with-name": "" + }, + "toolbar": { + "add-to-extensions": "", + "add-to-queryless-extensions": "", + "aria-label": "", + "copy-link": "", + "copy-link-abs-time": "", + "copy-links-absolute-category": "", + "copy-links-normal-category": "", + "copy-shortened-link": "", + "copy-shortened-link-abs-time": "", + "copy-shortened-link-label": "", + "copy-shortened-link-menu": "", + "refresh-picker-cancel": "", + "refresh-picker-run": "", + "split-close": "", + "split-close-tooltip": "", + "split-narrow": "", + "split-title": "", + "split-tooltip": "", + "split-widen": "" + } + }, + "explore-metrics": { + "breakdown": { + "clearFilter": "", + "labelSelect": "", + "missing-otel-labels": "", + "noMatchingValue": "", + "sortBy": "" + }, + "related-logs": { + "LrrDocsLink": "", + "openExploreLogs": "", + "relatedLogsUnavailable": "", + "warnExperimentalFeature": "" + }, + "viewBy": "" + }, + "export": { + "json": { + "cancel-button": "", + "copy-button": "", + "download-button": "", + "download-successful_toast_message": "", + "export-externally-label": "", + "info-text": "", + "title": "" + }, + "menu": { + "export-as-json-label": "", + "export-as-json-tooltip": "" + } + }, + "folder-filter": { + "clear-folder-button": "" + }, + "folder-picker": { + "create-instructions": "", + "loading": "" + }, + "forgot-password": { + "back-button": "", + "change-password": { + "skip-button": "", + "submit-button": "" + }, + "contact-admin": "", + "email-sent": "", + "reset-password-header": "", + "send-email-button": "" + }, + "form-prompt": { + "continue-button": "", + "description": "", + "discard-button": "" + }, + "gen-ai": { + "apply-suggestion": "", + "incomplete-request-error": "", + "send-custom-feedback": "" + }, + "get-enterprise": { + "requires-license": "", + "title": "" + }, + "grafana-ui": { + "action-editor": { + "button": { + "confirm": "", + "confirm-action": "" + }, + "inline": { + "add-action": "", + "edit-action": "" + }, + "modal": { + "action-body": "", + "action-method": "", + "action-query-params": "", + "action-title": "", + "action-title-placeholder": "", + "one-click-description": "" + } + }, + "alert": { + "close-button": "" + }, + "auto-save-field": { + "saved": "", + "saving": "" + }, + "card": { + "option": "" + }, + "cascader": { + "clear-button": "" + }, + "color-picker-popover": { + "palette-tab": "", + "spectrum-tab": "" + }, + "confirm-button": { + "cancel": "" + }, + "confirm-content": { + "placeholder": "" + }, + "data-link-editor": { + "info": "", + "new-tab-label": "", + "title-label": "", + "title-placeholder": "", + "url-label": "" + }, + "data-link-editor-modal": { + "cancel": "", + "one-click-description": "", + "save": "" + }, + "data-link-inline-editor": { + "one-click": "" + }, + "data-links-inline-editor": { + "add-link": "", + "edit-link": "", + "one-click": "", + "one-click-enabled": "", + "title-not-provided": "", + "tooltip-edit": "", + "tooltip-remove": "", + "url-not-provided": "" + }, + "data-source-basic-auth-settings": { + "user-label": "", + "user-placeholder": "" + }, + "data-source-http-proxy-settings": { + "oauth-identity-label": "", + "oauth-identity-tooltip": "", + "skip-tls-verify-label": "", + "ts-client-auth-label": "", + "with-ca-cert-label": "", + "with-ca-cert-tooltip": "" + }, + "data-source-http-settings": { + "access-help": "", + "access-help-details": "", + "access-label": "", + "access-options-browser": "", + "access-options-proxy": "", + "allowed-cookies": "", + "allowed-cookies-tooltip": "", + "auth": "", + "azure-auth-label": "", + "azure-auth-tooltip": "", + "basic-auth": "", + "basic-auth-label": "", + "browser-mode-description": "", + "browser-mode-title": "", + "default-url-access-select": "", + "default-url-tooltip": "", + "direct-url-tooltip": "", + "heading": "", + "proxy-url-tooltip": "", + "server-mode-description": "", + "server-mode-title": "", + "timeout-form-label": "", + "timeout-label": "", + "timeout-tooltip": "", + "url-label": "", + "with-credential-label": "", + "with-credential-tooltip": "" + }, + "data-source-settings": { + "alerting-settings-heading": "", + "alerting-settings-label": "", + "alerting-settings-tooltip": "", + "cert-key-reset": "", + "custom-headers-add": "", + "custom-headers-header": "", + "custom-headers-header-placeholder": "", + "custom-headers-header-remove": "", + "custom-headers-header-value": "", + "custom-headers-title": "", + "secure-socks-heading": "", + "secure-socks-label": "", + "secure-socks-tooltip": "", + "tls-certification-label": "", + "tls-certification-placeholder": "", + "tls-client-certification-label": "", + "tls-client-key-label": "", + "tls-client-key-placeholder": "", + "tls-heading": "", + "tls-server-name-label": "", + "tls-tooltip": "" + }, + "date-time-picker": { + "apply": "", + "calendar-icon-label": "", + "cancel": "", + "next-label": "", + "previous-label": "", + "select-placeholder": "" + }, + "drawer": { + "close": "" + }, + "feature-badge": { + "experimental": "", + "new": "", + "preview": "", + "private-preview": "" + }, + "field-link-list": { + "external-links-heading": "" + }, + "file-dropzone": { + "cancel-upload": "", + "file-too-large": "" + }, + "filter-input": { + "clear": "" + }, + "modal": { + "close-tooltip": "" + }, + "named-colors-palette": { + "text-color-swatch": "", + "transparent-swatch": "" + }, + "page-toolbar": { + "go-back": "", + "search-dashboard-name": "", + "search-links": "", + "search-parent-folder": "" + }, + "pagination": { + "next-page": "", + "previous-page": "" + }, + "secret-form-field": { + "reset": "" + }, + "segment-async": { + "error": "", + "loading": "", + "no-options": "" + }, + "select": { + "default-create-label": "", + "no-options-label": "", + "placeholder": "" + }, + "series-color-picker-popover": { + "y-axis-usage": "" + }, + "spinner": { + "aria-label": "" + }, + "table": { + "copy": "", + "csv-counts": "", + "filter-popup-apply": "", + "filter-popup-cancel": "", + "filter-popup-clear": "", + "filter-popup-heading": "", + "no-values-label": "", + "pagination-summary": "" + }, + "tags-input": { + "add": "" + }, + "user-icon": { + "active-text": "" + }, + "value-pill": { + "remove-button": "" + }, + "viz-legend": { + "right-axis-indicator": "" + }, + "viz-tooltip": { + "actions-confirmation-input-placeholder": "", + "actions-confirmation-label": "", + "actions-confirmation-message": "", + "footer-add-annotation": "", + "footer-click-to-action": "", + "footer-click-to-navigate": "" + } + }, + "graph": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "", + "title": "" + } + }, + "help-modal": { + "column-headers": { + "description": "", + "keys": "" + }, + "shortcuts-category": { + "dashboard": "", + "focused-panel": "", + "global": "", + "time-range": "" + }, + "shortcuts-description": { + "change-theme": "", + "collapse-all-rows": "", + "copy-time-range": "", + "dashboard-settings": "", + "duplicate-panel": "", + "exit-edit/setting-views": "", + "expand-all-rows": "", + "go-to-dashboards": "", + "go-to-explore": "", + "go-to-home-dashboard": "", + "go-to-profile": "", + "make-time-range-permanent": "", + "move-time-range-back": "", + "move-time-range-forward": "", + "open-search": "", + "open-shared-modal": "", + "paste-time-range": "", + "refresh-all-panels": "", + "remove-panel": "", + "save-dashboard": "", + "show-all-shortcuts": "", + "toggle-active-mode": "", + "toggle-all-panel-legends": "", + "toggle-auto-fit": "", + "toggle-exemplars": "", + "toggle-graph-crosshair": "", + "toggle-kiosk": "", + "toggle-panel-edit": "", + "toggle-panel-fullscreen": "", + "toggle-panel-legend": "", + "zoom-out-time-range": "" + }, + "title": "" + }, + "help-wizard": { + "download-snapshot": "", + "github-comment": "", + "support-bundle": "", + "troubleshooting-help": "" + }, + "inspector": { + "query": { + "collapse-all": "", + "copy-to-clipboard": "", + "description": "", + "expand-all": "", + "no-data": "", + "refresh": "" + } + }, + "ldap-drawer": { + "attributes-section": { + "description": "", + "email-label": "", + "label": "", + "member-of-label": "", + "name-label": "", + "surname-label": "", + "username-label": "" + }, + "extra-security-section": { + "client-cert-label": "", + "client-cert-placeholder": "", + "client-cert-value-label": "", + "client-cert-value-placeholder": "", + "client-key-label": "", + "client-key-placeholder": "", + "client-key-value-label": "", + "client-key-value-placeholder": "", + "encryption-provider-base-64": "", + "encryption-provider-description": "", + "encryption-provider-file-path": "", + "encryption-provider-label": "", + "label": "", + "min-tls-version-description": "", + "min-tls-version-label": "", + "root-ca-cert-label": "", + "root-ca-cert-placeholder": "", + "root-ca-cert-value-label": "", + "root-ca-cert-value-placeholder": "", + "start-tls-description": "", + "start-tls-label": "", + "tls-ciphers-label": "", + "tls-ciphers-placeholder": "", + "use-ssl-description": "", + "use-ssl-label": "", + "use-ssl-tooltip": "" + }, + "group-mapping": { + "grafana-admin": { + "description": "", + "label": "" + }, + "group-dn": { + "description": "", + "label": "" + }, + "org-id": { + "description": "", + "label": "" + }, + "org-role": { + "label": "" + }, + "remove": { + "button": "" + } + }, + "group-mapping-section": { + "add": { + "button": "" + }, + "description": "", + "group-search-base-dns-label": "", + "group-search-base-dns-placeholder": "", + "group-search-filter-description": "", + "group-search-filter-label": "", + "group-search-filter-user-attribute-description": "", + "group-search-filter-user-attribute-label": "", + "label": "", + "skip-org-role-sync-description": "", + "skip-org-role-sync-label": "" + }, + "misc-section": { + "allow-sign-up-descrition": "", + "allow-sign-up-label": "", + "label": "", + "port-description": "", + "port-label": "", + "timeout-description": "", + "timeout-label": "" + }, + "title": "" + }, + "ldap-settings-page": { + "advanced-settings-section": { + "edit-button": "", + "subtitle": "", + "title": "" + }, + "alert": { + "discard-success": "", + "error-fetching": "", + "error-saving": "", + "error-validate-form": "", + "feature-flag-disabled": "", + "saved": "" + }, + "bind-dn": { + "description": "", + "label": "", + "placeholder": "" + }, + "bind-password": { + "label": "" + }, + "buttons-section": { + "disable-button": "", + "discard-button": "", + "save-and-enable-button": "", + "save-button": "" + }, + "documentation": "", + "host": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "login-form-alert": { + "description": "", + "title": "" + }, + "search_filter": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "search-base-dns": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "subtitle": "", + "title": "" + }, + "library-panel": { + "add-modal": { + "cancel": "", + "create": "", + "error": "", + "folder": "", + "folder-description": "", + "name": "" + }, + "add-widget": { + "title": "" + }, + "empty-state": { + "message": "", + "more-info": "" + } + }, + "library-panels": { + "empty-state": { + "message": "" + }, + "loading-panel-text": "", + "modal": { + "button-cancel": "", + "button-view-panel1": "", + "button-view-panel2": "", + "panel-not-linked": "", + "select-no-options-message": "", + "select-placeholder": "", + "title": "", + "body_one": "", + "body_few": "", + "body_many": "", + "body_other": "" + }, + "save": { + "error": "", + "success": "" + } + }, + "link": { + "share": { + "config-alert-description": "", + "config-alert-title": "", + "config-description": "", + "copy-link-button": "", + "copy-to-clipboard": "", + "short-url-label": "", + "time-range-description": "", + "time-range-label": "" + }, + "share-panel": { + "config-description": "", + "download-image": "", + "render-image": "", + "render-image-error": "", + "render-image-error-description": "" + } + }, + "lock-icon": "", + "login": { + "divider": { + "connecting-text": "" + }, + "error": { + "blocked": "", + "invalid-user-or-password": "", + "title": "", + "unknown": "" + }, + "forgot-password": "", + "form": { + "confirmation-code": "", + "confirmation-code-label": "", + "confirmation-code-placeholder": "", + "email-label": "", + "email-placeholder": "", + "email-required": "", + "name-label": "", + "name-placeholder": "", + "password-label": "", + "password-placeholder": "", + "password-required": "", + "submit-label": "", + "submit-loading-label": "", + "username-label": "", + "username-placeholder": "", + "username-required": "", + "verify-email-label": "", + "verify-email-loading-label": "" + }, + "layout": { + "update-password": "" + }, + "services": { + "sing-in-with-prefix": "" + }, + "signup": { + "button-label": "", + "new-to-question": "" + } + }, + "logs": { + "infinite-scroll": { + "end-of-range": "", + "load-more": "", + "load-newer": "", + "load-older": "", + "older-logs": "" + }, + "log-details": { + "fields": "", + "links": "", + "log-line": "", + "no-details": "" + }, + "log-line-menu": { + "copy-link": "", + "copy-log": "", + "icon-label": "", + "pin-to-outline": "", + "show-context": "", + "unpin-from-outline": "" + }, + "log-row-message": { + "ellipsis": "", + "more": "", + "see-details": "" + }, + "log-rows": { + "disable-popover": { + "confirm": "", + "message": "", + "title": "" + }, + "disable-popover-message": { + "shortcut": "" + } + }, + "logs-navigation": { + "newer-logs": "", + "older-logs": "", + "scroll-bottom": "", + "scroll-top": "", + "start-of-range": "" + }, + "popover-menu": { + "copy": "", + "disable-menu": "", + "line-contains": "", + "line-contains-not": "" + } + }, + "migrate-to-cloud": { + "build-snapshot": { + "description": "", + "title": "", + "when-complete": "" + }, + "building-snapshot": { + "description": "", + "description-eta": "", + "title": "" + }, + "can-i-move": { + "body": "", + "link-title": "", + "title": "" + }, + "connect-modal": { + "body-cloud-stack": "", + "body-get-started": "", + "body-sign-up": "", + "body-token": "", + "body-token-field": "", + "body-token-field-placeholder": "", + "body-token-instructions": "", + "body-view-stacks": "", + "cancel": "", + "connect": "", + "connecting": "", + "title": "", + "token-error-title": "", + "token-errors": { + "instance-request-error": "", + "instance-unreachable": "", + "migration-disabled": "", + "session-creation-failure": "", + "token-invalid": "", + "token-not-saved": "", + "token-request-error": "", + "token-validation-failure": "" + }, + "token-required-error": "" + }, + "cta": { + "button": "", + "header": "" + }, + "delete-migration-token-confirm": { + "body": "", + "confirm-button": "", + "error-title": "", + "title": "" + }, + "disconnect-modal": { + "body": "", + "cancel": "", + "disconnect": "", + "disconnecting": "", + "error": "", + "title": "" + }, + "get-started": { + "body": "", + "configure-pdc-link": "", + "link-title": "", + "step-1": "", + "step-2": "", + "step-3": "", + "step-4": "", + "step-5": "", + "title": "" + }, + "is-it-secure": { + "body": "", + "link-title": "", + "title": "" + }, + "migrate-to-this-stack": { + "body": "", + "link-title": "", + "title": "" + }, + "migrated-counts": { + "alert_rule_groups": "", + "alert_rules": "", + "contact_points": "", + "dashboards": "", + "datasources": "", + "folders": "", + "library_elements": "", + "mute_timings": "", + "notification_policies": "", + "notification_templates": "", + "plugins": "" + }, + "migration-token": { + "delete-button": "", + "delete-modal-body": "", + "delete-modal-cancel": "", + "delete-modal-confirm": "", + "delete-modal-deleting": "", + "delete-modal-title": "", + "error-body": "", + "error-title": "", + "generate-button": "", + "generate-button-loading": "", + "modal-close": "", + "modal-copy-and-close": "", + "modal-copy-button": "", + "modal-field-description": "", + "modal-field-label": "", + "modal-title": "", + "status": "" + }, + "onprem": { + "cancel-snapshot-error-title": "", + "create-snapshot-error-title": "", + "disconnect-error-title": "", + "error-see-server-logs": "", + "get-session-error-title": "", + "get-snapshot-error-title": "", + "migration-finished-with-caveat-title": "", + "migration-finished-with-errors-body": "", + "migration-finished-with-warnings-body": "", + "snapshot-error-status-body": "", + "snapshot-error-status-title": "", + "success-message": "", + "success-message-generic": "", + "success-title": "", + "upload-snapshot-error-title": "" + }, + "pdc": { + "body": "", + "link-title": "", + "title": "" + }, + "pricing": { + "body": "", + "link-title": "", + "title": "" + }, + "public-preview": { + "button-text": "", + "message": "", + "message-cloud": "", + "title": "" + }, + "resource-details": { + "dismiss-button": "", + "error-messages": { + "dashboard-already-managed": "", + "datasource-already-managed": "", + "datasource-invalid-url": "", + "datasource-name-conflict": "", + "folder-name-conflict": "", + "generic-error": "", + "internal-service-error": "", + "library-element-name-conflict": "", + "resource-conflict": "", + "unexpected-error": "", + "unsupported-data-type": "" + }, + "error-title": "", + "generic-title": "", + "missing-message": "", + "resource-summary": "", + "title": "", + "warning-title": "" + }, + "resource-status": { + "error-details-button": "", + "failed": "", + "migrated": "", + "migrating": "", + "not-migrated": "", + "unknown": "", + "warning": "", + "warning-details-button": "" + }, + "resource-table": { + "dashboard-load-error": "", + "error-library-element-sub": "", + "error-library-element-title": "", + "unknown-datasource-title": "", + "unknown-datasource-type": "" + }, + "resource-type": { + "alert_rule": "", + "alert_rule_group": "", + "contact_point": "", + "dashboard": "", + "datasource": "", + "folder": "", + "library_element": "", + "mute_timing": "", + "notification_policy": "", + "notification_template": "", + "plugin": "", + "unknown": "" + }, + "summary": { + "cancel-snapshot": "", + "disconnect": "", + "errored-resource-count": "", + "page-loading": "", + "rebuild-snapshot": "", + "snapshot-date": "", + "snapshot-not-created": "", + "start-migration": "", + "successful-resource-count": "", + "target-stack-title": "", + "total-resource-count": "", + "upload-migration": "" + }, + "support-types-disclosure": { + "text": "" + }, + "token-status": { + "active": "", + "no-active": "", + "unknown": "", + "unknown-error": "" + }, + "what-is-cloud": { + "body": "", + "link-title": "", + "title": "" + }, + "why-host": { + "body": "", + "link-title": "", + "title": "" + } + }, + "multicombobox": { + "all": { + "title": "", + "title-filtered": "" + }, + "clear": { + "title": "" + } + }, + "nav": { + "add-new-connections": { + "title": "" + }, + "admin": { + "subtitle": "", + "title": "" + }, + "alert-list-legacy": { + "title": "" + }, + "alerting": { + "subtitle": "", + "title": "" + }, + "alerting-admin": { + "subtitle": "", + "title": "" + }, + "alerting-am-routes": { + "subtitle": "", + "title": "" + }, + "alerting-channels": { + "title": "" + }, + "alerting-groups": { + "subtitle": "", + "title": "" + }, + "alerting-home": { + "title": "" + }, + "alerting-legacy": { + "title": "" + }, + "alerting-list": { + "subtitle": "", + "title": "" + }, + "alerting-receivers": { + "subtitle": "", + "title": "" + }, + "alerting-silences": { + "subtitle": "", + "title": "" + }, + "alerting-upgrade": { + "subtitle": "", + "title": "" + }, + "alerts-and-incidents": { + "subtitle": "", + "title": "" + }, + "api-keys": { + "subtitle": "", + "title": "" + }, + "application": { + "title": "" + }, + "apps": { + "subtitle": "", + "title": "" + }, + "authentication": { + "title": "" + }, + "bookmarks": { + "title": "" + }, + "bookmarks-empty": { + "title": "" + }, + "collector": { + "title": "" + }, + "config": { + "title": "" + }, + "config-access": { + "subtitle": "", + "title": "" + }, + "config-general": { + "subtitle": "", + "title": "" + }, + "config-plugins": { + "subtitle": "", + "title": "" + }, + "connect-data": { + "title": "" + }, + "connections": { + "subtitle": "", + "title": "" + }, + "correlations": { + "subtitle": "", + "title": "" + }, + "create": { + "title": "" + }, + "create-alert": { + "title": "" + }, + "create-dashboard": { + "title": "" + }, + "create-folder": { + "title": "" + }, + "create-import": { + "title": "" + }, + "dashboards": { + "subtitle": "", + "title": "" + }, + "data-sources": { + "subtitle": "", + "title": "" + }, + "databases": { + "title": "" + }, + "datasources": { + "subtitle": "", + "title": "" + }, + "detect": { + "title": "" + }, + "drilldown": { + "title": "" + }, + "explore": { + "title": "" + }, + "frontend": { + "subtitle": "", + "title": "" + }, + "frontend-app": { + "title": "" + }, + "global-orgs": { + "subtitle": "", + "title": "" + }, + "global-users": { + "subtitle": "", + "title": "" + }, + "grafana-quaderno": { + "title": "" + }, + "groupsync": { + "subtitle": "" + }, + "help": { + "title": "" + }, + "help/community": "", + "help/documentation": "", + "help/keyboard-shortcuts": "", + "help/support": "", + "history-container": { + "drawer-tittle": "" + }, + "history-wrapper": { + "collapse": "", + "expand": "", + "icon-selected": "", + "icon-unselected": "", + "show-more": "", + "today": "", + "yesterday": "" + }, + "home": { + "title": "" + }, + "incidents": { + "title": "" + }, + "infrastructure": { + "subtitle": "", + "title": "" + }, + "integrations": { + "title": "" + }, + "k6": { + "title": "" + }, + "kubernetes": { + "title": "" + }, + "library-panels": { + "subtitle": "", + "title": "" + }, + "machine-learning": { + "title": "" + }, + "manage-folder": { + "subtitle": "" + }, + "migrate-to-cloud": { + "subtitle": "", + "title": "" + }, + "monitoring": { + "subtitle": "", + "title": "" + }, + "new": { + "title": "" + }, + "new-dashboard": { + "title": "" + }, + "new-folder": { + "title": "" + }, + "oncall": { + "title": "" + }, + "org-settings": { + "subtitle": "", + "title": "" + }, + "playlists": { + "subtitle": "", + "title": "" + }, + "plugins": { + "subtitle": "", + "title": "" + }, + "private-data-source-connections": { + "subtitle": "", + "title": "" + }, + "profile/notifications": { + "title": "" + }, + "profile/password": { + "title": "" + }, + "profile/settings": { + "title": "" + }, + "profiles": { + "title": "" + }, + "public": { + "title": "" + }, + "recently-deleted": { + "subtitle": "", + "title": "" + }, + "recorded-queries": { + "title": "" + }, + "reporting": { + "title": "" + }, + "scenes": { + "title": "" + }, + "search": { + "placeholderCommandPalette": "" + }, + "search-dashboards": { + "title": "" + }, + "server-settings": { + "subtitle": "", + "title": "" + }, + "service-accounts": { + "subtitle": "", + "title": "" + }, + "setup-guide": { + "title": "" + }, + "shared-dashboard": { + "subtitle": "", + "title": "" + }, + "sign-out": { + "title": "" + }, + "slo": { + "title": "" + }, + "snapshots": { + "subtitle": "", + "title": "" + }, + "starred": { + "title": "" + }, + "starred-empty": { + "title": "" + }, + "statistics-and-licensing": { + "title": "" + }, + "storage": { + "subtitle": "", + "title": "" + }, + "support-bundles": { + "subtitle": "", + "title": "" + }, + "synthetics": { + "title": "" + }, + "teams": { + "subtitle": "", + "title": "" + }, + "testing-and-synthetics": { + "subtitle": "", + "title": "" + }, + "upgrading": { + "title": "" + }, + "users": { + "subtitle": "", + "title": "" + } + }, + "navigation": { + "invite-user": { + "invite-button": "", + "invite-tooltip": "" + }, + "item": { + "add-bookmark": "", + "remove-bookmark": "" + }, + "kiosk": { + "tv-alert": "" + }, + "megamenu": { + "close": "", + "dock": "", + "list-label": "", + "open": "", + "undock": "" + }, + "rss-button": "" + }, + "news": { + "drawer": { + "close": "" + }, + "title": "" + }, + "notifications": { + "empty-state": { + "description": "", + "title": "" + }, + "starred-dashboard": "", + "unstarred-dashboard": "" + }, + "oauth": { + "form": { + "server-discovery-action-button": "", + "server-discovery-modal-close": "", + "server-discovery-modal-loading": "", + "server-discovery-modal-submit": "" + }, + "login": { + "error": "" + } + }, + "panel": { + "header-menu": { + "copy": "", + "create-library-panel": "", + "duplicate": "", + "edit": "", + "explore": "", + "get-help": "", + "hide-legend": "", + "inspect": "", + "inspect-data": "", + "inspect-json": "", + "more": "", + "new-alert-rule": "", + "query": "", + "remove": "", + "replace-library-panel": "", + "share": "", + "show-legend": "", + "unlink-library-panel": "", + "view": "" + } + }, + "panel-search": { + "no-matches": "", + "unsupported-layout": "" + }, + "panel-type-filter": { + "clear-button": "" + }, + "playlist-edit": { + "error-prefix": "", + "form": { + "add-tag-label": "", + "add-tag-placeholder": "", + "add-title-label": "", + "cancel": "", + "heading": "", + "interval-label": "", + "interval-placeholder": "", + "interval-required": "", + "name-label": "", + "name-placeholder": "", + "name-required": "", + "save": "", + "table-delete": "", + "table-drag": "", + "table-empty": "", + "table-heading": "" + }, + "sub-title": "", + "title": "" + }, + "playlist-page": { + "card": { + "delete": "", + "edit": "", + "start": "", + "tooltip": "" + }, + "create-button": { + "title": "" + }, + "delete-modal": { + "body": "", + "confirm-text": "" + }, + "empty": { + "button": "", + "pro-tip": "", + "title": "" + } + }, + "playlists": { + "empty-state": { + "message": "" + } + }, + "plugins": { + "catalog": { + "no-updates-available": "", + "update-all": { + "all-plugins-updated": "", + "available-header": "", + "button": "", + "cloud-update-message": "", + "error": "", + "error-status-text": "", + "header": "", + "installed-header": "", + "modal-confirmation": "", + "modal-dismiss": "", + "modal-in-progress": "", + "modal-title": "", + "name-header": "", + "update-header": "", + "update-status-text": "" + }, + "versions": { + "confirmation-text-1": "", + "confirmation-text-2": "", + "downgrade-confirm": "", + "downgrade-title": "" + } + }, + "details": { + "connections-tab": { + "description": "" + }, + "labels": { + "contactGrafanaLabs": "", + "customLinks": "", + "customLinksTooltip": "", + "dependencies": "", + "documentation": "", + "downloads": "", + "from": "", + "installedVersion": "", + "lastCommitDate": "", + "latestVersion": "", + "license": "", + "raiseAnIssue": "", + "reportAbuse": "", + "reportAbuseTooltip": "", + "repository": "", + "signature": "", + "status": "", + "updatedAt": "" + }, + "modal": { + "cancel": "", + "copyEmail": "", + "description": "", + "node": "", + "title": "" + } + }, + "empty-state": { + "message": "" + }, + "filter": { + "disabled": "", + "sort": "", + "sort-list": "", + "state": "" + }, + "plugin-help": { + "error": "", + "not-found": "" + } + }, + "profile": { + "change-password": { + "cancel-button": "", + "cannot-change-password-message": "", + "change-password-button": "", + "confirm-password-label": "", + "confirm-password-required": "", + "ldap-auth-proxy-message": "", + "new-password-label": "", + "new-password-required": "", + "new-password-same-as-old": "", + "old-password-label": "", + "old-password-required": "", + "passwords-must-match": "", + "strong-password-validation-register": "" + } + }, + "public-dashboard": { + "acknowledgment-checkboxes": { + "ack-title": "", + "data-src-ack-desc": "", + "data-src-ack-tooltip": "", + "public-ack-desc": "", + "public-ack-tooltip": "", + "usage-ack-desc": "", + "usage-ack-desc-tooltip": "" + }, + "config": { + "can-view-dashboard-radio-button-label": "", + "copy-button": "", + "dashboard-url-field-label": "", + "email-share-type-option-label": "", + "pause-sharing-dashboard-label": "", + "public-share-type-option-label": "", + "revoke-public-URL-button": "", + "revoke-public-URL-button-title": "", + "settings-title": "" + }, + "configuration": { + "display-annotations-description": "", + "display-annotations-label": "", + "enable-time-range-description": "", + "enable-time-range-label": "", + "settings-label": "", + "success-pause": "", + "success-resume": "", + "success-update": "", + "success-update-old": "", + "time-range-label": "", + "time-range-tooltip": "" + }, + "create-page": { + "generate-public-url-button": "", + "unsupported-features-desc": "", + "welcome-title": "" + }, + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "email-sharing": { + "accept-button": "", + "alert-text": "", + "bill-ack": "", + "cancel-button": "", + "input-invalid-email-text": "", + "input-required-email-text": "", + "invite-button": "", + "invite-field-desc": "", + "invite-field-label": "", + "learn-more-button": "", + "recipient-email-placeholder": "", + "recipient-invalid-email-text": "", + "recipient-invitation-button": "", + "recipient-invitation-description": "", + "recipient-invitation-tooltip": "", + "recipient-list-description": "", + "recipient-list-title": "", + "recipient-required-email-text": "", + "resend-button": "", + "resend-button-title": "", + "resend-invite-label": "", + "revoke-access-label": "", + "revoke-button": "", + "revoke-button-title": "", + "success-creation": "", + "success-share-type-change": "" + }, + "modal-alerts": { + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "save-dashboard-changes-alert-title": "", + "unsupport-data-source-alert-readmore-link": "", + "unsupported-data-source-alert-desc": "", + "unsupported-data-source-alert-title": "", + "unsupported-template-variable-alert-desc": "", + "unsupported-template-variable-alert-title": "" + }, + "public-sharing": { + "accept-button": "", + "alert-text": "", + "cancel-button": "", + "learn-more-button": "", + "public-ack": "", + "success-creation": "", + "success-share-type-change": "" + }, + "settings-bar-header": { + "collapse-settings-tooltip": "", + "expand-settings-tooltip": "" + }, + "settings-configuration": { + "default-time-range-label": "", + "default-time-range-label-desc": "", + "show-annotations-label": "", + "show-annotations-label-desc": "", + "time-range-picker-label": "", + "time-range-picker-label-desc": "" + }, + "settings-summary": { + "annotations-hide-text": "", + "annotations-show-text": "", + "time-range-picker-disabled-text": "", + "time-range-picker-enabled-text": "", + "time-range-text": "" + }, + "share": { + "success-delete": "", + "success-delete-old": "" + }, + "share-configuration": { + "share-type-label": "" + }, + "share-externally": { + "copy-link-button": "", + "email-share-type-option-description": "", + "email-share-type-option-label": "", + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "pause-access-button": "", + "pause-access-tooltip": "", + "public-share-type-option-description": "", + "public-share-type-option-label": "", + "resume-access-button": "", + "revoke-access-button": "", + "revoke-access-description": "", + "unsupported-data-source-alert-desc": "" + }, + "sharing": { + "success-creation": "" + } + }, + "public-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "public-dashboard-users-access-list": { + "dashboard-modal": { + "external-link": "", + "loading-text": "", + "open-dashboard-list-text": "", + "public-dashboard-link": "", + "public-dashboard-setting": "", + "sharing-setting": "" + }, + "delete-user-modal": { + "delete-user-button-text": "", + "delete-user-cancel-button": "", + "delete-user-revoke-access-button": "", + "revoke-access-title": "", + "revoke-user-access-modal-desc-line1": "", + "revoke-user-access-modal-desc-line2": "" + }, + "delete-user-shared-dashboards-modal": { + "revoke-user-access-modal-desc-line2": "" + }, + "modal": { + "dashboard-modal-title": "", + "shared-dashboard-modal-title": "" + }, + "table-body": { + "dashboard-count_one": "", + "dashboard-count_few": "", + "dashboard-count_many": "", + "dashboard-count_other": "" + }, + "table-header": { + "activated-label": "", + "activated-tooltip": "", + "email-label": "", + "last-active-label": "", + "origin-label": "", + "role-label": "" + } + }, + "query-operation": { + "header": { + "collapse-row": "", + "datasource-help": "", + "drag-and-drop": "", + "duplicate-query": "", + "expand-row": "", + "hide-response": "", + "remove-query": "", + "show-response": "", + "toggle-edit-mode": "" + }, + "query-editor-not-exported": "" + }, + "recently-deleted": { + "buttons": { + "delete": "", + "restore": "" + }, + "page": { + "no-deleted-dashboards": "", + "no-deleted-dashboards-text": "", + "no-search-result": "" + }, + "permanently-delete-modal": { + "confirm-text": "", + "delete-button": "", + "delete-loading": "", + "title": "", + "text_one": "", + "text_few": "", + "text_many": "", + "text_other": "" + }, + "restore-modal": { + "restore-button": "", + "restore-loading": "", + "title": "", + "folder-picker-text_one": "", + "folder-picker-text_few": "", + "folder-picker-text_many": "", + "folder-picker-text_other": "", + "text_one": "", + "text_few": "", + "text_many": "", + "text_other": "" + } + }, + "recentlyDeleted": { + "filter": { + "placeholder": "" + } + }, + "reduce": { + "strictMode": { + "description": "", + "title": "" + } + }, + "refresh-picker": { + "aria-label": { + "choose-interval": "", + "duration-selected": "" + }, + "auto-option": { + "aria-label": "", + "label": "" + }, + "live-option": { + "aria-label": "", + "label": "" + }, + "off-option": { + "aria-label": "", + "label": "" + }, + "tooltip": { + "interval-selected": "", + "turned-off": "" + } + }, + "return-to-previous": { + "button": { + "label": "" + }, + "dismissable-button": "" + }, + "role-picker": { + "built-in": { + "basic-roles": "" + }, + "input": { + "no-roles": "" + }, + "menu": { + "clear-button": "", + "tooltip": "" + }, + "sub-menu": { + "clear-button": "" + }, + "title": { + "description": "" + } + }, + "role-picker-drawer": { + "basic-roles": { + "label": "" + } + }, + "route-error": { + "description": "", + "reload-button": "", + "title": "" + }, + "save-dashboards": { + "message-length": { + "info": "", + "title": "" + }, + "name-exists": { + "message-info": "", + "message-suggestion": "", + "title": "" + } + }, + "scopes": { + "dashboards": { + "collapse": "", + "expand": "", + "loading": "", + "noResultsForFilter": "", + "noResultsForFilterClear": "", + "noResultsForScopes": "", + "noResultsNoScopes": "", + "search": "", + "toggle": { + "collapse": "", + "disabled": "", + "expand": "" + } + }, + "selector": { + "apply": "", + "cancel": "", + "input": { + "placeholder": "", + "removeAll": "" + }, + "title": "" + }, + "tree": { + "collapse": "", + "expand": "", + "headline": { + "noResults": "", + "recommended": "", + "results": "" + }, + "search": "" + } + }, + "search": { + "actions": { + "include-panels": "", + "remove-datasource-filter": "", + "sort-placeholder": "", + "starred": "", + "view-as-folders": "", + "view-as-list": "" + }, + "dashboard-actions": { + "import": "", + "new": "", + "new-dashboard": "", + "new-folder": "" + }, + "results-table": { + "datasource-header": "", + "deleted-less-than-1-min": "", + "deleted-remaining-header": "", + "location-header": "", + "name-header": "", + "tags-header": "", + "type-dashboard": "", + "type-folder": "", + "type-header": "" + }, + "search-input": { + "include-panels-placeholder": "", + "placeholder": "" + } + }, + "select": { + "select-menu": { + "selected-count": "" + } + }, + "service-account-create-page": { + "create": { + "button": "" + }, + "name": { + "label": "", + "required-error": "" + }, + "page-nav": { + "label": "" + }, + "role": { + "label": "" + } + }, + "service-accounts": { + "empty-state": { + "button-title": "", + "message": "", + "more-info": "", + "title": "" + } + }, + "share-dashboard": { + "menu": { + "export-json-title": "", + "share-externally-title": "", + "share-internally-title": "", + "share-snapshot-title": "" + }, + "share-button": "", + "share-button-tooltip": "" + }, + "share-drawer": { + "confirm-action": { + "back-arrow-button": "", + "cancel-button": "" + } + }, + "share-modal": { + "dashboard": { + "title": "" + }, + "embed": { + "copy": "", + "html": "", + "html-description": "", + "info": "", + "time-range": "" + }, + "export": { + "back-button": "", + "cancel-button": "", + "info-text": "", + "loading": "", + "save-button": "", + "share-externally-label": "", + "view-button": "" + }, + "library": { + "info": "" + }, + "link": { + "copy-link-button": "", + "info-text": "", + "link-url": "", + "render-alert": "", + "render-instructions": "", + "rendered-image": "", + "save-alert": "", + "save-dashboard": "", + "shorten-url": "", + "time-range-description": "", + "time-range-label": "" + }, + "panel": { + "title": "" + }, + "snapshot": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "deleted-message": "", + "expire": "", + "expire-day": "", + "expire-hour": "", + "expire-never": "", + "expire-week": "", + "info-text-1": "", + "info-text-2": "", + "local-button": "", + "mistake-message": "", + "name": "", + "timeout": "", + "timeout-description": "", + "url-label": "" + }, + "tab-title": { + "embed": "", + "export": "", + "library-panel": "", + "link": "", + "panel-embed": "", + "public-dashboard": "", + "public-dashboard-title": "", + "snapshot": "" + }, + "theme-picker": { + "current": "", + "dark": "", + "field-name": "", + "light": "" + }, + "view-json": { + "copy-button": "" + } + }, + "share-panel": { + "drawer": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "" + }, + "menu": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "", + "share-snapshot-title": "" + }, + "new-library-panel": { + "cancel-button": "", + "create-button": "" + } + }, + "share-panel-image": { + "preview": { + "title": "" + }, + "settings": { + "height-label": "", + "height-min": "", + "height-placeholder": "", + "height-required": "", + "max-warning": "", + "scale-factor-label": "", + "scale-factor-min": "", + "scale-factor-placeholder": "", + "scale-factor-required": "", + "title": "", + "width-label": "", + "width-min": "", + "width-placeholder": "", + "width-required": "" + } + }, + "share-playlist": { + "checkbox-description": "", + "checkbox-label": "", + "copy-link-button": "", + "link-url-label": "", + "mode": "", + "mode-kiosk": "", + "mode-normal": "", + "title": "" + }, + "shared": { + "preferences": { + "theme": { + "dark-label": "", + "light-label": "", + "system-label": "" + } + } + }, + "shared-dashboard": { + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "fields": { + "timezone-label": "" + } + }, + "shared-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "shared-preferences": { + "fields": { + "home-dashboard-label": "", + "home-dashboard-placeholder": "", + "locale-label": "", + "locale-placeholder": "", + "theme-description": "", + "theme-label": "", + "week-start-label": "" + }, + "theme": { + "default-label": "" + }, + "title": "" + }, + "sign-up": { + "back-button": "", + "submit-button": "", + "verify": { + "back-button": "", + "complete-button": "", + "header": "", + "info": "", + "send-button": "" + } + }, + "silences": { + "empty-state": { + "button-title": "", + "title": "" + }, + "table": { + "add-silence-button": "", + "edit-button": "", + "expired-silences": "", + "no-matching-silences": "", + "noConfig": "", + "recreate-button": "", + "unsilence-button": "" + } + }, + "silences-table": { + "header": { + "alert-name": "", + "state": "" + } + }, + "snapshot": { + "empty-state": { + "message": "", + "more-info": "" + }, + "external-badge": "", + "name-column-header": "", + "share": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "delete-description": "", + "delete-permission-tooltip": "", + "delete-title": "", + "deleted-alert": "", + "expiration-label": "", + "info-alert": "", + "learn-more-button": "", + "local-button": "", + "name-label": "", + "new-snapshot-button": "", + "success-creation": "", + "success-delete": "", + "view-all-button": "" + }, + "share-panel": { + "info-alert": "" + }, + "url-column-header": "", + "view-button": "" + }, + "table": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "" + } + }, + "tag-filter": { + "clear-button": "", + "loading": "", + "no-tags": "", + "placeholder": "" + }, + "teams": { + "empty-state": { + "button-title": "", + "message": "", + "pro-tip": "", + "title": "" + } + }, + "theme-preview": { + "breadcrumbs": { + "dashboards": "", + "home": "" + }, + "panel": { + "form-label": "", + "title": "" + } + }, + "time-picker": { + "absolute": { + "recent-title": "", + "title": "" + }, + "calendar": { + "apply-button": "", + "cancel-button": "", + "close": "", + "next-month": "", + "previous-month": "", + "select-time": "" + }, + "content": { + "empty-recent-list-docs": "", + "empty-recent-list-info": "", + "filter-placeholder": "" + }, + "copy-paste": { + "copy-success-message": "", + "default-error-message": "", + "default-error-title": "", + "tooltip-copy": "", + "tooltip-paste": "" + }, + "footer": { + "change-settings-button": "", + "fiscal-year-option": "", + "fiscal-year-start": "", + "time-zone-option": "", + "time-zone-selection": "" + }, + "range-content": { + "apply-button": "", + "default-error": "", + "fiscal-year": "", + "from-input": "", + "open-input-calendar": "", + "range-error": "", + "to-input": "" + }, + "range-picker": { + "backwards-time-aria-label": "", + "current-time-selected": "", + "forwards-time-aria-label": "", + "to": "", + "zoom-out-button": "", + "zoom-out-tooltip": "" + }, + "time-range": { + "apply": "", + "aria-role": "", + "default-title": "", + "example": "", + "example-details": "", + "example-title": "", + "from-label": "", + "from-to": "", + "more-info": "", + "specify": "", + "submit-button-label": "", + "supported-formats": "", + "to-label": "" + }, + "zone": { + "select-aria-label": "", + "select-search-input": "" + } + }, + "trails": { + "bookmarks": { + "or-view-bookmarks": "" + }, + "card": { + "date-created": "" + }, + "home": { + "learn-more": "", + "lets-start": "", + "start-your-metrics-exploration": "", + "subtitle": "" + }, + "metric-select": { + "filter-by": "", + "native-histogram": "", + "new-badge": "", + "otel-switch": "" + }, + "native-histogram-banner": { + "ch-heatmap": "", + "ch-histogram": "", + "click-histogram": "", + "hide-examples": "", + "learn-more": "", + "metric-examples": "", + "nh-heatmap": "", + "nh-histogram": "", + "now": "", + "previously": "", + "see-examples": "", + "sentence": "" + }, + "recent-metrics": { + "or-view-a-recent-exploration": "" + }, + "settings": { + "always-keep-selected-metric-graph-in-view": "", + "show-previews-of-metric-graphs": "" + } + }, + "transformations": { + "empty": { + "add-transformation-body": "", + "add-transformation-header": "" + } + }, + "upgrade-box": { + "discovery-text": "", + "discovery-text-continued": "", + "get-started": "", + "learn-more": "", + "upgrade-button": "" + }, + "user-orgs": { + "current-org-button": "", + "name-column": "", + "role-column": "", + "select-org-button": "", + "title": "" + }, + "user-profile": { + "fields": { + "email-error": "", + "email-label": "", + "name-error": "", + "name-label": "", + "username-label": "" + }, + "tabs": { + "general": "" + } + }, + "user-session": { + "auth-module-column": "", + "browser-column": "", + "created-at-column": "", + "identity-provider-column": "", + "ip-column": "", + "revoke": "", + "seen-at-column": "" + }, + "user-sessions": { + "loading": "" + }, + "users": { + "empty-state": { + "message": "" + } + }, + "users-access-list": { + "tabs": { + "public-dashboard-users-tab-title": "", + "shared-dashboard-users-tab-title": "" + } + }, + "variable": { + "adhoc": { + "placeholder": "" + }, + "dropdown": { + "placeholder": "" + }, + "picker": { + "link-all": "", + "option-all": "", + "option-selected-values": "", + "option-tooltip": "" + }, + "textbox": { + "placeholder": "" + } + }, + "variables": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + }, + "unknown-table": { + "loading": "", + "no-unknowns": "", + "renamed-or-missing-variables": "", + "variable": "" + } + } +} \ No newline at end of file diff --git a/public/locales/pt-BR/grafana.json b/public/locales/pt-BR/grafana.json index 9ba375ffcb2..3a29acad057 100644 --- a/public/locales/pt-BR/grafana.json +++ b/public/locales/pt-BR/grafana.json @@ -184,7 +184,8 @@ "rule-identifier": "", "rule-type": "", "state-error-timeout": "", - "state-no-data": "" + "state-no-data": "", + "target-datasource-uid": "" }, "alert-recording-rule-form": { "evaluation-behaviour": { @@ -504,6 +505,10 @@ "preview": "", "previewCondition": "" }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, "rule-form": { "evaluation": { "evaluation-group-and-interval": "", @@ -1068,23 +1073,18 @@ "elements": { "dashboard": "", "objects": "", + "panel": "", "panels": "", + "row": "", "rows": "", + "tab": "", "tabs": "" }, - "objects": { - "multi-select": { - "selection-number": "" - } - }, "open": "", "row": { "header": { "hide": "", "title": "" - }, - "multi-select": { - "title": "" } } }, @@ -1165,13 +1165,11 @@ "copy-or-duplicate": "", "delete": "", "duplicate": "", - "layout": "", - "panels-title": "" + "layout": "" } }, "options": { "description": "", - "title": "", "title-option": "" }, "outline": { @@ -1214,7 +1212,6 @@ }, "rows-layout": { "description": "", - "item-name": "", "name": "", "option": { "height": "", @@ -1253,9 +1250,6 @@ "menu": { "move-tab": "" }, - "multi-select": { - "title": "" - }, "name": "", "tab": { "menu": { @@ -1270,7 +1264,6 @@ "new": "" }, "tab-options": { - "title": "", "title-option": "" } }, @@ -1347,7 +1340,6 @@ "description": "", "open-edit": "", "plugin-type-image": "", - "title": "", "title-option": "", "transparent-background": "" } diff --git a/public/locales/pt-PT/grafana.json b/public/locales/pt-PT/grafana.json new file mode 100644 index 00000000000..f3a7ee625b6 --- /dev/null +++ b/public/locales/pt-PT/grafana.json @@ -0,0 +1,4010 @@ +{ + "_comment": "", + "access-control": { + "add-permission": { + "role-label": "", + "serviceaccount-label": "", + "team-label": "", + "title": "", + "user-label": "" + }, + "add-permissions": { + "save": "" + }, + "permission-list": { + "permission": "" + }, + "permission-list-item": { + "inherited": "" + }, + "permissions": { + "add-label": "", + "no-permissions": "", + "permissions-change-warning": "", + "role": "", + "serviceaccount": "", + "team": "", + "title": "", + "user": "" + } + }, + "action-editor": { + "modal": { + "cancel-button": "", + "save-button": "" + } + }, + "admin": { + "anon-users": { + "not-found": "" + }, + "edit-org": { + "access-denied": "", + "heading": "", + "update-button": "", + "users-heading": "" + }, + "feature-toggles": { + "sub-title": "" + }, + "get-enterprise": { + "contact-us": "", + "description": "", + "features-heading": "", + "included-description": "", + "included-heading": "", + "service-title": "", + "team-sync-details": "", + "title": "" + }, + "ldap": { + "test-mapping-heading": "", + "test-mapping-run-button": "" + }, + "ldap-permissions": { + "active": "", + "admin": "", + "inactive": "" + }, + "ldap-status": { + "title": "" + }, + "ldap-sync": { + "debug-button": "", + "external-sync-description": "", + "external-sync-label": "", + "next-sync-label": "", + "not-enabled": "", + "sync-button": "", + "title": "" + }, + "ldap-sync-info": { + "title": "" + }, + "ldap-user-groups": { + "no-org-found": "" + }, + "ldap-user-info": { + "no-team": "" + }, + "org-uers": { + "last-seen-never": "" + }, + "org-users": { + "not-editable": "" + }, + "orgs": { + "delete-body": "", + "id-header": "", + "name-header": "", + "new-org-button": "" + }, + "server-settings": { + "alerts-button": "", + "dashboards-button": "", + "data-sources-button": "", + "not-found": "", + "title": "", + "users-button": "" + }, + "settings": { + "info-description": "" + }, + "upgrade-info": { + "title": "" + }, + "user-orgs": { + "add-button": "", + "change-role-button": "", + "external-user-tooltip": "", + "remove-button": "", + "role-not-editable": "", + "title": "" + }, + "user-orgs-modal": { + "add-button": "", + "cancel-button": "" + }, + "user-permissions": { + "change-button": "", + "grafana-admin-key": "", + "grafana-admin-no": "", + "grafana-admin-yes": "", + "title": "" + }, + "user-profile": { + "delete-button": "", + "disable-button": "", + "edit-button": "", + "enable-button": "", + "title": "" + }, + "user-sessions": { + "browser-column": "", + "force-logout-all-button": "", + "force-logout-button": "", + "ip-column": "", + "last-seen-column": "", + "logged-on-column": "", + "title": "" + }, + "users-create": { + "create-button": "" + }, + "users-list": { + "create-button": "" + }, + "users-table": { + "last-seen-never": "", + "no-licensed-roles": "" + } + }, + "alert-labels": { + "button": { + "hide": "", + "show": { + "tooltip": "" + } + } + }, + "alerting": { + "alert": { + "alert-state": "", + "annotations": "", + "evaluation": "", + "evaluation-paused": "", + "evaluation-paused-description": "", + "last-evaluated": "", + "last-evaluation-duration": "", + "last-updated-at": "", + "last-updated-by": "", + "no-annotations": "", + "pending-period": "", + "rule": "", + "rule-identifier": "", + "rule-type": "", + "state-error-timeout": "", + "state-no-data": "", + "target-datasource-uid": "" + }, + "alert-recording-rule-form": { + "evaluation-behaviour": { + "description": { + "text": "" + } + } + }, + "alert-rules": { + "firing-for": "", + "next-evaluation": "", + "next-evaluation-in": "", + "rule-definition": "" + }, + "alertform": { + "labels": { + "alerting": "", + "recording": "" + } + }, + "alertVersionHistory": { + "alerting": "", + "alerting-change-description": "", + "annotations": "", + "compare": "", + "compare-with-latest": "", + "compareVersions": "", + "comparing-versions": "", + "condition": "", + "contactPointRouting": "", + "description": "", + "errorloading": "", + "execErrorState": "", + "intervalSeconds": "", + "labels": "", + "latest": "", + "name": "", + "namespace_uid": "", + "noDataState": "", + "noVersionsFound": "", + "paused": "", + "pendingPeriod": "", + "provisioning": "", + "provisioning-change-description": "", + "queryAndAlertCondition": "", + "restore": "", + "restore-manually": "", + "restore-modal": { + "body": "", + "confirm": "", + "error": "", + "summary": "", + "title": "" + }, + "restore-version": "", + "rule_group": "", + "unknown": "", + "unknown-change-description": "", + "user-id": "", + "warning-restore-manually": "", + "warning-restore-manually-title": "" + }, + "annotations": { + "description": "", + "title": "" + }, + "central-alert-history": { + "details": { + "error": "", + "header": { + "alert-rule": "", + "instance": "", + "state": "", + "timestamp": "" + }, + "loading": "", + "no-recognized-state": "", + "no-values": "", + "not-found": "", + "number-transitions": "", + "state": { + "alerting": "", + "error": "", + "no-data": "", + "normal": "", + "pending": "" + }, + "state-transitions": "", + "unknown-event-state": "", + "unknown-rule": "", + "value-in-transition": "" + }, + "error": "", + "filter": { + "clear": "", + "info": { + "label1": "", + "label2": "", + "label3": "", + "label4": "" + } + }, + "filterBy": "", + "too-many-events": { + "text": "", + "title": "" + } + }, + "common": { + "cancel": "", + "clear-filters": "", + "delete": "", + "edit": "", + "export": "", + "export-all": "", + "loading": "", + "search-by-matchers": "", + "titles": { + "notification-templates": "" + }, + "view": "" + }, + "contact-points": { + "create": "", + "custom-template-value": "", + "delete-reasons": { + "heading": "", + "no-permissions": "", + "policies": "", + "provisioned": "", + "rules": "" + }, + "delivered-to": "", + "delivery-duration": "", + "empty-state": { + "title": "" + }, + "key-value-map": { + "add": "", + "confirm-add": "" + }, + "last-delivery-attempt": "", + "last-delivery-failed": "", + "no-contact-points-found": "", + "no-delivery-attempts": "", + "no-integrations": "", + "only-firing": "", + "receiver-summary": { + "jira": "" + }, + "telegram": { + "parse-mode-warning-body": "", + "parse-mode-warning-title": "" + }, + "used-by_one": "", + "used-by_other": "", + "used-by-rules_one": "", + "used-by-rules_other": "" + }, + "contactPointFilter": { + "label": "" + }, + "copy-to-clipboard": "", + "dag": { + "missing-reference": "", + "self-reference": "" + }, + "export": { + "subtitle": { + "formats": "", + "one-format": "" + } + }, + "folderAndGroup": { + "evaluation": { + "modal": { + "text": { + "alerting": "", + "recording": "" + } + } + } + }, + "group-actions": { + "actions-trigger": "", + "delete": "", + "edit": "", + "export": "", + "reorder": "" + }, + "list-view": { + "empty": { + "new-alert-rule": "", + "new-recording-rule": "", + "provisioning": "" + }, + "section": { + "dataSourceManaged": { + "title": "" + }, + "grafanaManaged": { + "export-new-rule": "", + "export-rules": "", + "loading": "", + "new-recording-rule": "", + "title": "" + } + } + }, + "manage-permissions": { + "button": "", + "title": "" + }, + "mute_timings": { + "error-loading": { + "description": "", + "title": "" + } + }, + "mute-timings": { + "add-mute-timing": "", + "description": "", + "save": "", + "saving": "" + }, + "notification-preview": { + "alertmanager": "", + "error": "", + "initialized": "", + "preview-routing": "", + "title": "", + "uninitialized": "" + }, + "notification-templates": { + "duplicate": { + "subTitle": "", + "title": "" + }, + "edit": { + "subTitle": "", + "title": "" + }, + "new": { + "subTitle": "", + "title": "" + } + }, + "policies": { + "default-policy": { + "description": "", + "title": "", + "update": "" + }, + "delete": { + "confirm": "", + "warning-1": "", + "warning-2": "" + }, + "filter-description": "", + "generated-policies": "", + "matchers": "", + "metadata": { + "active-time": "", + "delivered-to": "", + "grouped-by": "", + "grouping": { + "none": "", + "single-group": "" + }, + "inherited": "", + "mute-time": "", + "timingOptions": { + "groupInterval": { + "description": "", + "label": "" + }, + "groupWait": { + "description": "", + "label": "" + }, + "repeatInterval": { + "description": "", + "label": "" + } + }, + "n-instances_one": "", + "n-instances_other": "" + }, + "new-child": "", + "new-policy": "", + "no-matchers": "", + "reload-policies": "", + "save-policy": "", + "update": { + "please-wait": "", + "update-policy": "", + "updating": "" + }, + "update-errors": { + "conflict": "", + "error-code": "", + "fallback": "", + "suffix": "", + "title": "" + }, + "n-more-policies_one": "", + "n-more-policies_other": "" + }, + "provisioning": { + "badge-tooltip-provenance": "", + "badge-tooltip-standard": "" + }, + "queryAndExpressionsStep": { + "disableAdvancedOptions": { + "text": "" + }, + "preview": "", + "previewCondition": "" + }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, + "rule-form": { + "evaluation": { + "evaluation-group-and-interval": "", + "group": { + "cancel": "", + "create": "", + "interval": "" + }, + "group-name": "", + "group-text": "", + "new-group": "", + "pause": { + "alerting": "", + "recording": "" + }, + "select-folder-before": "" + }, + "evaluation-behaviour": { + "description": { + "text": "" + }, + "info-help": { + "text": "" + }, + "pending-period": "" + }, + "evaluation-behaviour-description1": "", + "evaluation-behaviour-description2": "", + "evaluation-behaviour-description3": "", + "evaluation-behaviour-for": { + "error-parsing": "", + "validation": "" + }, + "folder": { + "cancel": "", + "create": "", + "create-folder": "", + "creating-new-folder": "", + "label": "", + "name": "", + "new-folder": "", + "new-folder-or": "" + }, + "folder-and-labels": "", + "folders": { + "help-info": "" + }, + "labels": { + "help-info": "" + }, + "pause": { + "label": "" + }, + "threshold": { + "recovery": { + "stop-alerting-above": "", + "stop-alerting-bellow": "", + "stop-alerting-equal": "", + "stop-alerting-inside-range": "", + "stop-alerting-less": "", + "stop-alerting-more": "", + "stop-alerting-not-equal": "", + "stop-alerting-outside-range": "", + "title": "" + } + } + }, + "rule-groups": { + "delete": { + "success": "" + }, + "move": { + "success": "" + }, + "rename": { + "success": "" + }, + "update": { + "success": "" + } + }, + "rule-list": { + "configure-datasource": "", + "ds-error-boundary": { + "description": "", + "title": "" + }, + "filter-view": { + "no-more-results": "", + "no-rules-found": "" + }, + "new-alert-rule": "", + "pagination": { + "next-page": "", + "previous-page": "" + }, + "return-button": { + "title": "" + }, + "rulerrule-loading-error": "" + }, + "rule-state": { + "creating": "", + "deleting": "", + "paused": "", + "recording-rule": "" + }, + "rule-view": { + "query": { + "datasources-na": { + "description": "", + "title": "" + } + } + }, + "rule-viewer": { + "error-loading": "", + "prometheus-consistency-check": { + "alert-message": "", + "alert-title": "" + } + }, + "rules": { + "add-rule": { + "success": "" + }, + "delete-rule": { + "success": "" + }, + "pause-rule": { + "success": "" + }, + "resume-rule": { + "success": "" + }, + "update-rule": { + "success": "" + } + }, + "search": { + "property": { + "data-source": "", + "evaluation-group": "", + "labels": "", + "namespace": "", + "rule-health": "", + "rule-name": "", + "rule-type": "", + "state": "" + }, + "save-query": "" + }, + "silences": { + "affected-instances": "", + "only-firing-instances": "", + "preview-affected-instances": "" + }, + "simpleCondition": { + "alertCondition": "" + }, + "templates": { + "editor": { + "add-example": "", + "auto-complete": "", + "goto-docs": "" + }, + "help": { + "intro": "" + }, + "misconfigured-badge-text": "", + "misconfigured-warning": "", + "misconfigured-warning-details": "" + }, + "threshold": { + "to": "" + } + }, + "annotations": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + } + }, + "api-keys": { + "empty-state": { + "message": "" + } + }, + "app-chrome": { + "skip-content-button": "", + "top-bar": { + "sign-in": "" + } + }, + "app-notification": { + "item": { + "trace-id": "" + } + }, + "bookmarks-page": { + "empty": { + "message": "", + "tip": "" + } + }, + "bouncing-loader": { + "label": "" + }, + "browse-dashboards": { + "action": { + "cancel-button": "", + "cannot-move-folders": "", + "confirmation-text": "", + "delete-button": "", + "delete-modal-invalid-text": "", + "delete-modal-invalid-title": "", + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "delete-modal-title": "", + "deleting": "", + "manage-permissions-button": "", + "move-button": "", + "move-modal-alert": "", + "move-modal-field-label": "", + "move-modal-text": "", + "move-modal-title": "", + "moving": "", + "new-folder-name-required-phrase": "" + }, + "actions": { + "button-to-recently-deleted": "" + }, + "counts": { + "alertRule_one": "", + "alertRule_other": "", + "dashboard_one": "", + "dashboard_other": "", + "folder_one": "", + "folder_other": "", + "libraryPanel_one": "", + "libraryPanel_other": "", + "total_one": "", + "total_other": "" + }, + "dashboards-tree": { + "collapse-folder-button": "", + "expand-folder-button": "", + "name-column": "", + "select-all-header-checkbox": "", + "select-checkbox": "", + "tags-column": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "", + "title-folder": "" + }, + "folder-actions-button": { + "delete": "", + "folder-actions": "", + "manage-permissions": "", + "move": "" + }, + "folder-picker": { + "accessible-label": "", + "button-label": "", + "clear-selection": "", + "empty-message": "", + "error-title": "", + "non-folder-item": "", + "search-placeholder": "", + "unknown-error": "" + }, + "hard-delete": { + "success": "" + }, + "manage-folder-nav": { + "alert-rules": "", + "dashboards": "", + "panels": "" + }, + "new-folder-form": { + "cancel-label": "", + "create-label": "", + "name-label": "" + }, + "no-results": { + "clear": "", + "text": "" + }, + "soft-delete": { + "success": "" + } + }, + "clipboard-button": { + "inline-toast": { + "success": "" + } + }, + "combobox": { + "async": { + "error": "" + }, + "clear": { + "title": "" + }, + "custom-value": { + "description": "" + }, + "group": { + "undefined": "" + }, + "options": { + "no-found": "" + } + }, + "command-palette": { + "action": { + "change-theme": "", + "dark-theme": "", + "light-theme": "" + }, + "empty-state": { + "message": "" + }, + "search-box": { + "placeholder": "" + }, + "section": { + "actions": "", + "dashboard-search-results": "", + "folder-search-results": "", + "pages": "", + "preferences": "", + "recent-dashboards": "" + } + }, + "common": { + "apply": "", + "cancel": "", + "clear": "", + "close": "", + "collapse": "", + "edit": "", + "help": "", + "loading": "", + "locale": { + "default": "" + }, + "save": "", + "search": "", + "view": "" + }, + "configuration-tracker": { + "config-card": { + "complete": "" + } + }, + "connections": { + "connect-data": { + "category-header-label": "", + "empty-message": "", + "request-data-source": "", + "roadmap": "" + }, + "search": { + "placeholder": "" + } + }, + "core": { + "versionHistory": { + "comparison": { + "header": { + "hide-json-diff": "", + "show-json-diff": "", + "text": "" + }, + "select": "" + }, + "no-properties-changed": "", + "table": { + "updated": "", + "updatedBy": "", + "version": "" + }, + "view-json-diff": "" + } + }, + "correlations": { + "add-new": "", + "alert": { + "error-message": "", + "title": "" + }, + "basic-info-form": { + "description-description": "", + "description-label": "", + "label-description": "", + "label-label": "", + "label-placeholder": "", + "label-required": "", + "sub-text": "", + "title": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + }, + "list": { + "delete": "", + "label": "", + "loading": "", + "read-only": "", + "source": "", + "target": "" + }, + "navigation-form": { + "add-button": "", + "back-button": "", + "next-button": "", + "save-button": "" + }, + "page-content": "", + "page-heading": "", + "query-editor": { + "control-rules": "", + "data-source-text": "", + "data-source-title": "", + "error-text": "", + "error-title": "", + "loading": "", + "query-description": "", + "query-editor-title": "", + "query-label": "" + }, + "source-form": { + "control-required": "", + "description": "", + "description-external-pre": "", + "description-query-pre": "", + "external-title": "", + "heading-external": "", + "heading-query": "", + "query-title": "", + "results-description": "", + "results-label": "", + "results-required": "", + "source-description": "", + "source-label": "", + "sub-text": "" + }, + "sub-title": "", + "target-form": { + "control-rules": "", + "sub-text": "", + "target-description-external": "", + "target-description-query": "", + "target-label": "", + "target-type-description": "", + "title": "", + "type-label": "" + }, + "trans-details": { + "logfmt-description": "", + "logfmt-label": "", + "regex-description": "", + "regex-expression": "", + "regex-label": "", + "regex-map-values": "" + }, + "transform": { + "add-button": "", + "heading": "", + "no-transform": "" + }, + "transform-row": { + "expression-label": "", + "expression-required": "", + "expression-tooltip": "", + "field-input": "", + "field-label": "", + "field-tooltip": "", + "map-value-label": "", + "map-value-tooltip": "", + "remove-button": "", + "remove-tooltip": "", + "transform-required": "", + "type-label": "", + "type-tooltip": "" + } + }, + "dashboard": { + "add-menu": { + "import": "", + "paste-panel": "", + "row": "", + "visualization": "" + }, + "alert-rules-drawer": { + "redirect-link": "", + "subtitle": "" + }, + "default-layout": { + "description": "", + "item-options": { + "repeat": { + "direction": { + "horizontal": "", + "title": "", + "vertical": "" + }, + "max": "", + "title": "", + "variable": { + "description": "", + "title": "" + } + } + }, + "name": "", + "row-actions": { + "delete": "", + "modal": { + "alt-action": "", + "text": "", + "title": "" + } + }, + "row-options": { + "button": { + "label": "" + }, + "form": { + "cancel": "", + "repeat-for": { + "label": "", + "learn-more": "", + "warning": { + "text": "" + } + }, + "title": "", + "update": "" + }, + "modal": { + "title": "" + }, + "repeat": { + "title": "", + "variable": { + "title": "" + } + }, + "title": "" + } + }, + "edit-pane": { + "elements": { + "dashboard": "", + "objects": "", + "panel": "", + "panels": "", + "row": "", + "rows": "", + "tab": "", + "tabs": "" + }, + "open": "", + "row": { + "header": { + "hide": "", + "title": "" + } + } + }, + "editpane": { + "add": "", + "configure": "", + "outline": "" + }, + "empty": { + "add-library-panel-body": "", + "add-library-panel-button": "", + "add-library-panel-header": "", + "add-visualization-body": "", + "add-visualization-button": "", + "add-visualization-header": "", + "import-a-dashboard-body": "", + "import-a-dashboard-header": "", + "import-dashboard-button": "" + }, + "errors": { + "failed-to-load": "" + }, + "inspect": { + "data-tab": "", + "error-tab": "", + "json-tab": "", + "meta-tab": "", + "query-tab": "", + "stats-tab": "", + "subtitle": "", + "title": "" + }, + "inspect-data": { + "data-options": "", + "dataframe-aria-label": "", + "dataframe-label": "", + "download-csv": "", + "download-excel-description": "", + "download-excel-label": "", + "download-logs": "", + "download-service": "", + "download-traces": "", + "excel-header": "", + "formatted": "", + "formatted-data-description": "", + "formatted-data-label": "", + "panel-transforms": "", + "series-to-columns": "", + "transformation": "", + "transformations-description": "", + "transformations-label": "" + }, + "inspect-json": { + "dataframe-description": "", + "dataframe-label": "", + "panel-data-description": "", + "panel-data-label": "", + "panel-json-description": "", + "panel-json-label": "", + "select-source": "", + "unknown": "" + }, + "inspect-meta": { + "no-inspector": "" + }, + "inspect-stats": { + "data-title": "", + "data-traceids": "", + "processing-time": "", + "queries": "", + "request-time": "", + "rows": "", + "table-title": "" + }, + "layout": { + "common": { + "copy": "", + "copy-or-duplicate": "", + "delete": "", + "duplicate": "", + "layout": "" + } + }, + "options": { + "description": "", + "title-option": "" + }, + "outline": { + "tree": { + "item": { + "collapse": "", + "empty": "", + "expand": "" + } + } + }, + "panel-edit": { + "alerting-tab": { + "dashboard-not-saved": "", + "no-rules": "" + } + }, + "responsive-layout": { + "description": "", + "item-options": { + "hide-no-data": "", + "repeat": { + "variable": { + "description": "", + "title": "" + } + }, + "title": "" + }, + "name": "", + "options": { + "columns": "", + "fixed": "", + "min": "", + "one-column": "", + "rows": "", + "three-columns": "", + "two-columns": "" + } + }, + "rows-layout": { + "description": "", + "name": "", + "option": { + "height": "", + "hide-header": "", + "repeat": "", + "title": "" + }, + "options": { + "height-expand": "", + "height-min": "" + }, + "row": { + "collapse": "", + "expand": "", + "menu": { + "add": "", + "add-panel": "", + "add-row-above": "", + "add-row-below": "", + "move-down": "", + "move-row": "", + "move-up": "" + }, + "new": "", + "repeat": { + "learn-more": "", + "warning": "" + } + }, + "row-options": { + "title-option": "" + } + }, + "tabs-layout": { + "description": "", + "menu": { + "move-tab": "" + }, + "name": "", + "tab": { + "menu": { + "add": "", + "add-panel": "", + "add-tab-above": "", + "add-tab-after": "", + "add-tab-before": "", + "move-left": "", + "move-right": "" + }, + "new": "" + }, + "tab-options": { + "title-option": "" + } + }, + "toolbar": { + "add": "", + "add-panel": "", + "add-panel-description": "", + "add-panel-lib": "", + "add-row": "", + "add-tab": "", + "alert-rules": "", + "back-to-dashboard": "", + "dashboard-settings": { + "label": "", + "tooltip": "" + }, + "discard-library-panel-changes": "", + "discard-panel": "", + "discard-panel-new": "", + "edit": { + "label": "", + "tooltip": "" + }, + "edit-dashboard-v2-schema": "", + "enter-edit-mode": { + "label": "", + "tooltip": "" + }, + "exit-edit-mode": { + "label": "", + "tooltip": "" + }, + "libray-panel-description": "", + "mark-favorite": "", + "more-save-options": "", + "open-original": "", + "playlist-next": "", + "playlist-previous": "", + "playlist-stop": "", + "public-dashboard": "", + "refresh": "", + "row-description": "", + "save": "", + "save-dashboard": { + "label": "", + "tooltip": "" + }, + "save-dashboard-copy": { + "label": "", + "tooltip": "" + }, + "save-dashboard-short": "", + "save-library-panel": "", + "settings": "", + "share": { + "label": "", + "tooltip": "" + }, + "share-button": "", + "show-hidden-elements": "", + "switch-old-dashboard": "", + "tabs-description": "", + "unlink-library-panel": "", + "unmark-favorite": "" + }, + "validation": { + "invalid-dashboard-id": "", + "invalid-json": "", + "tags-expected-array": "", + "tags-expected-strings": "" + }, + "viz-panel": { + "options": { + "description": "", + "open-edit": "", + "plugin-type-image": "", + "title-option": "", + "transparent-background": "" + } + } + }, + "dashboard-import": { + "file-dropzone": { + "primary-text": "", + "secondary-text": "" + }, + "form-actions": { + "cancel": "", + "load": "" + }, + "gcom-field": { + "label": "", + "load-button": "", + "placeholder": "", + "validation-required": "" + }, + "json-field": { + "label": "", + "validation-required": "" + } + }, + "dashboard-links": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "title": "" + } + }, + "dashboard-settings": { + "annotations": { + "title": "" + }, + "dashboard-delete-button": "", + "delete-modal": { + "confirmation-text": "", + "delete-button": "", + "title": "" + }, + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "general": { + "auto-refresh-description": "", + "auto-refresh-label": "", + "description-label": "", + "editable-description": "", + "editable-label": "", + "folder-label": "", + "panel-options-graph-tooltip-description": "", + "panel-options-graph-tooltip-label": "", + "panel-options-label": "", + "panels-preload-description": "", + "panels-preload-label": "", + "tags-label": "", + "title": "", + "title-label": "" + }, + "json-editor": { + "save-button": "", + "subtitle": "", + "title": "" + }, + "links": { + "title": "" + }, + "permissions": { + "title": "" + }, + "provisioned-delete-modal": { + "confirm-button": "", + "text-1": "", + "text-2": "", + "text-3": "", + "text-link": "", + "title": "" + }, + "settings": { + "title": "" + }, + "time-picker": { + "hide-time-picker": "", + "now-delay-description": "", + "now-delay-label": "", + "refresh-live-dashboards-description": "", + "refresh-live-dashboards-label": "", + "time-options-label": "", + "time-zone-label": "", + "week-start-label": "" + }, + "time-regions": { + "advanced-description-cron": "", + "advanced-description-rest": "", + "advanced-description-use": "", + "advanced-label": "" + }, + "variables": { + "title": "" + }, + "versions": { + "title": "" + } + }, + "dashboards": { + "panel-edit": { + "angular-deprecation-button-open-panel-json": "", + "angular-deprecation-description": "", + "angular-deprecation-heading": "" + }, + "panel-queries": { + "add-query-from-library": "" + }, + "settings": { + "variables": { + "dependencies": { + "button": "", + "title": "" + } + } + } + }, + "data-source-list": { + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + } + }, + "data-source-picker": { + "add-new-data-source": "", + "built-in-list": { + "description-dashboard": "", + "description-grafana": "", + "description-mixed": "" + }, + "list": { + "no-data-source-message": "" + }, + "modal": { + "configure-new-data-source": "", + "input-placeholder": "", + "title": "" + }, + "open-advanced-button": "" + }, + "data-source-testing-status-page": { + "error-more-details-link": "", + "success-more-details-links": "" + }, + "data-sources": { + "datasource-add-button": { + "label": "" + }, + "empty-state": { + "message": "" + } + }, + "embed": { + "share": { + "time-range-description": "", + "time-range-label": "" + } + }, + "empty-list-cta": { + "pro-tip": "" + }, + "entity-not-found": { + "description": "" + }, + "errors": { + "dashboard-settings": { + "annotations": { + "datasource": "" + } + } + }, + "explore": { + "add-to-dashboard": "", + "drilldownInfo": { + "action": "", + "description": "", + "title": "" + }, + "logs": { + "logs-volume": { + "add-filters": "", + "decrease-timerange": "", + "much-data": "" + }, + "maximum-pinned-logs": "", + "no-logs-found": "", + "scan-for-older-logs": "", + "stop-scan": "" + }, + "rich-history": { + "close-tooltip": "", + "datasource-a-z": "", + "datasource-z-a": "", + "newest-first": "", + "oldest-first": "", + "query-history": "", + "query-library": "", + "settings": "", + "starred": "" + }, + "rich-history-card": { + "add-comment-form": "", + "add-comment-tooltip": "", + "add-to-library": "", + "cancel": "", + "confirm-delete": "", + "copy-query-tooltip": "", + "copy-shortened-link-tooltip": "", + "datasource-icon-label": "", + "datasource-name-label": "", + "datasource-not-exist": "", + "delete-query-confirmation-title": "", + "delete-query-title": "", + "delete-query-tooltip": "", + "delete-starred-query-confirmation-text": "", + "edit-comment-tooltip": "", + "optional-description": "", + "query-comment-label": "", + "query-text-label": "", + "save-comment": "", + "star-query-tooltip": "", + "unstar-query-tooltip": "", + "update-comment-form": "" + }, + "rich-history-container": { + "loading": "" + }, + "rich-history-notification": { + "query-copied": "", + "query-deleted": "" + }, + "rich-history-queries-tab": { + "displaying-partial-queries": "", + "displaying-queries": "", + "filter-aria-label": "", + "filter-history": "", + "filter-placeholder": "", + "history-local": "", + "loading": "", + "loading-results": "", + "search-placeholder": "", + "showing-queries": "", + "sort-aria-label": "", + "sort-placeholder": "" + }, + "rich-history-settings-tab": { + "alert-info": "", + "change-default-tab": "", + "clear-history-info": "", + "clear-query-history": "", + "clear-query-history-button": "", + "delete-confirm": "", + "delete-confirm-text": "", + "delete-title": "", + "history-time-span": "", + "history-time-span-description": "", + "only-show-active-datasource": "", + "query-history-deleted": "", + "retention-period": { + "1-week": "", + "2-days": "", + "2-weeks": "", + "5-days": "" + } + }, + "rich-history-starred-tab": { + "filter-queries-aria-label": "", + "filter-queries-placeholder": "", + "loading": "", + "loading-results": "", + "local-history-message": "", + "search-queries-placeholder": "", + "showing-queries": "", + "sort-queries-aria-label": "", + "sort-queries-placeholder": "" + }, + "rich-history-utils": { + "a-week-ago": "", + "days-ago": "", + "default-from": "", + "default-to": "", + "today": "", + "two-weeks-ago": "", + "yesterday": "" + }, + "rich-history-utils-notification": { + "saving-failed": "", + "update-failed": "" + }, + "run-query": { + "left-pane": "", + "right-pane": "", + "run-query-button": "", + "switch-datasource-button": "" + }, + "secondary-actions": { + "add-from-query-library": "", + "query-add-button": "", + "query-add-button-aria-label": "", + "query-history-button": "", + "query-history-button-aria-label": "", + "query-inspector-button": "", + "query-inspector-button-aria-label": "" + }, + "table": { + "no-data": "", + "title": "", + "title-with-name": "" + }, + "toolbar": { + "add-to-extensions": "", + "add-to-queryless-extensions": "", + "aria-label": "", + "copy-link": "", + "copy-link-abs-time": "", + "copy-links-absolute-category": "", + "copy-links-normal-category": "", + "copy-shortened-link": "", + "copy-shortened-link-abs-time": "", + "copy-shortened-link-label": "", + "copy-shortened-link-menu": "", + "refresh-picker-cancel": "", + "refresh-picker-run": "", + "split-close": "", + "split-close-tooltip": "", + "split-narrow": "", + "split-title": "", + "split-tooltip": "", + "split-widen": "" + } + }, + "explore-metrics": { + "breakdown": { + "clearFilter": "", + "labelSelect": "", + "missing-otel-labels": "", + "noMatchingValue": "", + "sortBy": "" + }, + "related-logs": { + "LrrDocsLink": "", + "openExploreLogs": "", + "relatedLogsUnavailable": "", + "warnExperimentalFeature": "" + }, + "viewBy": "" + }, + "export": { + "json": { + "cancel-button": "", + "copy-button": "", + "download-button": "", + "download-successful_toast_message": "", + "export-externally-label": "", + "info-text": "", + "title": "" + }, + "menu": { + "export-as-json-label": "", + "export-as-json-tooltip": "" + } + }, + "folder-filter": { + "clear-folder-button": "" + }, + "folder-picker": { + "create-instructions": "", + "loading": "" + }, + "forgot-password": { + "back-button": "", + "change-password": { + "skip-button": "", + "submit-button": "" + }, + "contact-admin": "", + "email-sent": "", + "reset-password-header": "", + "send-email-button": "" + }, + "form-prompt": { + "continue-button": "", + "description": "", + "discard-button": "" + }, + "gen-ai": { + "apply-suggestion": "", + "incomplete-request-error": "", + "send-custom-feedback": "" + }, + "get-enterprise": { + "requires-license": "", + "title": "" + }, + "grafana-ui": { + "action-editor": { + "button": { + "confirm": "", + "confirm-action": "" + }, + "inline": { + "add-action": "", + "edit-action": "" + }, + "modal": { + "action-body": "", + "action-method": "", + "action-query-params": "", + "action-title": "", + "action-title-placeholder": "", + "one-click-description": "" + } + }, + "alert": { + "close-button": "" + }, + "auto-save-field": { + "saved": "", + "saving": "" + }, + "card": { + "option": "" + }, + "cascader": { + "clear-button": "" + }, + "color-picker-popover": { + "palette-tab": "", + "spectrum-tab": "" + }, + "confirm-button": { + "cancel": "" + }, + "confirm-content": { + "placeholder": "" + }, + "data-link-editor": { + "info": "", + "new-tab-label": "", + "title-label": "", + "title-placeholder": "", + "url-label": "" + }, + "data-link-editor-modal": { + "cancel": "", + "one-click-description": "", + "save": "" + }, + "data-link-inline-editor": { + "one-click": "" + }, + "data-links-inline-editor": { + "add-link": "", + "edit-link": "", + "one-click": "", + "one-click-enabled": "", + "title-not-provided": "", + "tooltip-edit": "", + "tooltip-remove": "", + "url-not-provided": "" + }, + "data-source-basic-auth-settings": { + "user-label": "", + "user-placeholder": "" + }, + "data-source-http-proxy-settings": { + "oauth-identity-label": "", + "oauth-identity-tooltip": "", + "skip-tls-verify-label": "", + "ts-client-auth-label": "", + "with-ca-cert-label": "", + "with-ca-cert-tooltip": "" + }, + "data-source-http-settings": { + "access-help": "", + "access-help-details": "", + "access-label": "", + "access-options-browser": "", + "access-options-proxy": "", + "allowed-cookies": "", + "allowed-cookies-tooltip": "", + "auth": "", + "azure-auth-label": "", + "azure-auth-tooltip": "", + "basic-auth": "", + "basic-auth-label": "", + "browser-mode-description": "", + "browser-mode-title": "", + "default-url-access-select": "", + "default-url-tooltip": "", + "direct-url-tooltip": "", + "heading": "", + "proxy-url-tooltip": "", + "server-mode-description": "", + "server-mode-title": "", + "timeout-form-label": "", + "timeout-label": "", + "timeout-tooltip": "", + "url-label": "", + "with-credential-label": "", + "with-credential-tooltip": "" + }, + "data-source-settings": { + "alerting-settings-heading": "", + "alerting-settings-label": "", + "alerting-settings-tooltip": "", + "cert-key-reset": "", + "custom-headers-add": "", + "custom-headers-header": "", + "custom-headers-header-placeholder": "", + "custom-headers-header-remove": "", + "custom-headers-header-value": "", + "custom-headers-title": "", + "secure-socks-heading": "", + "secure-socks-label": "", + "secure-socks-tooltip": "", + "tls-certification-label": "", + "tls-certification-placeholder": "", + "tls-client-certification-label": "", + "tls-client-key-label": "", + "tls-client-key-placeholder": "", + "tls-heading": "", + "tls-server-name-label": "", + "tls-tooltip": "" + }, + "date-time-picker": { + "apply": "", + "calendar-icon-label": "", + "cancel": "", + "next-label": "", + "previous-label": "", + "select-placeholder": "" + }, + "drawer": { + "close": "" + }, + "feature-badge": { + "experimental": "", + "new": "", + "preview": "", + "private-preview": "" + }, + "field-link-list": { + "external-links-heading": "" + }, + "file-dropzone": { + "cancel-upload": "", + "file-too-large": "" + }, + "filter-input": { + "clear": "" + }, + "modal": { + "close-tooltip": "" + }, + "named-colors-palette": { + "text-color-swatch": "", + "transparent-swatch": "" + }, + "page-toolbar": { + "go-back": "", + "search-dashboard-name": "", + "search-links": "", + "search-parent-folder": "" + }, + "pagination": { + "next-page": "", + "previous-page": "" + }, + "secret-form-field": { + "reset": "" + }, + "segment-async": { + "error": "", + "loading": "", + "no-options": "" + }, + "select": { + "default-create-label": "", + "no-options-label": "", + "placeholder": "" + }, + "series-color-picker-popover": { + "y-axis-usage": "" + }, + "spinner": { + "aria-label": "" + }, + "table": { + "copy": "", + "csv-counts": "", + "filter-popup-apply": "", + "filter-popup-cancel": "", + "filter-popup-clear": "", + "filter-popup-heading": "", + "no-values-label": "", + "pagination-summary": "" + }, + "tags-input": { + "add": "" + }, + "user-icon": { + "active-text": "" + }, + "value-pill": { + "remove-button": "" + }, + "viz-legend": { + "right-axis-indicator": "" + }, + "viz-tooltip": { + "actions-confirmation-input-placeholder": "", + "actions-confirmation-label": "", + "actions-confirmation-message": "", + "footer-add-annotation": "", + "footer-click-to-action": "", + "footer-click-to-navigate": "" + } + }, + "graph": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "", + "title": "" + } + }, + "help-modal": { + "column-headers": { + "description": "", + "keys": "" + }, + "shortcuts-category": { + "dashboard": "", + "focused-panel": "", + "global": "", + "time-range": "" + }, + "shortcuts-description": { + "change-theme": "", + "collapse-all-rows": "", + "copy-time-range": "", + "dashboard-settings": "", + "duplicate-panel": "", + "exit-edit/setting-views": "", + "expand-all-rows": "", + "go-to-dashboards": "", + "go-to-explore": "", + "go-to-home-dashboard": "", + "go-to-profile": "", + "make-time-range-permanent": "", + "move-time-range-back": "", + "move-time-range-forward": "", + "open-search": "", + "open-shared-modal": "", + "paste-time-range": "", + "refresh-all-panels": "", + "remove-panel": "", + "save-dashboard": "", + "show-all-shortcuts": "", + "toggle-active-mode": "", + "toggle-all-panel-legends": "", + "toggle-auto-fit": "", + "toggle-exemplars": "", + "toggle-graph-crosshair": "", + "toggle-kiosk": "", + "toggle-panel-edit": "", + "toggle-panel-fullscreen": "", + "toggle-panel-legend": "", + "zoom-out-time-range": "" + }, + "title": "" + }, + "help-wizard": { + "download-snapshot": "", + "github-comment": "", + "support-bundle": "", + "troubleshooting-help": "" + }, + "inspector": { + "query": { + "collapse-all": "", + "copy-to-clipboard": "", + "description": "", + "expand-all": "", + "no-data": "", + "refresh": "" + } + }, + "ldap-drawer": { + "attributes-section": { + "description": "", + "email-label": "", + "label": "", + "member-of-label": "", + "name-label": "", + "surname-label": "", + "username-label": "" + }, + "extra-security-section": { + "client-cert-label": "", + "client-cert-placeholder": "", + "client-cert-value-label": "", + "client-cert-value-placeholder": "", + "client-key-label": "", + "client-key-placeholder": "", + "client-key-value-label": "", + "client-key-value-placeholder": "", + "encryption-provider-base-64": "", + "encryption-provider-description": "", + "encryption-provider-file-path": "", + "encryption-provider-label": "", + "label": "", + "min-tls-version-description": "", + "min-tls-version-label": "", + "root-ca-cert-label": "", + "root-ca-cert-placeholder": "", + "root-ca-cert-value-label": "", + "root-ca-cert-value-placeholder": "", + "start-tls-description": "", + "start-tls-label": "", + "tls-ciphers-label": "", + "tls-ciphers-placeholder": "", + "use-ssl-description": "", + "use-ssl-label": "", + "use-ssl-tooltip": "" + }, + "group-mapping": { + "grafana-admin": { + "description": "", + "label": "" + }, + "group-dn": { + "description": "", + "label": "" + }, + "org-id": { + "description": "", + "label": "" + }, + "org-role": { + "label": "" + }, + "remove": { + "button": "" + } + }, + "group-mapping-section": { + "add": { + "button": "" + }, + "description": "", + "group-search-base-dns-label": "", + "group-search-base-dns-placeholder": "", + "group-search-filter-description": "", + "group-search-filter-label": "", + "group-search-filter-user-attribute-description": "", + "group-search-filter-user-attribute-label": "", + "label": "", + "skip-org-role-sync-description": "", + "skip-org-role-sync-label": "" + }, + "misc-section": { + "allow-sign-up-descrition": "", + "allow-sign-up-label": "", + "label": "", + "port-description": "", + "port-label": "", + "timeout-description": "", + "timeout-label": "" + }, + "title": "" + }, + "ldap-settings-page": { + "advanced-settings-section": { + "edit-button": "", + "subtitle": "", + "title": "" + }, + "alert": { + "discard-success": "", + "error-fetching": "", + "error-saving": "", + "error-validate-form": "", + "feature-flag-disabled": "", + "saved": "" + }, + "bind-dn": { + "description": "", + "label": "", + "placeholder": "" + }, + "bind-password": { + "label": "" + }, + "buttons-section": { + "disable-button": "", + "discard-button": "", + "save-and-enable-button": "", + "save-button": "" + }, + "documentation": "", + "host": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "login-form-alert": { + "description": "", + "title": "" + }, + "search_filter": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "search-base-dns": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "subtitle": "", + "title": "" + }, + "library-panel": { + "add-modal": { + "cancel": "", + "create": "", + "error": "", + "folder": "", + "folder-description": "", + "name": "" + }, + "add-widget": { + "title": "" + }, + "empty-state": { + "message": "", + "more-info": "" + } + }, + "library-panels": { + "empty-state": { + "message": "" + }, + "loading-panel-text": "", + "modal": { + "button-cancel": "", + "button-view-panel1": "", + "button-view-panel2": "", + "panel-not-linked": "", + "select-no-options-message": "", + "select-placeholder": "", + "title": "", + "body_one": "", + "body_other": "" + }, + "save": { + "error": "", + "success": "" + } + }, + "link": { + "share": { + "config-alert-description": "", + "config-alert-title": "", + "config-description": "", + "copy-link-button": "", + "copy-to-clipboard": "", + "short-url-label": "", + "time-range-description": "", + "time-range-label": "" + }, + "share-panel": { + "config-description": "", + "download-image": "", + "render-image": "", + "render-image-error": "", + "render-image-error-description": "" + } + }, + "lock-icon": "", + "login": { + "divider": { + "connecting-text": "" + }, + "error": { + "blocked": "", + "invalid-user-or-password": "", + "title": "", + "unknown": "" + }, + "forgot-password": "", + "form": { + "confirmation-code": "", + "confirmation-code-label": "", + "confirmation-code-placeholder": "", + "email-label": "", + "email-placeholder": "", + "email-required": "", + "name-label": "", + "name-placeholder": "", + "password-label": "", + "password-placeholder": "", + "password-required": "", + "submit-label": "", + "submit-loading-label": "", + "username-label": "", + "username-placeholder": "", + "username-required": "", + "verify-email-label": "", + "verify-email-loading-label": "" + }, + "layout": { + "update-password": "" + }, + "services": { + "sing-in-with-prefix": "" + }, + "signup": { + "button-label": "", + "new-to-question": "" + } + }, + "logs": { + "infinite-scroll": { + "end-of-range": "", + "load-more": "", + "load-newer": "", + "load-older": "", + "older-logs": "" + }, + "log-details": { + "fields": "", + "links": "", + "log-line": "", + "no-details": "" + }, + "log-line-menu": { + "copy-link": "", + "copy-log": "", + "icon-label": "", + "pin-to-outline": "", + "show-context": "", + "unpin-from-outline": "" + }, + "log-row-message": { + "ellipsis": "", + "more": "", + "see-details": "" + }, + "log-rows": { + "disable-popover": { + "confirm": "", + "message": "", + "title": "" + }, + "disable-popover-message": { + "shortcut": "" + } + }, + "logs-navigation": { + "newer-logs": "", + "older-logs": "", + "scroll-bottom": "", + "scroll-top": "", + "start-of-range": "" + }, + "popover-menu": { + "copy": "", + "disable-menu": "", + "line-contains": "", + "line-contains-not": "" + } + }, + "migrate-to-cloud": { + "build-snapshot": { + "description": "", + "title": "", + "when-complete": "" + }, + "building-snapshot": { + "description": "", + "description-eta": "", + "title": "" + }, + "can-i-move": { + "body": "", + "link-title": "", + "title": "" + }, + "connect-modal": { + "body-cloud-stack": "", + "body-get-started": "", + "body-sign-up": "", + "body-token": "", + "body-token-field": "", + "body-token-field-placeholder": "", + "body-token-instructions": "", + "body-view-stacks": "", + "cancel": "", + "connect": "", + "connecting": "", + "title": "", + "token-error-title": "", + "token-errors": { + "instance-request-error": "", + "instance-unreachable": "", + "migration-disabled": "", + "session-creation-failure": "", + "token-invalid": "", + "token-not-saved": "", + "token-request-error": "", + "token-validation-failure": "" + }, + "token-required-error": "" + }, + "cta": { + "button": "", + "header": "" + }, + "delete-migration-token-confirm": { + "body": "", + "confirm-button": "", + "error-title": "", + "title": "" + }, + "disconnect-modal": { + "body": "", + "cancel": "", + "disconnect": "", + "disconnecting": "", + "error": "", + "title": "" + }, + "get-started": { + "body": "", + "configure-pdc-link": "", + "link-title": "", + "step-1": "", + "step-2": "", + "step-3": "", + "step-4": "", + "step-5": "", + "title": "" + }, + "is-it-secure": { + "body": "", + "link-title": "", + "title": "" + }, + "migrate-to-this-stack": { + "body": "", + "link-title": "", + "title": "" + }, + "migrated-counts": { + "alert_rule_groups": "", + "alert_rules": "", + "contact_points": "", + "dashboards": "", + "datasources": "", + "folders": "", + "library_elements": "", + "mute_timings": "", + "notification_policies": "", + "notification_templates": "", + "plugins": "" + }, + "migration-token": { + "delete-button": "", + "delete-modal-body": "", + "delete-modal-cancel": "", + "delete-modal-confirm": "", + "delete-modal-deleting": "", + "delete-modal-title": "", + "error-body": "", + "error-title": "", + "generate-button": "", + "generate-button-loading": "", + "modal-close": "", + "modal-copy-and-close": "", + "modal-copy-button": "", + "modal-field-description": "", + "modal-field-label": "", + "modal-title": "", + "status": "" + }, + "onprem": { + "cancel-snapshot-error-title": "", + "create-snapshot-error-title": "", + "disconnect-error-title": "", + "error-see-server-logs": "", + "get-session-error-title": "", + "get-snapshot-error-title": "", + "migration-finished-with-caveat-title": "", + "migration-finished-with-errors-body": "", + "migration-finished-with-warnings-body": "", + "snapshot-error-status-body": "", + "snapshot-error-status-title": "", + "success-message": "", + "success-message-generic": "", + "success-title": "", + "upload-snapshot-error-title": "" + }, + "pdc": { + "body": "", + "link-title": "", + "title": "" + }, + "pricing": { + "body": "", + "link-title": "", + "title": "" + }, + "public-preview": { + "button-text": "", + "message": "", + "message-cloud": "", + "title": "" + }, + "resource-details": { + "dismiss-button": "", + "error-messages": { + "dashboard-already-managed": "", + "datasource-already-managed": "", + "datasource-invalid-url": "", + "datasource-name-conflict": "", + "folder-name-conflict": "", + "generic-error": "", + "internal-service-error": "", + "library-element-name-conflict": "", + "resource-conflict": "", + "unexpected-error": "", + "unsupported-data-type": "" + }, + "error-title": "", + "generic-title": "", + "missing-message": "", + "resource-summary": "", + "title": "", + "warning-title": "" + }, + "resource-status": { + "error-details-button": "", + "failed": "", + "migrated": "", + "migrating": "", + "not-migrated": "", + "unknown": "", + "warning": "", + "warning-details-button": "" + }, + "resource-table": { + "dashboard-load-error": "", + "error-library-element-sub": "", + "error-library-element-title": "", + "unknown-datasource-title": "", + "unknown-datasource-type": "" + }, + "resource-type": { + "alert_rule": "", + "alert_rule_group": "", + "contact_point": "", + "dashboard": "", + "datasource": "", + "folder": "", + "library_element": "", + "mute_timing": "", + "notification_policy": "", + "notification_template": "", + "plugin": "", + "unknown": "" + }, + "summary": { + "cancel-snapshot": "", + "disconnect": "", + "errored-resource-count": "", + "page-loading": "", + "rebuild-snapshot": "", + "snapshot-date": "", + "snapshot-not-created": "", + "start-migration": "", + "successful-resource-count": "", + "target-stack-title": "", + "total-resource-count": "", + "upload-migration": "" + }, + "support-types-disclosure": { + "text": "" + }, + "token-status": { + "active": "", + "no-active": "", + "unknown": "", + "unknown-error": "" + }, + "what-is-cloud": { + "body": "", + "link-title": "", + "title": "" + }, + "why-host": { + "body": "", + "link-title": "", + "title": "" + } + }, + "multicombobox": { + "all": { + "title": "", + "title-filtered": "" + }, + "clear": { + "title": "" + } + }, + "nav": { + "add-new-connections": { + "title": "" + }, + "admin": { + "subtitle": "", + "title": "" + }, + "alert-list-legacy": { + "title": "" + }, + "alerting": { + "subtitle": "", + "title": "" + }, + "alerting-admin": { + "subtitle": "", + "title": "" + }, + "alerting-am-routes": { + "subtitle": "", + "title": "" + }, + "alerting-channels": { + "title": "" + }, + "alerting-groups": { + "subtitle": "", + "title": "" + }, + "alerting-home": { + "title": "" + }, + "alerting-legacy": { + "title": "" + }, + "alerting-list": { + "subtitle": "", + "title": "" + }, + "alerting-receivers": { + "subtitle": "", + "title": "" + }, + "alerting-silences": { + "subtitle": "", + "title": "" + }, + "alerting-upgrade": { + "subtitle": "", + "title": "" + }, + "alerts-and-incidents": { + "subtitle": "", + "title": "" + }, + "api-keys": { + "subtitle": "", + "title": "" + }, + "application": { + "title": "" + }, + "apps": { + "subtitle": "", + "title": "" + }, + "authentication": { + "title": "" + }, + "bookmarks": { + "title": "" + }, + "bookmarks-empty": { + "title": "" + }, + "collector": { + "title": "" + }, + "config": { + "title": "" + }, + "config-access": { + "subtitle": "", + "title": "" + }, + "config-general": { + "subtitle": "", + "title": "" + }, + "config-plugins": { + "subtitle": "", + "title": "" + }, + "connect-data": { + "title": "" + }, + "connections": { + "subtitle": "", + "title": "" + }, + "correlations": { + "subtitle": "", + "title": "" + }, + "create": { + "title": "" + }, + "create-alert": { + "title": "" + }, + "create-dashboard": { + "title": "" + }, + "create-folder": { + "title": "" + }, + "create-import": { + "title": "" + }, + "dashboards": { + "subtitle": "", + "title": "" + }, + "data-sources": { + "subtitle": "", + "title": "" + }, + "databases": { + "title": "" + }, + "datasources": { + "subtitle": "", + "title": "" + }, + "detect": { + "title": "" + }, + "drilldown": { + "title": "" + }, + "explore": { + "title": "" + }, + "frontend": { + "subtitle": "", + "title": "" + }, + "frontend-app": { + "title": "" + }, + "global-orgs": { + "subtitle": "", + "title": "" + }, + "global-users": { + "subtitle": "", + "title": "" + }, + "grafana-quaderno": { + "title": "" + }, + "groupsync": { + "subtitle": "" + }, + "help": { + "title": "" + }, + "help/community": "", + "help/documentation": "", + "help/keyboard-shortcuts": "", + "help/support": "", + "history-container": { + "drawer-tittle": "" + }, + "history-wrapper": { + "collapse": "", + "expand": "", + "icon-selected": "", + "icon-unselected": "", + "show-more": "", + "today": "", + "yesterday": "" + }, + "home": { + "title": "" + }, + "incidents": { + "title": "" + }, + "infrastructure": { + "subtitle": "", + "title": "" + }, + "integrations": { + "title": "" + }, + "k6": { + "title": "" + }, + "kubernetes": { + "title": "" + }, + "library-panels": { + "subtitle": "", + "title": "" + }, + "machine-learning": { + "title": "" + }, + "manage-folder": { + "subtitle": "" + }, + "migrate-to-cloud": { + "subtitle": "", + "title": "" + }, + "monitoring": { + "subtitle": "", + "title": "" + }, + "new": { + "title": "" + }, + "new-dashboard": { + "title": "" + }, + "new-folder": { + "title": "" + }, + "oncall": { + "title": "" + }, + "org-settings": { + "subtitle": "", + "title": "" + }, + "playlists": { + "subtitle": "", + "title": "" + }, + "plugins": { + "subtitle": "", + "title": "" + }, + "private-data-source-connections": { + "subtitle": "", + "title": "" + }, + "profile/notifications": { + "title": "" + }, + "profile/password": { + "title": "" + }, + "profile/settings": { + "title": "" + }, + "profiles": { + "title": "" + }, + "public": { + "title": "" + }, + "recently-deleted": { + "subtitle": "", + "title": "" + }, + "recorded-queries": { + "title": "" + }, + "reporting": { + "title": "" + }, + "scenes": { + "title": "" + }, + "search": { + "placeholderCommandPalette": "" + }, + "search-dashboards": { + "title": "" + }, + "server-settings": { + "subtitle": "", + "title": "" + }, + "service-accounts": { + "subtitle": "", + "title": "" + }, + "setup-guide": { + "title": "" + }, + "shared-dashboard": { + "subtitle": "", + "title": "" + }, + "sign-out": { + "title": "" + }, + "slo": { + "title": "" + }, + "snapshots": { + "subtitle": "", + "title": "" + }, + "starred": { + "title": "" + }, + "starred-empty": { + "title": "" + }, + "statistics-and-licensing": { + "title": "" + }, + "storage": { + "subtitle": "", + "title": "" + }, + "support-bundles": { + "subtitle": "", + "title": "" + }, + "synthetics": { + "title": "" + }, + "teams": { + "subtitle": "", + "title": "" + }, + "testing-and-synthetics": { + "subtitle": "", + "title": "" + }, + "upgrading": { + "title": "" + }, + "users": { + "subtitle": "", + "title": "" + } + }, + "navigation": { + "invite-user": { + "invite-button": "", + "invite-tooltip": "" + }, + "item": { + "add-bookmark": "", + "remove-bookmark": "" + }, + "kiosk": { + "tv-alert": "" + }, + "megamenu": { + "close": "", + "dock": "", + "list-label": "", + "open": "", + "undock": "" + }, + "rss-button": "" + }, + "news": { + "drawer": { + "close": "" + }, + "title": "" + }, + "notifications": { + "empty-state": { + "description": "", + "title": "" + }, + "starred-dashboard": "", + "unstarred-dashboard": "" + }, + "oauth": { + "form": { + "server-discovery-action-button": "", + "server-discovery-modal-close": "", + "server-discovery-modal-loading": "", + "server-discovery-modal-submit": "" + }, + "login": { + "error": "" + } + }, + "panel": { + "header-menu": { + "copy": "", + "create-library-panel": "", + "duplicate": "", + "edit": "", + "explore": "", + "get-help": "", + "hide-legend": "", + "inspect": "", + "inspect-data": "", + "inspect-json": "", + "more": "", + "new-alert-rule": "", + "query": "", + "remove": "", + "replace-library-panel": "", + "share": "", + "show-legend": "", + "unlink-library-panel": "", + "view": "" + } + }, + "panel-search": { + "no-matches": "", + "unsupported-layout": "" + }, + "panel-type-filter": { + "clear-button": "" + }, + "playlist-edit": { + "error-prefix": "", + "form": { + "add-tag-label": "", + "add-tag-placeholder": "", + "add-title-label": "", + "cancel": "", + "heading": "", + "interval-label": "", + "interval-placeholder": "", + "interval-required": "", + "name-label": "", + "name-placeholder": "", + "name-required": "", + "save": "", + "table-delete": "", + "table-drag": "", + "table-empty": "", + "table-heading": "" + }, + "sub-title": "", + "title": "" + }, + "playlist-page": { + "card": { + "delete": "", + "edit": "", + "start": "", + "tooltip": "" + }, + "create-button": { + "title": "" + }, + "delete-modal": { + "body": "", + "confirm-text": "" + }, + "empty": { + "button": "", + "pro-tip": "", + "title": "" + } + }, + "playlists": { + "empty-state": { + "message": "" + } + }, + "plugins": { + "catalog": { + "no-updates-available": "", + "update-all": { + "all-plugins-updated": "", + "available-header": "", + "button": "", + "cloud-update-message": "", + "error": "", + "error-status-text": "", + "header": "", + "installed-header": "", + "modal-confirmation": "", + "modal-dismiss": "", + "modal-in-progress": "", + "modal-title": "", + "name-header": "", + "update-header": "", + "update-status-text": "" + }, + "versions": { + "confirmation-text-1": "", + "confirmation-text-2": "", + "downgrade-confirm": "", + "downgrade-title": "" + } + }, + "details": { + "connections-tab": { + "description": "" + }, + "labels": { + "contactGrafanaLabs": "", + "customLinks": "", + "customLinksTooltip": "", + "dependencies": "", + "documentation": "", + "downloads": "", + "from": "", + "installedVersion": "", + "lastCommitDate": "", + "latestVersion": "", + "license": "", + "raiseAnIssue": "", + "reportAbuse": "", + "reportAbuseTooltip": "", + "repository": "", + "signature": "", + "status": "", + "updatedAt": "" + }, + "modal": { + "cancel": "", + "copyEmail": "", + "description": "", + "node": "", + "title": "" + } + }, + "empty-state": { + "message": "" + }, + "filter": { + "disabled": "", + "sort": "", + "sort-list": "", + "state": "" + }, + "plugin-help": { + "error": "", + "not-found": "" + } + }, + "profile": { + "change-password": { + "cancel-button": "", + "cannot-change-password-message": "", + "change-password-button": "", + "confirm-password-label": "", + "confirm-password-required": "", + "ldap-auth-proxy-message": "", + "new-password-label": "", + "new-password-required": "", + "new-password-same-as-old": "", + "old-password-label": "", + "old-password-required": "", + "passwords-must-match": "", + "strong-password-validation-register": "" + } + }, + "public-dashboard": { + "acknowledgment-checkboxes": { + "ack-title": "", + "data-src-ack-desc": "", + "data-src-ack-tooltip": "", + "public-ack-desc": "", + "public-ack-tooltip": "", + "usage-ack-desc": "", + "usage-ack-desc-tooltip": "" + }, + "config": { + "can-view-dashboard-radio-button-label": "", + "copy-button": "", + "dashboard-url-field-label": "", + "email-share-type-option-label": "", + "pause-sharing-dashboard-label": "", + "public-share-type-option-label": "", + "revoke-public-URL-button": "", + "revoke-public-URL-button-title": "", + "settings-title": "" + }, + "configuration": { + "display-annotations-description": "", + "display-annotations-label": "", + "enable-time-range-description": "", + "enable-time-range-label": "", + "settings-label": "", + "success-pause": "", + "success-resume": "", + "success-update": "", + "success-update-old": "", + "time-range-label": "", + "time-range-tooltip": "" + }, + "create-page": { + "generate-public-url-button": "", + "unsupported-features-desc": "", + "welcome-title": "" + }, + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "email-sharing": { + "accept-button": "", + "alert-text": "", + "bill-ack": "", + "cancel-button": "", + "input-invalid-email-text": "", + "input-required-email-text": "", + "invite-button": "", + "invite-field-desc": "", + "invite-field-label": "", + "learn-more-button": "", + "recipient-email-placeholder": "", + "recipient-invalid-email-text": "", + "recipient-invitation-button": "", + "recipient-invitation-description": "", + "recipient-invitation-tooltip": "", + "recipient-list-description": "", + "recipient-list-title": "", + "recipient-required-email-text": "", + "resend-button": "", + "resend-button-title": "", + "resend-invite-label": "", + "revoke-access-label": "", + "revoke-button": "", + "revoke-button-title": "", + "success-creation": "", + "success-share-type-change": "" + }, + "modal-alerts": { + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "save-dashboard-changes-alert-title": "", + "unsupport-data-source-alert-readmore-link": "", + "unsupported-data-source-alert-desc": "", + "unsupported-data-source-alert-title": "", + "unsupported-template-variable-alert-desc": "", + "unsupported-template-variable-alert-title": "" + }, + "public-sharing": { + "accept-button": "", + "alert-text": "", + "cancel-button": "", + "learn-more-button": "", + "public-ack": "", + "success-creation": "", + "success-share-type-change": "" + }, + "settings-bar-header": { + "collapse-settings-tooltip": "", + "expand-settings-tooltip": "" + }, + "settings-configuration": { + "default-time-range-label": "", + "default-time-range-label-desc": "", + "show-annotations-label": "", + "show-annotations-label-desc": "", + "time-range-picker-label": "", + "time-range-picker-label-desc": "" + }, + "settings-summary": { + "annotations-hide-text": "", + "annotations-show-text": "", + "time-range-picker-disabled-text": "", + "time-range-picker-enabled-text": "", + "time-range-text": "" + }, + "share": { + "success-delete": "", + "success-delete-old": "" + }, + "share-configuration": { + "share-type-label": "" + }, + "share-externally": { + "copy-link-button": "", + "email-share-type-option-description": "", + "email-share-type-option-label": "", + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "pause-access-button": "", + "pause-access-tooltip": "", + "public-share-type-option-description": "", + "public-share-type-option-label": "", + "resume-access-button": "", + "revoke-access-button": "", + "revoke-access-description": "", + "unsupported-data-source-alert-desc": "" + }, + "sharing": { + "success-creation": "" + } + }, + "public-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "public-dashboard-users-access-list": { + "dashboard-modal": { + "external-link": "", + "loading-text": "", + "open-dashboard-list-text": "", + "public-dashboard-link": "", + "public-dashboard-setting": "", + "sharing-setting": "" + }, + "delete-user-modal": { + "delete-user-button-text": "", + "delete-user-cancel-button": "", + "delete-user-revoke-access-button": "", + "revoke-access-title": "", + "revoke-user-access-modal-desc-line1": "", + "revoke-user-access-modal-desc-line2": "" + }, + "delete-user-shared-dashboards-modal": { + "revoke-user-access-modal-desc-line2": "" + }, + "modal": { + "dashboard-modal-title": "", + "shared-dashboard-modal-title": "" + }, + "table-body": { + "dashboard-count_one": "", + "dashboard-count_other": "" + }, + "table-header": { + "activated-label": "", + "activated-tooltip": "", + "email-label": "", + "last-active-label": "", + "origin-label": "", + "role-label": "" + } + }, + "query-operation": { + "header": { + "collapse-row": "", + "datasource-help": "", + "drag-and-drop": "", + "duplicate-query": "", + "expand-row": "", + "hide-response": "", + "remove-query": "", + "show-response": "", + "toggle-edit-mode": "" + }, + "query-editor-not-exported": "" + }, + "recently-deleted": { + "buttons": { + "delete": "", + "restore": "" + }, + "page": { + "no-deleted-dashboards": "", + "no-deleted-dashboards-text": "", + "no-search-result": "" + }, + "permanently-delete-modal": { + "confirm-text": "", + "delete-button": "", + "delete-loading": "", + "title": "", + "text_one": "", + "text_other": "" + }, + "restore-modal": { + "restore-button": "", + "restore-loading": "", + "title": "", + "folder-picker-text_one": "", + "folder-picker-text_other": "", + "text_one": "", + "text_other": "" + } + }, + "recentlyDeleted": { + "filter": { + "placeholder": "" + } + }, + "reduce": { + "strictMode": { + "description": "", + "title": "" + } + }, + "refresh-picker": { + "aria-label": { + "choose-interval": "", + "duration-selected": "" + }, + "auto-option": { + "aria-label": "", + "label": "" + }, + "live-option": { + "aria-label": "", + "label": "" + }, + "off-option": { + "aria-label": "", + "label": "" + }, + "tooltip": { + "interval-selected": "", + "turned-off": "" + } + }, + "return-to-previous": { + "button": { + "label": "" + }, + "dismissable-button": "" + }, + "role-picker": { + "built-in": { + "basic-roles": "" + }, + "input": { + "no-roles": "" + }, + "menu": { + "clear-button": "", + "tooltip": "" + }, + "sub-menu": { + "clear-button": "" + }, + "title": { + "description": "" + } + }, + "role-picker-drawer": { + "basic-roles": { + "label": "" + } + }, + "route-error": { + "description": "", + "reload-button": "", + "title": "" + }, + "save-dashboards": { + "message-length": { + "info": "", + "title": "" + }, + "name-exists": { + "message-info": "", + "message-suggestion": "", + "title": "" + } + }, + "scopes": { + "dashboards": { + "collapse": "", + "expand": "", + "loading": "", + "noResultsForFilter": "", + "noResultsForFilterClear": "", + "noResultsForScopes": "", + "noResultsNoScopes": "", + "search": "", + "toggle": { + "collapse": "", + "disabled": "", + "expand": "" + } + }, + "selector": { + "apply": "", + "cancel": "", + "input": { + "placeholder": "", + "removeAll": "" + }, + "title": "" + }, + "tree": { + "collapse": "", + "expand": "", + "headline": { + "noResults": "", + "recommended": "", + "results": "" + }, + "search": "" + } + }, + "search": { + "actions": { + "include-panels": "", + "remove-datasource-filter": "", + "sort-placeholder": "", + "starred": "", + "view-as-folders": "", + "view-as-list": "" + }, + "dashboard-actions": { + "import": "", + "new": "", + "new-dashboard": "", + "new-folder": "" + }, + "results-table": { + "datasource-header": "", + "deleted-less-than-1-min": "", + "deleted-remaining-header": "", + "location-header": "", + "name-header": "", + "tags-header": "", + "type-dashboard": "", + "type-folder": "", + "type-header": "" + }, + "search-input": { + "include-panels-placeholder": "", + "placeholder": "" + } + }, + "select": { + "select-menu": { + "selected-count": "" + } + }, + "service-account-create-page": { + "create": { + "button": "" + }, + "name": { + "label": "", + "required-error": "" + }, + "page-nav": { + "label": "" + }, + "role": { + "label": "" + } + }, + "service-accounts": { + "empty-state": { + "button-title": "", + "message": "", + "more-info": "", + "title": "" + } + }, + "share-dashboard": { + "menu": { + "export-json-title": "", + "share-externally-title": "", + "share-internally-title": "", + "share-snapshot-title": "" + }, + "share-button": "", + "share-button-tooltip": "" + }, + "share-drawer": { + "confirm-action": { + "back-arrow-button": "", + "cancel-button": "" + } + }, + "share-modal": { + "dashboard": { + "title": "" + }, + "embed": { + "copy": "", + "html": "", + "html-description": "", + "info": "", + "time-range": "" + }, + "export": { + "back-button": "", + "cancel-button": "", + "info-text": "", + "loading": "", + "save-button": "", + "share-externally-label": "", + "view-button": "" + }, + "library": { + "info": "" + }, + "link": { + "copy-link-button": "", + "info-text": "", + "link-url": "", + "render-alert": "", + "render-instructions": "", + "rendered-image": "", + "save-alert": "", + "save-dashboard": "", + "shorten-url": "", + "time-range-description": "", + "time-range-label": "" + }, + "panel": { + "title": "" + }, + "snapshot": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "deleted-message": "", + "expire": "", + "expire-day": "", + "expire-hour": "", + "expire-never": "", + "expire-week": "", + "info-text-1": "", + "info-text-2": "", + "local-button": "", + "mistake-message": "", + "name": "", + "timeout": "", + "timeout-description": "", + "url-label": "" + }, + "tab-title": { + "embed": "", + "export": "", + "library-panel": "", + "link": "", + "panel-embed": "", + "public-dashboard": "", + "public-dashboard-title": "", + "snapshot": "" + }, + "theme-picker": { + "current": "", + "dark": "", + "field-name": "", + "light": "" + }, + "view-json": { + "copy-button": "" + } + }, + "share-panel": { + "drawer": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "" + }, + "menu": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "", + "share-snapshot-title": "" + }, + "new-library-panel": { + "cancel-button": "", + "create-button": "" + } + }, + "share-panel-image": { + "preview": { + "title": "" + }, + "settings": { + "height-label": "", + "height-min": "", + "height-placeholder": "", + "height-required": "", + "max-warning": "", + "scale-factor-label": "", + "scale-factor-min": "", + "scale-factor-placeholder": "", + "scale-factor-required": "", + "title": "", + "width-label": "", + "width-min": "", + "width-placeholder": "", + "width-required": "" + } + }, + "share-playlist": { + "checkbox-description": "", + "checkbox-label": "", + "copy-link-button": "", + "link-url-label": "", + "mode": "", + "mode-kiosk": "", + "mode-normal": "", + "title": "" + }, + "shared": { + "preferences": { + "theme": { + "dark-label": "", + "light-label": "", + "system-label": "" + } + } + }, + "shared-dashboard": { + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "fields": { + "timezone-label": "" + } + }, + "shared-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "shared-preferences": { + "fields": { + "home-dashboard-label": "", + "home-dashboard-placeholder": "", + "locale-label": "", + "locale-placeholder": "", + "theme-description": "", + "theme-label": "", + "week-start-label": "" + }, + "theme": { + "default-label": "" + }, + "title": "" + }, + "sign-up": { + "back-button": "", + "submit-button": "", + "verify": { + "back-button": "", + "complete-button": "", + "header": "", + "info": "", + "send-button": "" + } + }, + "silences": { + "empty-state": { + "button-title": "", + "title": "" + }, + "table": { + "add-silence-button": "", + "edit-button": "", + "expired-silences": "", + "no-matching-silences": "", + "noConfig": "", + "recreate-button": "", + "unsilence-button": "" + } + }, + "silences-table": { + "header": { + "alert-name": "", + "state": "" + } + }, + "snapshot": { + "empty-state": { + "message": "", + "more-info": "" + }, + "external-badge": "", + "name-column-header": "", + "share": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "delete-description": "", + "delete-permission-tooltip": "", + "delete-title": "", + "deleted-alert": "", + "expiration-label": "", + "info-alert": "", + "learn-more-button": "", + "local-button": "", + "name-label": "", + "new-snapshot-button": "", + "success-creation": "", + "success-delete": "", + "view-all-button": "" + }, + "share-panel": { + "info-alert": "" + }, + "url-column-header": "", + "view-button": "" + }, + "table": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "" + } + }, + "tag-filter": { + "clear-button": "", + "loading": "", + "no-tags": "", + "placeholder": "" + }, + "teams": { + "empty-state": { + "button-title": "", + "message": "", + "pro-tip": "", + "title": "" + } + }, + "theme-preview": { + "breadcrumbs": { + "dashboards": "", + "home": "" + }, + "panel": { + "form-label": "", + "title": "" + } + }, + "time-picker": { + "absolute": { + "recent-title": "", + "title": "" + }, + "calendar": { + "apply-button": "", + "cancel-button": "", + "close": "", + "next-month": "", + "previous-month": "", + "select-time": "" + }, + "content": { + "empty-recent-list-docs": "", + "empty-recent-list-info": "", + "filter-placeholder": "" + }, + "copy-paste": { + "copy-success-message": "", + "default-error-message": "", + "default-error-title": "", + "tooltip-copy": "", + "tooltip-paste": "" + }, + "footer": { + "change-settings-button": "", + "fiscal-year-option": "", + "fiscal-year-start": "", + "time-zone-option": "", + "time-zone-selection": "" + }, + "range-content": { + "apply-button": "", + "default-error": "", + "fiscal-year": "", + "from-input": "", + "open-input-calendar": "", + "range-error": "", + "to-input": "" + }, + "range-picker": { + "backwards-time-aria-label": "", + "current-time-selected": "", + "forwards-time-aria-label": "", + "to": "", + "zoom-out-button": "", + "zoom-out-tooltip": "" + }, + "time-range": { + "apply": "", + "aria-role": "", + "default-title": "", + "example": "", + "example-details": "", + "example-title": "", + "from-label": "", + "from-to": "", + "more-info": "", + "specify": "", + "submit-button-label": "", + "supported-formats": "", + "to-label": "" + }, + "zone": { + "select-aria-label": "", + "select-search-input": "" + } + }, + "trails": { + "bookmarks": { + "or-view-bookmarks": "" + }, + "card": { + "date-created": "" + }, + "home": { + "learn-more": "", + "lets-start": "", + "start-your-metrics-exploration": "", + "subtitle": "" + }, + "metric-select": { + "filter-by": "", + "native-histogram": "", + "new-badge": "", + "otel-switch": "" + }, + "native-histogram-banner": { + "ch-heatmap": "", + "ch-histogram": "", + "click-histogram": "", + "hide-examples": "", + "learn-more": "", + "metric-examples": "", + "nh-heatmap": "", + "nh-histogram": "", + "now": "", + "previously": "", + "see-examples": "", + "sentence": "" + }, + "recent-metrics": { + "or-view-a-recent-exploration": "" + }, + "settings": { + "always-keep-selected-metric-graph-in-view": "", + "show-previews-of-metric-graphs": "" + } + }, + "transformations": { + "empty": { + "add-transformation-body": "", + "add-transformation-header": "" + } + }, + "upgrade-box": { + "discovery-text": "", + "discovery-text-continued": "", + "get-started": "", + "learn-more": "", + "upgrade-button": "" + }, + "user-orgs": { + "current-org-button": "", + "name-column": "", + "role-column": "", + "select-org-button": "", + "title": "" + }, + "user-profile": { + "fields": { + "email-error": "", + "email-label": "", + "name-error": "", + "name-label": "", + "username-label": "" + }, + "tabs": { + "general": "" + } + }, + "user-session": { + "auth-module-column": "", + "browser-column": "", + "created-at-column": "", + "identity-provider-column": "", + "ip-column": "", + "revoke": "", + "seen-at-column": "" + }, + "user-sessions": { + "loading": "" + }, + "users": { + "empty-state": { + "message": "" + } + }, + "users-access-list": { + "tabs": { + "public-dashboard-users-tab-title": "", + "shared-dashboard-users-tab-title": "" + } + }, + "variable": { + "adhoc": { + "placeholder": "" + }, + "dropdown": { + "placeholder": "" + }, + "picker": { + "link-all": "", + "option-all": "", + "option-selected-values": "", + "option-tooltip": "" + }, + "textbox": { + "placeholder": "" + } + }, + "variables": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + }, + "unknown-table": { + "loading": "", + "no-unknowns": "", + "renamed-or-missing-variables": "", + "variable": "" + } + } +} \ No newline at end of file diff --git a/public/locales/ru-RU/grafana.json b/public/locales/ru-RU/grafana.json new file mode 100644 index 00000000000..af5d7e65575 --- /dev/null +++ b/public/locales/ru-RU/grafana.json @@ -0,0 +1,4038 @@ +{ + "_comment": "", + "access-control": { + "add-permission": { + "role-label": "", + "serviceaccount-label": "", + "team-label": "", + "title": "", + "user-label": "" + }, + "add-permissions": { + "save": "" + }, + "permission-list": { + "permission": "" + }, + "permission-list-item": { + "inherited": "" + }, + "permissions": { + "add-label": "", + "no-permissions": "", + "permissions-change-warning": "", + "role": "", + "serviceaccount": "", + "team": "", + "title": "", + "user": "" + } + }, + "action-editor": { + "modal": { + "cancel-button": "", + "save-button": "" + } + }, + "admin": { + "anon-users": { + "not-found": "" + }, + "edit-org": { + "access-denied": "", + "heading": "", + "update-button": "", + "users-heading": "" + }, + "feature-toggles": { + "sub-title": "" + }, + "get-enterprise": { + "contact-us": "", + "description": "", + "features-heading": "", + "included-description": "", + "included-heading": "", + "service-title": "", + "team-sync-details": "", + "title": "" + }, + "ldap": { + "test-mapping-heading": "", + "test-mapping-run-button": "" + }, + "ldap-permissions": { + "active": "", + "admin": "", + "inactive": "" + }, + "ldap-status": { + "title": "" + }, + "ldap-sync": { + "debug-button": "", + "external-sync-description": "", + "external-sync-label": "", + "next-sync-label": "", + "not-enabled": "", + "sync-button": "", + "title": "" + }, + "ldap-sync-info": { + "title": "" + }, + "ldap-user-groups": { + "no-org-found": "" + }, + "ldap-user-info": { + "no-team": "" + }, + "org-uers": { + "last-seen-never": "" + }, + "org-users": { + "not-editable": "" + }, + "orgs": { + "delete-body": "", + "id-header": "", + "name-header": "", + "new-org-button": "" + }, + "server-settings": { + "alerts-button": "", + "dashboards-button": "", + "data-sources-button": "", + "not-found": "", + "title": "", + "users-button": "" + }, + "settings": { + "info-description": "" + }, + "upgrade-info": { + "title": "" + }, + "user-orgs": { + "add-button": "", + "change-role-button": "", + "external-user-tooltip": "", + "remove-button": "", + "role-not-editable": "", + "title": "" + }, + "user-orgs-modal": { + "add-button": "", + "cancel-button": "" + }, + "user-permissions": { + "change-button": "", + "grafana-admin-key": "", + "grafana-admin-no": "", + "grafana-admin-yes": "", + "title": "" + }, + "user-profile": { + "delete-button": "", + "disable-button": "", + "edit-button": "", + "enable-button": "", + "title": "" + }, + "user-sessions": { + "browser-column": "", + "force-logout-all-button": "", + "force-logout-button": "", + "ip-column": "", + "last-seen-column": "", + "logged-on-column": "", + "title": "" + }, + "users-create": { + "create-button": "" + }, + "users-list": { + "create-button": "" + }, + "users-table": { + "last-seen-never": "", + "no-licensed-roles": "" + } + }, + "alert-labels": { + "button": { + "hide": "", + "show": { + "tooltip": "" + } + } + }, + "alerting": { + "alert": { + "alert-state": "", + "annotations": "", + "evaluation": "", + "evaluation-paused": "", + "evaluation-paused-description": "", + "last-evaluated": "", + "last-evaluation-duration": "", + "last-updated-at": "", + "last-updated-by": "", + "no-annotations": "", + "pending-period": "", + "rule": "", + "rule-identifier": "", + "rule-type": "", + "state-error-timeout": "", + "state-no-data": "", + "target-datasource-uid": "" + }, + "alert-recording-rule-form": { + "evaluation-behaviour": { + "description": { + "text": "" + } + } + }, + "alert-rules": { + "firing-for": "", + "next-evaluation": "", + "next-evaluation-in": "", + "rule-definition": "" + }, + "alertform": { + "labels": { + "alerting": "", + "recording": "" + } + }, + "alertVersionHistory": { + "alerting": "", + "alerting-change-description": "", + "annotations": "", + "compare": "", + "compare-with-latest": "", + "compareVersions": "", + "comparing-versions": "", + "condition": "", + "contactPointRouting": "", + "description": "", + "errorloading": "", + "execErrorState": "", + "intervalSeconds": "", + "labels": "", + "latest": "", + "name": "", + "namespace_uid": "", + "noDataState": "", + "noVersionsFound": "", + "paused": "", + "pendingPeriod": "", + "provisioning": "", + "provisioning-change-description": "", + "queryAndAlertCondition": "", + "restore": "", + "restore-manually": "", + "restore-modal": { + "body": "", + "confirm": "", + "error": "", + "summary": "", + "title": "" + }, + "restore-version": "", + "rule_group": "", + "unknown": "", + "unknown-change-description": "", + "user-id": "", + "warning-restore-manually": "", + "warning-restore-manually-title": "" + }, + "annotations": { + "description": "", + "title": "" + }, + "central-alert-history": { + "details": { + "error": "", + "header": { + "alert-rule": "", + "instance": "", + "state": "", + "timestamp": "" + }, + "loading": "", + "no-recognized-state": "", + "no-values": "", + "not-found": "", + "number-transitions": "", + "state": { + "alerting": "", + "error": "", + "no-data": "", + "normal": "", + "pending": "" + }, + "state-transitions": "", + "unknown-event-state": "", + "unknown-rule": "", + "value-in-transition": "" + }, + "error": "", + "filter": { + "clear": "", + "info": { + "label1": "", + "label2": "", + "label3": "", + "label4": "" + } + }, + "filterBy": "", + "too-many-events": { + "text": "", + "title": "" + } + }, + "common": { + "cancel": "", + "clear-filters": "", + "delete": "", + "edit": "", + "export": "", + "export-all": "", + "loading": "", + "search-by-matchers": "", + "titles": { + "notification-templates": "" + }, + "view": "" + }, + "contact-points": { + "create": "", + "custom-template-value": "", + "delete-reasons": { + "heading": "", + "no-permissions": "", + "policies": "", + "provisioned": "", + "rules": "" + }, + "delivered-to": "", + "delivery-duration": "", + "empty-state": { + "title": "" + }, + "key-value-map": { + "add": "", + "confirm-add": "" + }, + "last-delivery-attempt": "", + "last-delivery-failed": "", + "no-contact-points-found": "", + "no-delivery-attempts": "", + "no-integrations": "", + "only-firing": "", + "receiver-summary": { + "jira": "" + }, + "telegram": { + "parse-mode-warning-body": "", + "parse-mode-warning-title": "" + }, + "used-by_one": "", + "used-by_few": "", + "used-by_many": "", + "used-by_other": "", + "used-by-rules_one": "", + "used-by-rules_few": "", + "used-by-rules_many": "", + "used-by-rules_other": "" + }, + "contactPointFilter": { + "label": "" + }, + "copy-to-clipboard": "", + "dag": { + "missing-reference": "", + "self-reference": "" + }, + "export": { + "subtitle": { + "formats": "", + "one-format": "" + } + }, + "folderAndGroup": { + "evaluation": { + "modal": { + "text": { + "alerting": "", + "recording": "" + } + } + } + }, + "group-actions": { + "actions-trigger": "", + "delete": "", + "edit": "", + "export": "", + "reorder": "" + }, + "list-view": { + "empty": { + "new-alert-rule": "", + "new-recording-rule": "", + "provisioning": "" + }, + "section": { + "dataSourceManaged": { + "title": "" + }, + "grafanaManaged": { + "export-new-rule": "", + "export-rules": "", + "loading": "", + "new-recording-rule": "", + "title": "" + } + } + }, + "manage-permissions": { + "button": "", + "title": "" + }, + "mute_timings": { + "error-loading": { + "description": "", + "title": "" + } + }, + "mute-timings": { + "add-mute-timing": "", + "description": "", + "save": "", + "saving": "" + }, + "notification-preview": { + "alertmanager": "", + "error": "", + "initialized": "", + "preview-routing": "", + "title": "", + "uninitialized": "" + }, + "notification-templates": { + "duplicate": { + "subTitle": "", + "title": "" + }, + "edit": { + "subTitle": "", + "title": "" + }, + "new": { + "subTitle": "", + "title": "" + } + }, + "policies": { + "default-policy": { + "description": "", + "title": "", + "update": "" + }, + "delete": { + "confirm": "", + "warning-1": "", + "warning-2": "" + }, + "filter-description": "", + "generated-policies": "", + "matchers": "", + "metadata": { + "active-time": "", + "delivered-to": "", + "grouped-by": "", + "grouping": { + "none": "", + "single-group": "" + }, + "inherited": "", + "mute-time": "", + "timingOptions": { + "groupInterval": { + "description": "", + "label": "" + }, + "groupWait": { + "description": "", + "label": "" + }, + "repeatInterval": { + "description": "", + "label": "" + } + }, + "n-instances_one": "", + "n-instances_few": "", + "n-instances_many": "", + "n-instances_other": "" + }, + "new-child": "", + "new-policy": "", + "no-matchers": "", + "reload-policies": "", + "save-policy": "", + "update": { + "please-wait": "", + "update-policy": "", + "updating": "" + }, + "update-errors": { + "conflict": "", + "error-code": "", + "fallback": "", + "suffix": "", + "title": "" + }, + "n-more-policies_one": "", + "n-more-policies_few": "", + "n-more-policies_many": "", + "n-more-policies_other": "" + }, + "provisioning": { + "badge-tooltip-provenance": "", + "badge-tooltip-standard": "" + }, + "queryAndExpressionsStep": { + "disableAdvancedOptions": { + "text": "" + }, + "preview": "", + "previewCondition": "" + }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, + "rule-form": { + "evaluation": { + "evaluation-group-and-interval": "", + "group": { + "cancel": "", + "create": "", + "interval": "" + }, + "group-name": "", + "group-text": "", + "new-group": "", + "pause": { + "alerting": "", + "recording": "" + }, + "select-folder-before": "" + }, + "evaluation-behaviour": { + "description": { + "text": "" + }, + "info-help": { + "text": "" + }, + "pending-period": "" + }, + "evaluation-behaviour-description1": "", + "evaluation-behaviour-description2": "", + "evaluation-behaviour-description3": "", + "evaluation-behaviour-for": { + "error-parsing": "", + "validation": "" + }, + "folder": { + "cancel": "", + "create": "", + "create-folder": "", + "creating-new-folder": "", + "label": "", + "name": "", + "new-folder": "", + "new-folder-or": "" + }, + "folder-and-labels": "", + "folders": { + "help-info": "" + }, + "labels": { + "help-info": "" + }, + "pause": { + "label": "" + }, + "threshold": { + "recovery": { + "stop-alerting-above": "", + "stop-alerting-bellow": "", + "stop-alerting-equal": "", + "stop-alerting-inside-range": "", + "stop-alerting-less": "", + "stop-alerting-more": "", + "stop-alerting-not-equal": "", + "stop-alerting-outside-range": "", + "title": "" + } + } + }, + "rule-groups": { + "delete": { + "success": "" + }, + "move": { + "success": "" + }, + "rename": { + "success": "" + }, + "update": { + "success": "" + } + }, + "rule-list": { + "configure-datasource": "", + "ds-error-boundary": { + "description": "", + "title": "" + }, + "filter-view": { + "no-more-results": "", + "no-rules-found": "" + }, + "new-alert-rule": "", + "pagination": { + "next-page": "", + "previous-page": "" + }, + "return-button": { + "title": "" + }, + "rulerrule-loading-error": "" + }, + "rule-state": { + "creating": "", + "deleting": "", + "paused": "", + "recording-rule": "" + }, + "rule-view": { + "query": { + "datasources-na": { + "description": "", + "title": "" + } + } + }, + "rule-viewer": { + "error-loading": "", + "prometheus-consistency-check": { + "alert-message": "", + "alert-title": "" + } + }, + "rules": { + "add-rule": { + "success": "" + }, + "delete-rule": { + "success": "" + }, + "pause-rule": { + "success": "" + }, + "resume-rule": { + "success": "" + }, + "update-rule": { + "success": "" + } + }, + "search": { + "property": { + "data-source": "", + "evaluation-group": "", + "labels": "", + "namespace": "", + "rule-health": "", + "rule-name": "", + "rule-type": "", + "state": "" + }, + "save-query": "" + }, + "silences": { + "affected-instances": "", + "only-firing-instances": "", + "preview-affected-instances": "" + }, + "simpleCondition": { + "alertCondition": "" + }, + "templates": { + "editor": { + "add-example": "", + "auto-complete": "", + "goto-docs": "" + }, + "help": { + "intro": "" + }, + "misconfigured-badge-text": "", + "misconfigured-warning": "", + "misconfigured-warning-details": "" + }, + "threshold": { + "to": "" + } + }, + "annotations": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + } + }, + "api-keys": { + "empty-state": { + "message": "" + } + }, + "app-chrome": { + "skip-content-button": "", + "top-bar": { + "sign-in": "" + } + }, + "app-notification": { + "item": { + "trace-id": "" + } + }, + "bookmarks-page": { + "empty": { + "message": "", + "tip": "" + } + }, + "bouncing-loader": { + "label": "" + }, + "browse-dashboards": { + "action": { + "cancel-button": "", + "cannot-move-folders": "", + "confirmation-text": "", + "delete-button": "", + "delete-modal-invalid-text": "", + "delete-modal-invalid-title": "", + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "delete-modal-title": "", + "deleting": "", + "manage-permissions-button": "", + "move-button": "", + "move-modal-alert": "", + "move-modal-field-label": "", + "move-modal-text": "", + "move-modal-title": "", + "moving": "", + "new-folder-name-required-phrase": "" + }, + "actions": { + "button-to-recently-deleted": "" + }, + "counts": { + "alertRule_one": "", + "alertRule_few": "", + "alertRule_many": "", + "alertRule_other": "", + "dashboard_one": "", + "dashboard_few": "", + "dashboard_many": "", + "dashboard_other": "", + "folder_one": "", + "folder_few": "", + "folder_many": "", + "folder_other": "", + "libraryPanel_one": "", + "libraryPanel_few": "", + "libraryPanel_many": "", + "libraryPanel_other": "", + "total_one": "", + "total_few": "", + "total_many": "", + "total_other": "" + }, + "dashboards-tree": { + "collapse-folder-button": "", + "expand-folder-button": "", + "name-column": "", + "select-all-header-checkbox": "", + "select-checkbox": "", + "tags-column": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "", + "title-folder": "" + }, + "folder-actions-button": { + "delete": "", + "folder-actions": "", + "manage-permissions": "", + "move": "" + }, + "folder-picker": { + "accessible-label": "", + "button-label": "", + "clear-selection": "", + "empty-message": "", + "error-title": "", + "non-folder-item": "", + "search-placeholder": "", + "unknown-error": "" + }, + "hard-delete": { + "success": "" + }, + "manage-folder-nav": { + "alert-rules": "", + "dashboards": "", + "panels": "" + }, + "new-folder-form": { + "cancel-label": "", + "create-label": "", + "name-label": "" + }, + "no-results": { + "clear": "", + "text": "" + }, + "soft-delete": { + "success": "" + } + }, + "clipboard-button": { + "inline-toast": { + "success": "" + } + }, + "combobox": { + "async": { + "error": "" + }, + "clear": { + "title": "" + }, + "custom-value": { + "description": "" + }, + "group": { + "undefined": "" + }, + "options": { + "no-found": "" + } + }, + "command-palette": { + "action": { + "change-theme": "", + "dark-theme": "", + "light-theme": "" + }, + "empty-state": { + "message": "" + }, + "search-box": { + "placeholder": "" + }, + "section": { + "actions": "", + "dashboard-search-results": "", + "folder-search-results": "", + "pages": "", + "preferences": "", + "recent-dashboards": "" + } + }, + "common": { + "apply": "", + "cancel": "", + "clear": "", + "close": "", + "collapse": "", + "edit": "", + "help": "", + "loading": "", + "locale": { + "default": "" + }, + "save": "", + "search": "", + "view": "" + }, + "configuration-tracker": { + "config-card": { + "complete": "" + } + }, + "connections": { + "connect-data": { + "category-header-label": "", + "empty-message": "", + "request-data-source": "", + "roadmap": "" + }, + "search": { + "placeholder": "" + } + }, + "core": { + "versionHistory": { + "comparison": { + "header": { + "hide-json-diff": "", + "show-json-diff": "", + "text": "" + }, + "select": "" + }, + "no-properties-changed": "", + "table": { + "updated": "", + "updatedBy": "", + "version": "" + }, + "view-json-diff": "" + } + }, + "correlations": { + "add-new": "", + "alert": { + "error-message": "", + "title": "" + }, + "basic-info-form": { + "description-description": "", + "description-label": "", + "label-description": "", + "label-label": "", + "label-placeholder": "", + "label-required": "", + "sub-text": "", + "title": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + }, + "list": { + "delete": "", + "label": "", + "loading": "", + "read-only": "", + "source": "", + "target": "" + }, + "navigation-form": { + "add-button": "", + "back-button": "", + "next-button": "", + "save-button": "" + }, + "page-content": "", + "page-heading": "", + "query-editor": { + "control-rules": "", + "data-source-text": "", + "data-source-title": "", + "error-text": "", + "error-title": "", + "loading": "", + "query-description": "", + "query-editor-title": "", + "query-label": "" + }, + "source-form": { + "control-required": "", + "description": "", + "description-external-pre": "", + "description-query-pre": "", + "external-title": "", + "heading-external": "", + "heading-query": "", + "query-title": "", + "results-description": "", + "results-label": "", + "results-required": "", + "source-description": "", + "source-label": "", + "sub-text": "" + }, + "sub-title": "", + "target-form": { + "control-rules": "", + "sub-text": "", + "target-description-external": "", + "target-description-query": "", + "target-label": "", + "target-type-description": "", + "title": "", + "type-label": "" + }, + "trans-details": { + "logfmt-description": "", + "logfmt-label": "", + "regex-description": "", + "regex-expression": "", + "regex-label": "", + "regex-map-values": "" + }, + "transform": { + "add-button": "", + "heading": "", + "no-transform": "" + }, + "transform-row": { + "expression-label": "", + "expression-required": "", + "expression-tooltip": "", + "field-input": "", + "field-label": "", + "field-tooltip": "", + "map-value-label": "", + "map-value-tooltip": "", + "remove-button": "", + "remove-tooltip": "", + "transform-required": "", + "type-label": "", + "type-tooltip": "" + } + }, + "dashboard": { + "add-menu": { + "import": "", + "paste-panel": "", + "row": "", + "visualization": "" + }, + "alert-rules-drawer": { + "redirect-link": "", + "subtitle": "" + }, + "default-layout": { + "description": "", + "item-options": { + "repeat": { + "direction": { + "horizontal": "", + "title": "", + "vertical": "" + }, + "max": "", + "title": "", + "variable": { + "description": "", + "title": "" + } + } + }, + "name": "", + "row-actions": { + "delete": "", + "modal": { + "alt-action": "", + "text": "", + "title": "" + } + }, + "row-options": { + "button": { + "label": "" + }, + "form": { + "cancel": "", + "repeat-for": { + "label": "", + "learn-more": "", + "warning": { + "text": "" + } + }, + "title": "", + "update": "" + }, + "modal": { + "title": "" + }, + "repeat": { + "title": "", + "variable": { + "title": "" + } + }, + "title": "" + } + }, + "edit-pane": { + "elements": { + "dashboard": "", + "objects": "", + "panel": "", + "panels": "", + "row": "", + "rows": "", + "tab": "", + "tabs": "" + }, + "open": "", + "row": { + "header": { + "hide": "", + "title": "" + } + } + }, + "editpane": { + "add": "", + "configure": "", + "outline": "" + }, + "empty": { + "add-library-panel-body": "", + "add-library-panel-button": "", + "add-library-panel-header": "", + "add-visualization-body": "", + "add-visualization-button": "", + "add-visualization-header": "", + "import-a-dashboard-body": "", + "import-a-dashboard-header": "", + "import-dashboard-button": "" + }, + "errors": { + "failed-to-load": "" + }, + "inspect": { + "data-tab": "", + "error-tab": "", + "json-tab": "", + "meta-tab": "", + "query-tab": "", + "stats-tab": "", + "subtitle": "", + "title": "" + }, + "inspect-data": { + "data-options": "", + "dataframe-aria-label": "", + "dataframe-label": "", + "download-csv": "", + "download-excel-description": "", + "download-excel-label": "", + "download-logs": "", + "download-service": "", + "download-traces": "", + "excel-header": "", + "formatted": "", + "formatted-data-description": "", + "formatted-data-label": "", + "panel-transforms": "", + "series-to-columns": "", + "transformation": "", + "transformations-description": "", + "transformations-label": "" + }, + "inspect-json": { + "dataframe-description": "", + "dataframe-label": "", + "panel-data-description": "", + "panel-data-label": "", + "panel-json-description": "", + "panel-json-label": "", + "select-source": "", + "unknown": "" + }, + "inspect-meta": { + "no-inspector": "" + }, + "inspect-stats": { + "data-title": "", + "data-traceids": "", + "processing-time": "", + "queries": "", + "request-time": "", + "rows": "", + "table-title": "" + }, + "layout": { + "common": { + "copy": "", + "copy-or-duplicate": "", + "delete": "", + "duplicate": "", + "layout": "" + } + }, + "options": { + "description": "", + "title-option": "" + }, + "outline": { + "tree": { + "item": { + "collapse": "", + "empty": "", + "expand": "" + } + } + }, + "panel-edit": { + "alerting-tab": { + "dashboard-not-saved": "", + "no-rules": "" + } + }, + "responsive-layout": { + "description": "", + "item-options": { + "hide-no-data": "", + "repeat": { + "variable": { + "description": "", + "title": "" + } + }, + "title": "" + }, + "name": "", + "options": { + "columns": "", + "fixed": "", + "min": "", + "one-column": "", + "rows": "", + "three-columns": "", + "two-columns": "" + } + }, + "rows-layout": { + "description": "", + "name": "", + "option": { + "height": "", + "hide-header": "", + "repeat": "", + "title": "" + }, + "options": { + "height-expand": "", + "height-min": "" + }, + "row": { + "collapse": "", + "expand": "", + "menu": { + "add": "", + "add-panel": "", + "add-row-above": "", + "add-row-below": "", + "move-down": "", + "move-row": "", + "move-up": "" + }, + "new": "", + "repeat": { + "learn-more": "", + "warning": "" + } + }, + "row-options": { + "title-option": "" + } + }, + "tabs-layout": { + "description": "", + "menu": { + "move-tab": "" + }, + "name": "", + "tab": { + "menu": { + "add": "", + "add-panel": "", + "add-tab-above": "", + "add-tab-after": "", + "add-tab-before": "", + "move-left": "", + "move-right": "" + }, + "new": "" + }, + "tab-options": { + "title-option": "" + } + }, + "toolbar": { + "add": "", + "add-panel": "", + "add-panel-description": "", + "add-panel-lib": "", + "add-row": "", + "add-tab": "", + "alert-rules": "", + "back-to-dashboard": "", + "dashboard-settings": { + "label": "", + "tooltip": "" + }, + "discard-library-panel-changes": "", + "discard-panel": "", + "discard-panel-new": "", + "edit": { + "label": "", + "tooltip": "" + }, + "edit-dashboard-v2-schema": "", + "enter-edit-mode": { + "label": "", + "tooltip": "" + }, + "exit-edit-mode": { + "label": "", + "tooltip": "" + }, + "libray-panel-description": "", + "mark-favorite": "", + "more-save-options": "", + "open-original": "", + "playlist-next": "", + "playlist-previous": "", + "playlist-stop": "", + "public-dashboard": "", + "refresh": "", + "row-description": "", + "save": "", + "save-dashboard": { + "label": "", + "tooltip": "" + }, + "save-dashboard-copy": { + "label": "", + "tooltip": "" + }, + "save-dashboard-short": "", + "save-library-panel": "", + "settings": "", + "share": { + "label": "", + "tooltip": "" + }, + "share-button": "", + "show-hidden-elements": "", + "switch-old-dashboard": "", + "tabs-description": "", + "unlink-library-panel": "", + "unmark-favorite": "" + }, + "validation": { + "invalid-dashboard-id": "", + "invalid-json": "", + "tags-expected-array": "", + "tags-expected-strings": "" + }, + "viz-panel": { + "options": { + "description": "", + "open-edit": "", + "plugin-type-image": "", + "title-option": "", + "transparent-background": "" + } + } + }, + "dashboard-import": { + "file-dropzone": { + "primary-text": "", + "secondary-text": "" + }, + "form-actions": { + "cancel": "", + "load": "" + }, + "gcom-field": { + "label": "", + "load-button": "", + "placeholder": "", + "validation-required": "" + }, + "json-field": { + "label": "", + "validation-required": "" + } + }, + "dashboard-links": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "title": "" + } + }, + "dashboard-settings": { + "annotations": { + "title": "" + }, + "dashboard-delete-button": "", + "delete-modal": { + "confirmation-text": "", + "delete-button": "", + "title": "" + }, + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "general": { + "auto-refresh-description": "", + "auto-refresh-label": "", + "description-label": "", + "editable-description": "", + "editable-label": "", + "folder-label": "", + "panel-options-graph-tooltip-description": "", + "panel-options-graph-tooltip-label": "", + "panel-options-label": "", + "panels-preload-description": "", + "panels-preload-label": "", + "tags-label": "", + "title": "", + "title-label": "" + }, + "json-editor": { + "save-button": "", + "subtitle": "", + "title": "" + }, + "links": { + "title": "" + }, + "permissions": { + "title": "" + }, + "provisioned-delete-modal": { + "confirm-button": "", + "text-1": "", + "text-2": "", + "text-3": "", + "text-link": "", + "title": "" + }, + "settings": { + "title": "" + }, + "time-picker": { + "hide-time-picker": "", + "now-delay-description": "", + "now-delay-label": "", + "refresh-live-dashboards-description": "", + "refresh-live-dashboards-label": "", + "time-options-label": "", + "time-zone-label": "", + "week-start-label": "" + }, + "time-regions": { + "advanced-description-cron": "", + "advanced-description-rest": "", + "advanced-description-use": "", + "advanced-label": "" + }, + "variables": { + "title": "" + }, + "versions": { + "title": "" + } + }, + "dashboards": { + "panel-edit": { + "angular-deprecation-button-open-panel-json": "", + "angular-deprecation-description": "", + "angular-deprecation-heading": "" + }, + "panel-queries": { + "add-query-from-library": "" + }, + "settings": { + "variables": { + "dependencies": { + "button": "", + "title": "" + } + } + } + }, + "data-source-list": { + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + } + }, + "data-source-picker": { + "add-new-data-source": "", + "built-in-list": { + "description-dashboard": "", + "description-grafana": "", + "description-mixed": "" + }, + "list": { + "no-data-source-message": "" + }, + "modal": { + "configure-new-data-source": "", + "input-placeholder": "", + "title": "" + }, + "open-advanced-button": "" + }, + "data-source-testing-status-page": { + "error-more-details-link": "", + "success-more-details-links": "" + }, + "data-sources": { + "datasource-add-button": { + "label": "" + }, + "empty-state": { + "message": "" + } + }, + "embed": { + "share": { + "time-range-description": "", + "time-range-label": "" + } + }, + "empty-list-cta": { + "pro-tip": "" + }, + "entity-not-found": { + "description": "" + }, + "errors": { + "dashboard-settings": { + "annotations": { + "datasource": "" + } + } + }, + "explore": { + "add-to-dashboard": "", + "drilldownInfo": { + "action": "", + "description": "", + "title": "" + }, + "logs": { + "logs-volume": { + "add-filters": "", + "decrease-timerange": "", + "much-data": "" + }, + "maximum-pinned-logs": "", + "no-logs-found": "", + "scan-for-older-logs": "", + "stop-scan": "" + }, + "rich-history": { + "close-tooltip": "", + "datasource-a-z": "", + "datasource-z-a": "", + "newest-first": "", + "oldest-first": "", + "query-history": "", + "query-library": "", + "settings": "", + "starred": "" + }, + "rich-history-card": { + "add-comment-form": "", + "add-comment-tooltip": "", + "add-to-library": "", + "cancel": "", + "confirm-delete": "", + "copy-query-tooltip": "", + "copy-shortened-link-tooltip": "", + "datasource-icon-label": "", + "datasource-name-label": "", + "datasource-not-exist": "", + "delete-query-confirmation-title": "", + "delete-query-title": "", + "delete-query-tooltip": "", + "delete-starred-query-confirmation-text": "", + "edit-comment-tooltip": "", + "optional-description": "", + "query-comment-label": "", + "query-text-label": "", + "save-comment": "", + "star-query-tooltip": "", + "unstar-query-tooltip": "", + "update-comment-form": "" + }, + "rich-history-container": { + "loading": "" + }, + "rich-history-notification": { + "query-copied": "", + "query-deleted": "" + }, + "rich-history-queries-tab": { + "displaying-partial-queries": "", + "displaying-queries": "", + "filter-aria-label": "", + "filter-history": "", + "filter-placeholder": "", + "history-local": "", + "loading": "", + "loading-results": "", + "search-placeholder": "", + "showing-queries": "", + "sort-aria-label": "", + "sort-placeholder": "" + }, + "rich-history-settings-tab": { + "alert-info": "", + "change-default-tab": "", + "clear-history-info": "", + "clear-query-history": "", + "clear-query-history-button": "", + "delete-confirm": "", + "delete-confirm-text": "", + "delete-title": "", + "history-time-span": "", + "history-time-span-description": "", + "only-show-active-datasource": "", + "query-history-deleted": "", + "retention-period": { + "1-week": "", + "2-days": "", + "2-weeks": "", + "5-days": "" + } + }, + "rich-history-starred-tab": { + "filter-queries-aria-label": "", + "filter-queries-placeholder": "", + "loading": "", + "loading-results": "", + "local-history-message": "", + "search-queries-placeholder": "", + "showing-queries": "", + "sort-queries-aria-label": "", + "sort-queries-placeholder": "" + }, + "rich-history-utils": { + "a-week-ago": "", + "days-ago": "", + "default-from": "", + "default-to": "", + "today": "", + "two-weeks-ago": "", + "yesterday": "" + }, + "rich-history-utils-notification": { + "saving-failed": "", + "update-failed": "" + }, + "run-query": { + "left-pane": "", + "right-pane": "", + "run-query-button": "", + "switch-datasource-button": "" + }, + "secondary-actions": { + "add-from-query-library": "", + "query-add-button": "", + "query-add-button-aria-label": "", + "query-history-button": "", + "query-history-button-aria-label": "", + "query-inspector-button": "", + "query-inspector-button-aria-label": "" + }, + "table": { + "no-data": "", + "title": "", + "title-with-name": "" + }, + "toolbar": { + "add-to-extensions": "", + "add-to-queryless-extensions": "", + "aria-label": "", + "copy-link": "", + "copy-link-abs-time": "", + "copy-links-absolute-category": "", + "copy-links-normal-category": "", + "copy-shortened-link": "", + "copy-shortened-link-abs-time": "", + "copy-shortened-link-label": "", + "copy-shortened-link-menu": "", + "refresh-picker-cancel": "", + "refresh-picker-run": "", + "split-close": "", + "split-close-tooltip": "", + "split-narrow": "", + "split-title": "", + "split-tooltip": "", + "split-widen": "" + } + }, + "explore-metrics": { + "breakdown": { + "clearFilter": "", + "labelSelect": "", + "missing-otel-labels": "", + "noMatchingValue": "", + "sortBy": "" + }, + "related-logs": { + "LrrDocsLink": "", + "openExploreLogs": "", + "relatedLogsUnavailable": "", + "warnExperimentalFeature": "" + }, + "viewBy": "" + }, + "export": { + "json": { + "cancel-button": "", + "copy-button": "", + "download-button": "", + "download-successful_toast_message": "", + "export-externally-label": "", + "info-text": "", + "title": "" + }, + "menu": { + "export-as-json-label": "", + "export-as-json-tooltip": "" + } + }, + "folder-filter": { + "clear-folder-button": "" + }, + "folder-picker": { + "create-instructions": "", + "loading": "" + }, + "forgot-password": { + "back-button": "", + "change-password": { + "skip-button": "", + "submit-button": "" + }, + "contact-admin": "", + "email-sent": "", + "reset-password-header": "", + "send-email-button": "" + }, + "form-prompt": { + "continue-button": "", + "description": "", + "discard-button": "" + }, + "gen-ai": { + "apply-suggestion": "", + "incomplete-request-error": "", + "send-custom-feedback": "" + }, + "get-enterprise": { + "requires-license": "", + "title": "" + }, + "grafana-ui": { + "action-editor": { + "button": { + "confirm": "", + "confirm-action": "" + }, + "inline": { + "add-action": "", + "edit-action": "" + }, + "modal": { + "action-body": "", + "action-method": "", + "action-query-params": "", + "action-title": "", + "action-title-placeholder": "", + "one-click-description": "" + } + }, + "alert": { + "close-button": "" + }, + "auto-save-field": { + "saved": "", + "saving": "" + }, + "card": { + "option": "" + }, + "cascader": { + "clear-button": "" + }, + "color-picker-popover": { + "palette-tab": "", + "spectrum-tab": "" + }, + "confirm-button": { + "cancel": "" + }, + "confirm-content": { + "placeholder": "" + }, + "data-link-editor": { + "info": "", + "new-tab-label": "", + "title-label": "", + "title-placeholder": "", + "url-label": "" + }, + "data-link-editor-modal": { + "cancel": "", + "one-click-description": "", + "save": "" + }, + "data-link-inline-editor": { + "one-click": "" + }, + "data-links-inline-editor": { + "add-link": "", + "edit-link": "", + "one-click": "", + "one-click-enabled": "", + "title-not-provided": "", + "tooltip-edit": "", + "tooltip-remove": "", + "url-not-provided": "" + }, + "data-source-basic-auth-settings": { + "user-label": "", + "user-placeholder": "" + }, + "data-source-http-proxy-settings": { + "oauth-identity-label": "", + "oauth-identity-tooltip": "", + "skip-tls-verify-label": "", + "ts-client-auth-label": "", + "with-ca-cert-label": "", + "with-ca-cert-tooltip": "" + }, + "data-source-http-settings": { + "access-help": "", + "access-help-details": "", + "access-label": "", + "access-options-browser": "", + "access-options-proxy": "", + "allowed-cookies": "", + "allowed-cookies-tooltip": "", + "auth": "", + "azure-auth-label": "", + "azure-auth-tooltip": "", + "basic-auth": "", + "basic-auth-label": "", + "browser-mode-description": "", + "browser-mode-title": "", + "default-url-access-select": "", + "default-url-tooltip": "", + "direct-url-tooltip": "", + "heading": "", + "proxy-url-tooltip": "", + "server-mode-description": "", + "server-mode-title": "", + "timeout-form-label": "", + "timeout-label": "", + "timeout-tooltip": "", + "url-label": "", + "with-credential-label": "", + "with-credential-tooltip": "" + }, + "data-source-settings": { + "alerting-settings-heading": "", + "alerting-settings-label": "", + "alerting-settings-tooltip": "", + "cert-key-reset": "", + "custom-headers-add": "", + "custom-headers-header": "", + "custom-headers-header-placeholder": "", + "custom-headers-header-remove": "", + "custom-headers-header-value": "", + "custom-headers-title": "", + "secure-socks-heading": "", + "secure-socks-label": "", + "secure-socks-tooltip": "", + "tls-certification-label": "", + "tls-certification-placeholder": "", + "tls-client-certification-label": "", + "tls-client-key-label": "", + "tls-client-key-placeholder": "", + "tls-heading": "", + "tls-server-name-label": "", + "tls-tooltip": "" + }, + "date-time-picker": { + "apply": "", + "calendar-icon-label": "", + "cancel": "", + "next-label": "", + "previous-label": "", + "select-placeholder": "" + }, + "drawer": { + "close": "" + }, + "feature-badge": { + "experimental": "", + "new": "", + "preview": "", + "private-preview": "" + }, + "field-link-list": { + "external-links-heading": "" + }, + "file-dropzone": { + "cancel-upload": "", + "file-too-large": "" + }, + "filter-input": { + "clear": "" + }, + "modal": { + "close-tooltip": "" + }, + "named-colors-palette": { + "text-color-swatch": "", + "transparent-swatch": "" + }, + "page-toolbar": { + "go-back": "", + "search-dashboard-name": "", + "search-links": "", + "search-parent-folder": "" + }, + "pagination": { + "next-page": "", + "previous-page": "" + }, + "secret-form-field": { + "reset": "" + }, + "segment-async": { + "error": "", + "loading": "", + "no-options": "" + }, + "select": { + "default-create-label": "", + "no-options-label": "", + "placeholder": "" + }, + "series-color-picker-popover": { + "y-axis-usage": "" + }, + "spinner": { + "aria-label": "" + }, + "table": { + "copy": "", + "csv-counts": "", + "filter-popup-apply": "", + "filter-popup-cancel": "", + "filter-popup-clear": "", + "filter-popup-heading": "", + "no-values-label": "", + "pagination-summary": "" + }, + "tags-input": { + "add": "" + }, + "user-icon": { + "active-text": "" + }, + "value-pill": { + "remove-button": "" + }, + "viz-legend": { + "right-axis-indicator": "" + }, + "viz-tooltip": { + "actions-confirmation-input-placeholder": "", + "actions-confirmation-label": "", + "actions-confirmation-message": "", + "footer-add-annotation": "", + "footer-click-to-action": "", + "footer-click-to-navigate": "" + } + }, + "graph": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "", + "title": "" + } + }, + "help-modal": { + "column-headers": { + "description": "", + "keys": "" + }, + "shortcuts-category": { + "dashboard": "", + "focused-panel": "", + "global": "", + "time-range": "" + }, + "shortcuts-description": { + "change-theme": "", + "collapse-all-rows": "", + "copy-time-range": "", + "dashboard-settings": "", + "duplicate-panel": "", + "exit-edit/setting-views": "", + "expand-all-rows": "", + "go-to-dashboards": "", + "go-to-explore": "", + "go-to-home-dashboard": "", + "go-to-profile": "", + "make-time-range-permanent": "", + "move-time-range-back": "", + "move-time-range-forward": "", + "open-search": "", + "open-shared-modal": "", + "paste-time-range": "", + "refresh-all-panels": "", + "remove-panel": "", + "save-dashboard": "", + "show-all-shortcuts": "", + "toggle-active-mode": "", + "toggle-all-panel-legends": "", + "toggle-auto-fit": "", + "toggle-exemplars": "", + "toggle-graph-crosshair": "", + "toggle-kiosk": "", + "toggle-panel-edit": "", + "toggle-panel-fullscreen": "", + "toggle-panel-legend": "", + "zoom-out-time-range": "" + }, + "title": "" + }, + "help-wizard": { + "download-snapshot": "", + "github-comment": "", + "support-bundle": "", + "troubleshooting-help": "" + }, + "inspector": { + "query": { + "collapse-all": "", + "copy-to-clipboard": "", + "description": "", + "expand-all": "", + "no-data": "", + "refresh": "" + } + }, + "ldap-drawer": { + "attributes-section": { + "description": "", + "email-label": "", + "label": "", + "member-of-label": "", + "name-label": "", + "surname-label": "", + "username-label": "" + }, + "extra-security-section": { + "client-cert-label": "", + "client-cert-placeholder": "", + "client-cert-value-label": "", + "client-cert-value-placeholder": "", + "client-key-label": "", + "client-key-placeholder": "", + "client-key-value-label": "", + "client-key-value-placeholder": "", + "encryption-provider-base-64": "", + "encryption-provider-description": "", + "encryption-provider-file-path": "", + "encryption-provider-label": "", + "label": "", + "min-tls-version-description": "", + "min-tls-version-label": "", + "root-ca-cert-label": "", + "root-ca-cert-placeholder": "", + "root-ca-cert-value-label": "", + "root-ca-cert-value-placeholder": "", + "start-tls-description": "", + "start-tls-label": "", + "tls-ciphers-label": "", + "tls-ciphers-placeholder": "", + "use-ssl-description": "", + "use-ssl-label": "", + "use-ssl-tooltip": "" + }, + "group-mapping": { + "grafana-admin": { + "description": "", + "label": "" + }, + "group-dn": { + "description": "", + "label": "" + }, + "org-id": { + "description": "", + "label": "" + }, + "org-role": { + "label": "" + }, + "remove": { + "button": "" + } + }, + "group-mapping-section": { + "add": { + "button": "" + }, + "description": "", + "group-search-base-dns-label": "", + "group-search-base-dns-placeholder": "", + "group-search-filter-description": "", + "group-search-filter-label": "", + "group-search-filter-user-attribute-description": "", + "group-search-filter-user-attribute-label": "", + "label": "", + "skip-org-role-sync-description": "", + "skip-org-role-sync-label": "" + }, + "misc-section": { + "allow-sign-up-descrition": "", + "allow-sign-up-label": "", + "label": "", + "port-description": "", + "port-label": "", + "timeout-description": "", + "timeout-label": "" + }, + "title": "" + }, + "ldap-settings-page": { + "advanced-settings-section": { + "edit-button": "", + "subtitle": "", + "title": "" + }, + "alert": { + "discard-success": "", + "error-fetching": "", + "error-saving": "", + "error-validate-form": "", + "feature-flag-disabled": "", + "saved": "" + }, + "bind-dn": { + "description": "", + "label": "", + "placeholder": "" + }, + "bind-password": { + "label": "" + }, + "buttons-section": { + "disable-button": "", + "discard-button": "", + "save-and-enable-button": "", + "save-button": "" + }, + "documentation": "", + "host": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "login-form-alert": { + "description": "", + "title": "" + }, + "search_filter": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "search-base-dns": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "subtitle": "", + "title": "" + }, + "library-panel": { + "add-modal": { + "cancel": "", + "create": "", + "error": "", + "folder": "", + "folder-description": "", + "name": "" + }, + "add-widget": { + "title": "" + }, + "empty-state": { + "message": "", + "more-info": "" + } + }, + "library-panels": { + "empty-state": { + "message": "" + }, + "loading-panel-text": "", + "modal": { + "button-cancel": "", + "button-view-panel1": "", + "button-view-panel2": "", + "panel-not-linked": "", + "select-no-options-message": "", + "select-placeholder": "", + "title": "", + "body_one": "", + "body_few": "", + "body_many": "", + "body_other": "" + }, + "save": { + "error": "", + "success": "" + } + }, + "link": { + "share": { + "config-alert-description": "", + "config-alert-title": "", + "config-description": "", + "copy-link-button": "", + "copy-to-clipboard": "", + "short-url-label": "", + "time-range-description": "", + "time-range-label": "" + }, + "share-panel": { + "config-description": "", + "download-image": "", + "render-image": "", + "render-image-error": "", + "render-image-error-description": "" + } + }, + "lock-icon": "", + "login": { + "divider": { + "connecting-text": "" + }, + "error": { + "blocked": "", + "invalid-user-or-password": "", + "title": "", + "unknown": "" + }, + "forgot-password": "", + "form": { + "confirmation-code": "", + "confirmation-code-label": "", + "confirmation-code-placeholder": "", + "email-label": "", + "email-placeholder": "", + "email-required": "", + "name-label": "", + "name-placeholder": "", + "password-label": "", + "password-placeholder": "", + "password-required": "", + "submit-label": "", + "submit-loading-label": "", + "username-label": "", + "username-placeholder": "", + "username-required": "", + "verify-email-label": "", + "verify-email-loading-label": "" + }, + "layout": { + "update-password": "" + }, + "services": { + "sing-in-with-prefix": "" + }, + "signup": { + "button-label": "", + "new-to-question": "" + } + }, + "logs": { + "infinite-scroll": { + "end-of-range": "", + "load-more": "", + "load-newer": "", + "load-older": "", + "older-logs": "" + }, + "log-details": { + "fields": "", + "links": "", + "log-line": "", + "no-details": "" + }, + "log-line-menu": { + "copy-link": "", + "copy-log": "", + "icon-label": "", + "pin-to-outline": "", + "show-context": "", + "unpin-from-outline": "" + }, + "log-row-message": { + "ellipsis": "", + "more": "", + "see-details": "" + }, + "log-rows": { + "disable-popover": { + "confirm": "", + "message": "", + "title": "" + }, + "disable-popover-message": { + "shortcut": "" + } + }, + "logs-navigation": { + "newer-logs": "", + "older-logs": "", + "scroll-bottom": "", + "scroll-top": "", + "start-of-range": "" + }, + "popover-menu": { + "copy": "", + "disable-menu": "", + "line-contains": "", + "line-contains-not": "" + } + }, + "migrate-to-cloud": { + "build-snapshot": { + "description": "", + "title": "", + "when-complete": "" + }, + "building-snapshot": { + "description": "", + "description-eta": "", + "title": "" + }, + "can-i-move": { + "body": "", + "link-title": "", + "title": "" + }, + "connect-modal": { + "body-cloud-stack": "", + "body-get-started": "", + "body-sign-up": "", + "body-token": "", + "body-token-field": "", + "body-token-field-placeholder": "", + "body-token-instructions": "", + "body-view-stacks": "", + "cancel": "", + "connect": "", + "connecting": "", + "title": "", + "token-error-title": "", + "token-errors": { + "instance-request-error": "", + "instance-unreachable": "", + "migration-disabled": "", + "session-creation-failure": "", + "token-invalid": "", + "token-not-saved": "", + "token-request-error": "", + "token-validation-failure": "" + }, + "token-required-error": "" + }, + "cta": { + "button": "", + "header": "" + }, + "delete-migration-token-confirm": { + "body": "", + "confirm-button": "", + "error-title": "", + "title": "" + }, + "disconnect-modal": { + "body": "", + "cancel": "", + "disconnect": "", + "disconnecting": "", + "error": "", + "title": "" + }, + "get-started": { + "body": "", + "configure-pdc-link": "", + "link-title": "", + "step-1": "", + "step-2": "", + "step-3": "", + "step-4": "", + "step-5": "", + "title": "" + }, + "is-it-secure": { + "body": "", + "link-title": "", + "title": "" + }, + "migrate-to-this-stack": { + "body": "", + "link-title": "", + "title": "" + }, + "migrated-counts": { + "alert_rule_groups": "", + "alert_rules": "", + "contact_points": "", + "dashboards": "", + "datasources": "", + "folders": "", + "library_elements": "", + "mute_timings": "", + "notification_policies": "", + "notification_templates": "", + "plugins": "" + }, + "migration-token": { + "delete-button": "", + "delete-modal-body": "", + "delete-modal-cancel": "", + "delete-modal-confirm": "", + "delete-modal-deleting": "", + "delete-modal-title": "", + "error-body": "", + "error-title": "", + "generate-button": "", + "generate-button-loading": "", + "modal-close": "", + "modal-copy-and-close": "", + "modal-copy-button": "", + "modal-field-description": "", + "modal-field-label": "", + "modal-title": "", + "status": "" + }, + "onprem": { + "cancel-snapshot-error-title": "", + "create-snapshot-error-title": "", + "disconnect-error-title": "", + "error-see-server-logs": "", + "get-session-error-title": "", + "get-snapshot-error-title": "", + "migration-finished-with-caveat-title": "", + "migration-finished-with-errors-body": "", + "migration-finished-with-warnings-body": "", + "snapshot-error-status-body": "", + "snapshot-error-status-title": "", + "success-message": "", + "success-message-generic": "", + "success-title": "", + "upload-snapshot-error-title": "" + }, + "pdc": { + "body": "", + "link-title": "", + "title": "" + }, + "pricing": { + "body": "", + "link-title": "", + "title": "" + }, + "public-preview": { + "button-text": "", + "message": "", + "message-cloud": "", + "title": "" + }, + "resource-details": { + "dismiss-button": "", + "error-messages": { + "dashboard-already-managed": "", + "datasource-already-managed": "", + "datasource-invalid-url": "", + "datasource-name-conflict": "", + "folder-name-conflict": "", + "generic-error": "", + "internal-service-error": "", + "library-element-name-conflict": "", + "resource-conflict": "", + "unexpected-error": "", + "unsupported-data-type": "" + }, + "error-title": "", + "generic-title": "", + "missing-message": "", + "resource-summary": "", + "title": "", + "warning-title": "" + }, + "resource-status": { + "error-details-button": "", + "failed": "", + "migrated": "", + "migrating": "", + "not-migrated": "", + "unknown": "", + "warning": "", + "warning-details-button": "" + }, + "resource-table": { + "dashboard-load-error": "", + "error-library-element-sub": "", + "error-library-element-title": "", + "unknown-datasource-title": "", + "unknown-datasource-type": "" + }, + "resource-type": { + "alert_rule": "", + "alert_rule_group": "", + "contact_point": "", + "dashboard": "", + "datasource": "", + "folder": "", + "library_element": "", + "mute_timing": "", + "notification_policy": "", + "notification_template": "", + "plugin": "", + "unknown": "" + }, + "summary": { + "cancel-snapshot": "", + "disconnect": "", + "errored-resource-count": "", + "page-loading": "", + "rebuild-snapshot": "", + "snapshot-date": "", + "snapshot-not-created": "", + "start-migration": "", + "successful-resource-count": "", + "target-stack-title": "", + "total-resource-count": "", + "upload-migration": "" + }, + "support-types-disclosure": { + "text": "" + }, + "token-status": { + "active": "", + "no-active": "", + "unknown": "", + "unknown-error": "" + }, + "what-is-cloud": { + "body": "", + "link-title": "", + "title": "" + }, + "why-host": { + "body": "", + "link-title": "", + "title": "" + } + }, + "multicombobox": { + "all": { + "title": "", + "title-filtered": "" + }, + "clear": { + "title": "" + } + }, + "nav": { + "add-new-connections": { + "title": "" + }, + "admin": { + "subtitle": "", + "title": "" + }, + "alert-list-legacy": { + "title": "" + }, + "alerting": { + "subtitle": "", + "title": "" + }, + "alerting-admin": { + "subtitle": "", + "title": "" + }, + "alerting-am-routes": { + "subtitle": "", + "title": "" + }, + "alerting-channels": { + "title": "" + }, + "alerting-groups": { + "subtitle": "", + "title": "" + }, + "alerting-home": { + "title": "" + }, + "alerting-legacy": { + "title": "" + }, + "alerting-list": { + "subtitle": "", + "title": "" + }, + "alerting-receivers": { + "subtitle": "", + "title": "" + }, + "alerting-silences": { + "subtitle": "", + "title": "" + }, + "alerting-upgrade": { + "subtitle": "", + "title": "" + }, + "alerts-and-incidents": { + "subtitle": "", + "title": "" + }, + "api-keys": { + "subtitle": "", + "title": "" + }, + "application": { + "title": "" + }, + "apps": { + "subtitle": "", + "title": "" + }, + "authentication": { + "title": "" + }, + "bookmarks": { + "title": "" + }, + "bookmarks-empty": { + "title": "" + }, + "collector": { + "title": "" + }, + "config": { + "title": "" + }, + "config-access": { + "subtitle": "", + "title": "" + }, + "config-general": { + "subtitle": "", + "title": "" + }, + "config-plugins": { + "subtitle": "", + "title": "" + }, + "connect-data": { + "title": "" + }, + "connections": { + "subtitle": "", + "title": "" + }, + "correlations": { + "subtitle": "", + "title": "" + }, + "create": { + "title": "" + }, + "create-alert": { + "title": "" + }, + "create-dashboard": { + "title": "" + }, + "create-folder": { + "title": "" + }, + "create-import": { + "title": "" + }, + "dashboards": { + "subtitle": "", + "title": "" + }, + "data-sources": { + "subtitle": "", + "title": "" + }, + "databases": { + "title": "" + }, + "datasources": { + "subtitle": "", + "title": "" + }, + "detect": { + "title": "" + }, + "drilldown": { + "title": "" + }, + "explore": { + "title": "" + }, + "frontend": { + "subtitle": "", + "title": "" + }, + "frontend-app": { + "title": "" + }, + "global-orgs": { + "subtitle": "", + "title": "" + }, + "global-users": { + "subtitle": "", + "title": "" + }, + "grafana-quaderno": { + "title": "" + }, + "groupsync": { + "subtitle": "" + }, + "help": { + "title": "" + }, + "help/community": "", + "help/documentation": "", + "help/keyboard-shortcuts": "", + "help/support": "", + "history-container": { + "drawer-tittle": "" + }, + "history-wrapper": { + "collapse": "", + "expand": "", + "icon-selected": "", + "icon-unselected": "", + "show-more": "", + "today": "", + "yesterday": "" + }, + "home": { + "title": "" + }, + "incidents": { + "title": "" + }, + "infrastructure": { + "subtitle": "", + "title": "" + }, + "integrations": { + "title": "" + }, + "k6": { + "title": "" + }, + "kubernetes": { + "title": "" + }, + "library-panels": { + "subtitle": "", + "title": "" + }, + "machine-learning": { + "title": "" + }, + "manage-folder": { + "subtitle": "" + }, + "migrate-to-cloud": { + "subtitle": "", + "title": "" + }, + "monitoring": { + "subtitle": "", + "title": "" + }, + "new": { + "title": "" + }, + "new-dashboard": { + "title": "" + }, + "new-folder": { + "title": "" + }, + "oncall": { + "title": "" + }, + "org-settings": { + "subtitle": "", + "title": "" + }, + "playlists": { + "subtitle": "", + "title": "" + }, + "plugins": { + "subtitle": "", + "title": "" + }, + "private-data-source-connections": { + "subtitle": "", + "title": "" + }, + "profile/notifications": { + "title": "" + }, + "profile/password": { + "title": "" + }, + "profile/settings": { + "title": "" + }, + "profiles": { + "title": "" + }, + "public": { + "title": "" + }, + "recently-deleted": { + "subtitle": "", + "title": "" + }, + "recorded-queries": { + "title": "" + }, + "reporting": { + "title": "" + }, + "scenes": { + "title": "" + }, + "search": { + "placeholderCommandPalette": "" + }, + "search-dashboards": { + "title": "" + }, + "server-settings": { + "subtitle": "", + "title": "" + }, + "service-accounts": { + "subtitle": "", + "title": "" + }, + "setup-guide": { + "title": "" + }, + "shared-dashboard": { + "subtitle": "", + "title": "" + }, + "sign-out": { + "title": "" + }, + "slo": { + "title": "" + }, + "snapshots": { + "subtitle": "", + "title": "" + }, + "starred": { + "title": "" + }, + "starred-empty": { + "title": "" + }, + "statistics-and-licensing": { + "title": "" + }, + "storage": { + "subtitle": "", + "title": "" + }, + "support-bundles": { + "subtitle": "", + "title": "" + }, + "synthetics": { + "title": "" + }, + "teams": { + "subtitle": "", + "title": "" + }, + "testing-and-synthetics": { + "subtitle": "", + "title": "" + }, + "upgrading": { + "title": "" + }, + "users": { + "subtitle": "", + "title": "" + } + }, + "navigation": { + "invite-user": { + "invite-button": "", + "invite-tooltip": "" + }, + "item": { + "add-bookmark": "", + "remove-bookmark": "" + }, + "kiosk": { + "tv-alert": "" + }, + "megamenu": { + "close": "", + "dock": "", + "list-label": "", + "open": "", + "undock": "" + }, + "rss-button": "" + }, + "news": { + "drawer": { + "close": "" + }, + "title": "" + }, + "notifications": { + "empty-state": { + "description": "", + "title": "" + }, + "starred-dashboard": "", + "unstarred-dashboard": "" + }, + "oauth": { + "form": { + "server-discovery-action-button": "", + "server-discovery-modal-close": "", + "server-discovery-modal-loading": "", + "server-discovery-modal-submit": "" + }, + "login": { + "error": "" + } + }, + "panel": { + "header-menu": { + "copy": "", + "create-library-panel": "", + "duplicate": "", + "edit": "", + "explore": "", + "get-help": "", + "hide-legend": "", + "inspect": "", + "inspect-data": "", + "inspect-json": "", + "more": "", + "new-alert-rule": "", + "query": "", + "remove": "", + "replace-library-panel": "", + "share": "", + "show-legend": "", + "unlink-library-panel": "", + "view": "" + } + }, + "panel-search": { + "no-matches": "", + "unsupported-layout": "" + }, + "panel-type-filter": { + "clear-button": "" + }, + "playlist-edit": { + "error-prefix": "", + "form": { + "add-tag-label": "", + "add-tag-placeholder": "", + "add-title-label": "", + "cancel": "", + "heading": "", + "interval-label": "", + "interval-placeholder": "", + "interval-required": "", + "name-label": "", + "name-placeholder": "", + "name-required": "", + "save": "", + "table-delete": "", + "table-drag": "", + "table-empty": "", + "table-heading": "" + }, + "sub-title": "", + "title": "" + }, + "playlist-page": { + "card": { + "delete": "", + "edit": "", + "start": "", + "tooltip": "" + }, + "create-button": { + "title": "" + }, + "delete-modal": { + "body": "", + "confirm-text": "" + }, + "empty": { + "button": "", + "pro-tip": "", + "title": "" + } + }, + "playlists": { + "empty-state": { + "message": "" + } + }, + "plugins": { + "catalog": { + "no-updates-available": "", + "update-all": { + "all-plugins-updated": "", + "available-header": "", + "button": "", + "cloud-update-message": "", + "error": "", + "error-status-text": "", + "header": "", + "installed-header": "", + "modal-confirmation": "", + "modal-dismiss": "", + "modal-in-progress": "", + "modal-title": "", + "name-header": "", + "update-header": "", + "update-status-text": "" + }, + "versions": { + "confirmation-text-1": "", + "confirmation-text-2": "", + "downgrade-confirm": "", + "downgrade-title": "" + } + }, + "details": { + "connections-tab": { + "description": "" + }, + "labels": { + "contactGrafanaLabs": "", + "customLinks": "", + "customLinksTooltip": "", + "dependencies": "", + "documentation": "", + "downloads": "", + "from": "", + "installedVersion": "", + "lastCommitDate": "", + "latestVersion": "", + "license": "", + "raiseAnIssue": "", + "reportAbuse": "", + "reportAbuseTooltip": "", + "repository": "", + "signature": "", + "status": "", + "updatedAt": "" + }, + "modal": { + "cancel": "", + "copyEmail": "", + "description": "", + "node": "", + "title": "" + } + }, + "empty-state": { + "message": "" + }, + "filter": { + "disabled": "", + "sort": "", + "sort-list": "", + "state": "" + }, + "plugin-help": { + "error": "", + "not-found": "" + } + }, + "profile": { + "change-password": { + "cancel-button": "", + "cannot-change-password-message": "", + "change-password-button": "", + "confirm-password-label": "", + "confirm-password-required": "", + "ldap-auth-proxy-message": "", + "new-password-label": "", + "new-password-required": "", + "new-password-same-as-old": "", + "old-password-label": "", + "old-password-required": "", + "passwords-must-match": "", + "strong-password-validation-register": "" + } + }, + "public-dashboard": { + "acknowledgment-checkboxes": { + "ack-title": "", + "data-src-ack-desc": "", + "data-src-ack-tooltip": "", + "public-ack-desc": "", + "public-ack-tooltip": "", + "usage-ack-desc": "", + "usage-ack-desc-tooltip": "" + }, + "config": { + "can-view-dashboard-radio-button-label": "", + "copy-button": "", + "dashboard-url-field-label": "", + "email-share-type-option-label": "", + "pause-sharing-dashboard-label": "", + "public-share-type-option-label": "", + "revoke-public-URL-button": "", + "revoke-public-URL-button-title": "", + "settings-title": "" + }, + "configuration": { + "display-annotations-description": "", + "display-annotations-label": "", + "enable-time-range-description": "", + "enable-time-range-label": "", + "settings-label": "", + "success-pause": "", + "success-resume": "", + "success-update": "", + "success-update-old": "", + "time-range-label": "", + "time-range-tooltip": "" + }, + "create-page": { + "generate-public-url-button": "", + "unsupported-features-desc": "", + "welcome-title": "" + }, + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "email-sharing": { + "accept-button": "", + "alert-text": "", + "bill-ack": "", + "cancel-button": "", + "input-invalid-email-text": "", + "input-required-email-text": "", + "invite-button": "", + "invite-field-desc": "", + "invite-field-label": "", + "learn-more-button": "", + "recipient-email-placeholder": "", + "recipient-invalid-email-text": "", + "recipient-invitation-button": "", + "recipient-invitation-description": "", + "recipient-invitation-tooltip": "", + "recipient-list-description": "", + "recipient-list-title": "", + "recipient-required-email-text": "", + "resend-button": "", + "resend-button-title": "", + "resend-invite-label": "", + "revoke-access-label": "", + "revoke-button": "", + "revoke-button-title": "", + "success-creation": "", + "success-share-type-change": "" + }, + "modal-alerts": { + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "save-dashboard-changes-alert-title": "", + "unsupport-data-source-alert-readmore-link": "", + "unsupported-data-source-alert-desc": "", + "unsupported-data-source-alert-title": "", + "unsupported-template-variable-alert-desc": "", + "unsupported-template-variable-alert-title": "" + }, + "public-sharing": { + "accept-button": "", + "alert-text": "", + "cancel-button": "", + "learn-more-button": "", + "public-ack": "", + "success-creation": "", + "success-share-type-change": "" + }, + "settings-bar-header": { + "collapse-settings-tooltip": "", + "expand-settings-tooltip": "" + }, + "settings-configuration": { + "default-time-range-label": "", + "default-time-range-label-desc": "", + "show-annotations-label": "", + "show-annotations-label-desc": "", + "time-range-picker-label": "", + "time-range-picker-label-desc": "" + }, + "settings-summary": { + "annotations-hide-text": "", + "annotations-show-text": "", + "time-range-picker-disabled-text": "", + "time-range-picker-enabled-text": "", + "time-range-text": "" + }, + "share": { + "success-delete": "", + "success-delete-old": "" + }, + "share-configuration": { + "share-type-label": "" + }, + "share-externally": { + "copy-link-button": "", + "email-share-type-option-description": "", + "email-share-type-option-label": "", + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "pause-access-button": "", + "pause-access-tooltip": "", + "public-share-type-option-description": "", + "public-share-type-option-label": "", + "resume-access-button": "", + "revoke-access-button": "", + "revoke-access-description": "", + "unsupported-data-source-alert-desc": "" + }, + "sharing": { + "success-creation": "" + } + }, + "public-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "public-dashboard-users-access-list": { + "dashboard-modal": { + "external-link": "", + "loading-text": "", + "open-dashboard-list-text": "", + "public-dashboard-link": "", + "public-dashboard-setting": "", + "sharing-setting": "" + }, + "delete-user-modal": { + "delete-user-button-text": "", + "delete-user-cancel-button": "", + "delete-user-revoke-access-button": "", + "revoke-access-title": "", + "revoke-user-access-modal-desc-line1": "", + "revoke-user-access-modal-desc-line2": "" + }, + "delete-user-shared-dashboards-modal": { + "revoke-user-access-modal-desc-line2": "" + }, + "modal": { + "dashboard-modal-title": "", + "shared-dashboard-modal-title": "" + }, + "table-body": { + "dashboard-count_one": "", + "dashboard-count_few": "", + "dashboard-count_many": "", + "dashboard-count_other": "" + }, + "table-header": { + "activated-label": "", + "activated-tooltip": "", + "email-label": "", + "last-active-label": "", + "origin-label": "", + "role-label": "" + } + }, + "query-operation": { + "header": { + "collapse-row": "", + "datasource-help": "", + "drag-and-drop": "", + "duplicate-query": "", + "expand-row": "", + "hide-response": "", + "remove-query": "", + "show-response": "", + "toggle-edit-mode": "" + }, + "query-editor-not-exported": "" + }, + "recently-deleted": { + "buttons": { + "delete": "", + "restore": "" + }, + "page": { + "no-deleted-dashboards": "", + "no-deleted-dashboards-text": "", + "no-search-result": "" + }, + "permanently-delete-modal": { + "confirm-text": "", + "delete-button": "", + "delete-loading": "", + "title": "", + "text_one": "", + "text_few": "", + "text_many": "", + "text_other": "" + }, + "restore-modal": { + "restore-button": "", + "restore-loading": "", + "title": "", + "folder-picker-text_one": "", + "folder-picker-text_few": "", + "folder-picker-text_many": "", + "folder-picker-text_other": "", + "text_one": "", + "text_few": "", + "text_many": "", + "text_other": "" + } + }, + "recentlyDeleted": { + "filter": { + "placeholder": "" + } + }, + "reduce": { + "strictMode": { + "description": "", + "title": "" + } + }, + "refresh-picker": { + "aria-label": { + "choose-interval": "", + "duration-selected": "" + }, + "auto-option": { + "aria-label": "", + "label": "" + }, + "live-option": { + "aria-label": "", + "label": "" + }, + "off-option": { + "aria-label": "", + "label": "" + }, + "tooltip": { + "interval-selected": "", + "turned-off": "" + } + }, + "return-to-previous": { + "button": { + "label": "" + }, + "dismissable-button": "" + }, + "role-picker": { + "built-in": { + "basic-roles": "" + }, + "input": { + "no-roles": "" + }, + "menu": { + "clear-button": "", + "tooltip": "" + }, + "sub-menu": { + "clear-button": "" + }, + "title": { + "description": "" + } + }, + "role-picker-drawer": { + "basic-roles": { + "label": "" + } + }, + "route-error": { + "description": "", + "reload-button": "", + "title": "" + }, + "save-dashboards": { + "message-length": { + "info": "", + "title": "" + }, + "name-exists": { + "message-info": "", + "message-suggestion": "", + "title": "" + } + }, + "scopes": { + "dashboards": { + "collapse": "", + "expand": "", + "loading": "", + "noResultsForFilter": "", + "noResultsForFilterClear": "", + "noResultsForScopes": "", + "noResultsNoScopes": "", + "search": "", + "toggle": { + "collapse": "", + "disabled": "", + "expand": "" + } + }, + "selector": { + "apply": "", + "cancel": "", + "input": { + "placeholder": "", + "removeAll": "" + }, + "title": "" + }, + "tree": { + "collapse": "", + "expand": "", + "headline": { + "noResults": "", + "recommended": "", + "results": "" + }, + "search": "" + } + }, + "search": { + "actions": { + "include-panels": "", + "remove-datasource-filter": "", + "sort-placeholder": "", + "starred": "", + "view-as-folders": "", + "view-as-list": "" + }, + "dashboard-actions": { + "import": "", + "new": "", + "new-dashboard": "", + "new-folder": "" + }, + "results-table": { + "datasource-header": "", + "deleted-less-than-1-min": "", + "deleted-remaining-header": "", + "location-header": "", + "name-header": "", + "tags-header": "", + "type-dashboard": "", + "type-folder": "", + "type-header": "" + }, + "search-input": { + "include-panels-placeholder": "", + "placeholder": "" + } + }, + "select": { + "select-menu": { + "selected-count": "" + } + }, + "service-account-create-page": { + "create": { + "button": "" + }, + "name": { + "label": "", + "required-error": "" + }, + "page-nav": { + "label": "" + }, + "role": { + "label": "" + } + }, + "service-accounts": { + "empty-state": { + "button-title": "", + "message": "", + "more-info": "", + "title": "" + } + }, + "share-dashboard": { + "menu": { + "export-json-title": "", + "share-externally-title": "", + "share-internally-title": "", + "share-snapshot-title": "" + }, + "share-button": "", + "share-button-tooltip": "" + }, + "share-drawer": { + "confirm-action": { + "back-arrow-button": "", + "cancel-button": "" + } + }, + "share-modal": { + "dashboard": { + "title": "" + }, + "embed": { + "copy": "", + "html": "", + "html-description": "", + "info": "", + "time-range": "" + }, + "export": { + "back-button": "", + "cancel-button": "", + "info-text": "", + "loading": "", + "save-button": "", + "share-externally-label": "", + "view-button": "" + }, + "library": { + "info": "" + }, + "link": { + "copy-link-button": "", + "info-text": "", + "link-url": "", + "render-alert": "", + "render-instructions": "", + "rendered-image": "", + "save-alert": "", + "save-dashboard": "", + "shorten-url": "", + "time-range-description": "", + "time-range-label": "" + }, + "panel": { + "title": "" + }, + "snapshot": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "deleted-message": "", + "expire": "", + "expire-day": "", + "expire-hour": "", + "expire-never": "", + "expire-week": "", + "info-text-1": "", + "info-text-2": "", + "local-button": "", + "mistake-message": "", + "name": "", + "timeout": "", + "timeout-description": "", + "url-label": "" + }, + "tab-title": { + "embed": "", + "export": "", + "library-panel": "", + "link": "", + "panel-embed": "", + "public-dashboard": "", + "public-dashboard-title": "", + "snapshot": "" + }, + "theme-picker": { + "current": "", + "dark": "", + "field-name": "", + "light": "" + }, + "view-json": { + "copy-button": "" + } + }, + "share-panel": { + "drawer": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "" + }, + "menu": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "", + "share-snapshot-title": "" + }, + "new-library-panel": { + "cancel-button": "", + "create-button": "" + } + }, + "share-panel-image": { + "preview": { + "title": "" + }, + "settings": { + "height-label": "", + "height-min": "", + "height-placeholder": "", + "height-required": "", + "max-warning": "", + "scale-factor-label": "", + "scale-factor-min": "", + "scale-factor-placeholder": "", + "scale-factor-required": "", + "title": "", + "width-label": "", + "width-min": "", + "width-placeholder": "", + "width-required": "" + } + }, + "share-playlist": { + "checkbox-description": "", + "checkbox-label": "", + "copy-link-button": "", + "link-url-label": "", + "mode": "", + "mode-kiosk": "", + "mode-normal": "", + "title": "" + }, + "shared": { + "preferences": { + "theme": { + "dark-label": "", + "light-label": "", + "system-label": "" + } + } + }, + "shared-dashboard": { + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "fields": { + "timezone-label": "" + } + }, + "shared-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "shared-preferences": { + "fields": { + "home-dashboard-label": "", + "home-dashboard-placeholder": "", + "locale-label": "", + "locale-placeholder": "", + "theme-description": "", + "theme-label": "", + "week-start-label": "" + }, + "theme": { + "default-label": "" + }, + "title": "" + }, + "sign-up": { + "back-button": "", + "submit-button": "", + "verify": { + "back-button": "", + "complete-button": "", + "header": "", + "info": "", + "send-button": "" + } + }, + "silences": { + "empty-state": { + "button-title": "", + "title": "" + }, + "table": { + "add-silence-button": "", + "edit-button": "", + "expired-silences": "", + "no-matching-silences": "", + "noConfig": "", + "recreate-button": "", + "unsilence-button": "" + } + }, + "silences-table": { + "header": { + "alert-name": "", + "state": "" + } + }, + "snapshot": { + "empty-state": { + "message": "", + "more-info": "" + }, + "external-badge": "", + "name-column-header": "", + "share": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "delete-description": "", + "delete-permission-tooltip": "", + "delete-title": "", + "deleted-alert": "", + "expiration-label": "", + "info-alert": "", + "learn-more-button": "", + "local-button": "", + "name-label": "", + "new-snapshot-button": "", + "success-creation": "", + "success-delete": "", + "view-all-button": "" + }, + "share-panel": { + "info-alert": "" + }, + "url-column-header": "", + "view-button": "" + }, + "table": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "" + } + }, + "tag-filter": { + "clear-button": "", + "loading": "", + "no-tags": "", + "placeholder": "" + }, + "teams": { + "empty-state": { + "button-title": "", + "message": "", + "pro-tip": "", + "title": "" + } + }, + "theme-preview": { + "breadcrumbs": { + "dashboards": "", + "home": "" + }, + "panel": { + "form-label": "", + "title": "" + } + }, + "time-picker": { + "absolute": { + "recent-title": "", + "title": "" + }, + "calendar": { + "apply-button": "", + "cancel-button": "", + "close": "", + "next-month": "", + "previous-month": "", + "select-time": "" + }, + "content": { + "empty-recent-list-docs": "", + "empty-recent-list-info": "", + "filter-placeholder": "" + }, + "copy-paste": { + "copy-success-message": "", + "default-error-message": "", + "default-error-title": "", + "tooltip-copy": "", + "tooltip-paste": "" + }, + "footer": { + "change-settings-button": "", + "fiscal-year-option": "", + "fiscal-year-start": "", + "time-zone-option": "", + "time-zone-selection": "" + }, + "range-content": { + "apply-button": "", + "default-error": "", + "fiscal-year": "", + "from-input": "", + "open-input-calendar": "", + "range-error": "", + "to-input": "" + }, + "range-picker": { + "backwards-time-aria-label": "", + "current-time-selected": "", + "forwards-time-aria-label": "", + "to": "", + "zoom-out-button": "", + "zoom-out-tooltip": "" + }, + "time-range": { + "apply": "", + "aria-role": "", + "default-title": "", + "example": "", + "example-details": "", + "example-title": "", + "from-label": "", + "from-to": "", + "more-info": "", + "specify": "", + "submit-button-label": "", + "supported-formats": "", + "to-label": "" + }, + "zone": { + "select-aria-label": "", + "select-search-input": "" + } + }, + "trails": { + "bookmarks": { + "or-view-bookmarks": "" + }, + "card": { + "date-created": "" + }, + "home": { + "learn-more": "", + "lets-start": "", + "start-your-metrics-exploration": "", + "subtitle": "" + }, + "metric-select": { + "filter-by": "", + "native-histogram": "", + "new-badge": "", + "otel-switch": "" + }, + "native-histogram-banner": { + "ch-heatmap": "", + "ch-histogram": "", + "click-histogram": "", + "hide-examples": "", + "learn-more": "", + "metric-examples": "", + "nh-heatmap": "", + "nh-histogram": "", + "now": "", + "previously": "", + "see-examples": "", + "sentence": "" + }, + "recent-metrics": { + "or-view-a-recent-exploration": "" + }, + "settings": { + "always-keep-selected-metric-graph-in-view": "", + "show-previews-of-metric-graphs": "" + } + }, + "transformations": { + "empty": { + "add-transformation-body": "", + "add-transformation-header": "" + } + }, + "upgrade-box": { + "discovery-text": "", + "discovery-text-continued": "", + "get-started": "", + "learn-more": "", + "upgrade-button": "" + }, + "user-orgs": { + "current-org-button": "", + "name-column": "", + "role-column": "", + "select-org-button": "", + "title": "" + }, + "user-profile": { + "fields": { + "email-error": "", + "email-label": "", + "name-error": "", + "name-label": "", + "username-label": "" + }, + "tabs": { + "general": "" + } + }, + "user-session": { + "auth-module-column": "", + "browser-column": "", + "created-at-column": "", + "identity-provider-column": "", + "ip-column": "", + "revoke": "", + "seen-at-column": "" + }, + "user-sessions": { + "loading": "" + }, + "users": { + "empty-state": { + "message": "" + } + }, + "users-access-list": { + "tabs": { + "public-dashboard-users-tab-title": "", + "shared-dashboard-users-tab-title": "" + } + }, + "variable": { + "adhoc": { + "placeholder": "" + }, + "dropdown": { + "placeholder": "" + }, + "picker": { + "link-all": "", + "option-all": "", + "option-selected-values": "", + "option-tooltip": "" + }, + "textbox": { + "placeholder": "" + } + }, + "variables": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + }, + "unknown-table": { + "loading": "", + "no-unknowns": "", + "renamed-or-missing-variables": "", + "variable": "" + } + } +} \ No newline at end of file diff --git a/public/locales/sv-SE/grafana.json b/public/locales/sv-SE/grafana.json new file mode 100644 index 00000000000..f3a7ee625b6 --- /dev/null +++ b/public/locales/sv-SE/grafana.json @@ -0,0 +1,4010 @@ +{ + "_comment": "", + "access-control": { + "add-permission": { + "role-label": "", + "serviceaccount-label": "", + "team-label": "", + "title": "", + "user-label": "" + }, + "add-permissions": { + "save": "" + }, + "permission-list": { + "permission": "" + }, + "permission-list-item": { + "inherited": "" + }, + "permissions": { + "add-label": "", + "no-permissions": "", + "permissions-change-warning": "", + "role": "", + "serviceaccount": "", + "team": "", + "title": "", + "user": "" + } + }, + "action-editor": { + "modal": { + "cancel-button": "", + "save-button": "" + } + }, + "admin": { + "anon-users": { + "not-found": "" + }, + "edit-org": { + "access-denied": "", + "heading": "", + "update-button": "", + "users-heading": "" + }, + "feature-toggles": { + "sub-title": "" + }, + "get-enterprise": { + "contact-us": "", + "description": "", + "features-heading": "", + "included-description": "", + "included-heading": "", + "service-title": "", + "team-sync-details": "", + "title": "" + }, + "ldap": { + "test-mapping-heading": "", + "test-mapping-run-button": "" + }, + "ldap-permissions": { + "active": "", + "admin": "", + "inactive": "" + }, + "ldap-status": { + "title": "" + }, + "ldap-sync": { + "debug-button": "", + "external-sync-description": "", + "external-sync-label": "", + "next-sync-label": "", + "not-enabled": "", + "sync-button": "", + "title": "" + }, + "ldap-sync-info": { + "title": "" + }, + "ldap-user-groups": { + "no-org-found": "" + }, + "ldap-user-info": { + "no-team": "" + }, + "org-uers": { + "last-seen-never": "" + }, + "org-users": { + "not-editable": "" + }, + "orgs": { + "delete-body": "", + "id-header": "", + "name-header": "", + "new-org-button": "" + }, + "server-settings": { + "alerts-button": "", + "dashboards-button": "", + "data-sources-button": "", + "not-found": "", + "title": "", + "users-button": "" + }, + "settings": { + "info-description": "" + }, + "upgrade-info": { + "title": "" + }, + "user-orgs": { + "add-button": "", + "change-role-button": "", + "external-user-tooltip": "", + "remove-button": "", + "role-not-editable": "", + "title": "" + }, + "user-orgs-modal": { + "add-button": "", + "cancel-button": "" + }, + "user-permissions": { + "change-button": "", + "grafana-admin-key": "", + "grafana-admin-no": "", + "grafana-admin-yes": "", + "title": "" + }, + "user-profile": { + "delete-button": "", + "disable-button": "", + "edit-button": "", + "enable-button": "", + "title": "" + }, + "user-sessions": { + "browser-column": "", + "force-logout-all-button": "", + "force-logout-button": "", + "ip-column": "", + "last-seen-column": "", + "logged-on-column": "", + "title": "" + }, + "users-create": { + "create-button": "" + }, + "users-list": { + "create-button": "" + }, + "users-table": { + "last-seen-never": "", + "no-licensed-roles": "" + } + }, + "alert-labels": { + "button": { + "hide": "", + "show": { + "tooltip": "" + } + } + }, + "alerting": { + "alert": { + "alert-state": "", + "annotations": "", + "evaluation": "", + "evaluation-paused": "", + "evaluation-paused-description": "", + "last-evaluated": "", + "last-evaluation-duration": "", + "last-updated-at": "", + "last-updated-by": "", + "no-annotations": "", + "pending-period": "", + "rule": "", + "rule-identifier": "", + "rule-type": "", + "state-error-timeout": "", + "state-no-data": "", + "target-datasource-uid": "" + }, + "alert-recording-rule-form": { + "evaluation-behaviour": { + "description": { + "text": "" + } + } + }, + "alert-rules": { + "firing-for": "", + "next-evaluation": "", + "next-evaluation-in": "", + "rule-definition": "" + }, + "alertform": { + "labels": { + "alerting": "", + "recording": "" + } + }, + "alertVersionHistory": { + "alerting": "", + "alerting-change-description": "", + "annotations": "", + "compare": "", + "compare-with-latest": "", + "compareVersions": "", + "comparing-versions": "", + "condition": "", + "contactPointRouting": "", + "description": "", + "errorloading": "", + "execErrorState": "", + "intervalSeconds": "", + "labels": "", + "latest": "", + "name": "", + "namespace_uid": "", + "noDataState": "", + "noVersionsFound": "", + "paused": "", + "pendingPeriod": "", + "provisioning": "", + "provisioning-change-description": "", + "queryAndAlertCondition": "", + "restore": "", + "restore-manually": "", + "restore-modal": { + "body": "", + "confirm": "", + "error": "", + "summary": "", + "title": "" + }, + "restore-version": "", + "rule_group": "", + "unknown": "", + "unknown-change-description": "", + "user-id": "", + "warning-restore-manually": "", + "warning-restore-manually-title": "" + }, + "annotations": { + "description": "", + "title": "" + }, + "central-alert-history": { + "details": { + "error": "", + "header": { + "alert-rule": "", + "instance": "", + "state": "", + "timestamp": "" + }, + "loading": "", + "no-recognized-state": "", + "no-values": "", + "not-found": "", + "number-transitions": "", + "state": { + "alerting": "", + "error": "", + "no-data": "", + "normal": "", + "pending": "" + }, + "state-transitions": "", + "unknown-event-state": "", + "unknown-rule": "", + "value-in-transition": "" + }, + "error": "", + "filter": { + "clear": "", + "info": { + "label1": "", + "label2": "", + "label3": "", + "label4": "" + } + }, + "filterBy": "", + "too-many-events": { + "text": "", + "title": "" + } + }, + "common": { + "cancel": "", + "clear-filters": "", + "delete": "", + "edit": "", + "export": "", + "export-all": "", + "loading": "", + "search-by-matchers": "", + "titles": { + "notification-templates": "" + }, + "view": "" + }, + "contact-points": { + "create": "", + "custom-template-value": "", + "delete-reasons": { + "heading": "", + "no-permissions": "", + "policies": "", + "provisioned": "", + "rules": "" + }, + "delivered-to": "", + "delivery-duration": "", + "empty-state": { + "title": "" + }, + "key-value-map": { + "add": "", + "confirm-add": "" + }, + "last-delivery-attempt": "", + "last-delivery-failed": "", + "no-contact-points-found": "", + "no-delivery-attempts": "", + "no-integrations": "", + "only-firing": "", + "receiver-summary": { + "jira": "" + }, + "telegram": { + "parse-mode-warning-body": "", + "parse-mode-warning-title": "" + }, + "used-by_one": "", + "used-by_other": "", + "used-by-rules_one": "", + "used-by-rules_other": "" + }, + "contactPointFilter": { + "label": "" + }, + "copy-to-clipboard": "", + "dag": { + "missing-reference": "", + "self-reference": "" + }, + "export": { + "subtitle": { + "formats": "", + "one-format": "" + } + }, + "folderAndGroup": { + "evaluation": { + "modal": { + "text": { + "alerting": "", + "recording": "" + } + } + } + }, + "group-actions": { + "actions-trigger": "", + "delete": "", + "edit": "", + "export": "", + "reorder": "" + }, + "list-view": { + "empty": { + "new-alert-rule": "", + "new-recording-rule": "", + "provisioning": "" + }, + "section": { + "dataSourceManaged": { + "title": "" + }, + "grafanaManaged": { + "export-new-rule": "", + "export-rules": "", + "loading": "", + "new-recording-rule": "", + "title": "" + } + } + }, + "manage-permissions": { + "button": "", + "title": "" + }, + "mute_timings": { + "error-loading": { + "description": "", + "title": "" + } + }, + "mute-timings": { + "add-mute-timing": "", + "description": "", + "save": "", + "saving": "" + }, + "notification-preview": { + "alertmanager": "", + "error": "", + "initialized": "", + "preview-routing": "", + "title": "", + "uninitialized": "" + }, + "notification-templates": { + "duplicate": { + "subTitle": "", + "title": "" + }, + "edit": { + "subTitle": "", + "title": "" + }, + "new": { + "subTitle": "", + "title": "" + } + }, + "policies": { + "default-policy": { + "description": "", + "title": "", + "update": "" + }, + "delete": { + "confirm": "", + "warning-1": "", + "warning-2": "" + }, + "filter-description": "", + "generated-policies": "", + "matchers": "", + "metadata": { + "active-time": "", + "delivered-to": "", + "grouped-by": "", + "grouping": { + "none": "", + "single-group": "" + }, + "inherited": "", + "mute-time": "", + "timingOptions": { + "groupInterval": { + "description": "", + "label": "" + }, + "groupWait": { + "description": "", + "label": "" + }, + "repeatInterval": { + "description": "", + "label": "" + } + }, + "n-instances_one": "", + "n-instances_other": "" + }, + "new-child": "", + "new-policy": "", + "no-matchers": "", + "reload-policies": "", + "save-policy": "", + "update": { + "please-wait": "", + "update-policy": "", + "updating": "" + }, + "update-errors": { + "conflict": "", + "error-code": "", + "fallback": "", + "suffix": "", + "title": "" + }, + "n-more-policies_one": "", + "n-more-policies_other": "" + }, + "provisioning": { + "badge-tooltip-provenance": "", + "badge-tooltip-standard": "" + }, + "queryAndExpressionsStep": { + "disableAdvancedOptions": { + "text": "" + }, + "preview": "", + "previewCondition": "" + }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, + "rule-form": { + "evaluation": { + "evaluation-group-and-interval": "", + "group": { + "cancel": "", + "create": "", + "interval": "" + }, + "group-name": "", + "group-text": "", + "new-group": "", + "pause": { + "alerting": "", + "recording": "" + }, + "select-folder-before": "" + }, + "evaluation-behaviour": { + "description": { + "text": "" + }, + "info-help": { + "text": "" + }, + "pending-period": "" + }, + "evaluation-behaviour-description1": "", + "evaluation-behaviour-description2": "", + "evaluation-behaviour-description3": "", + "evaluation-behaviour-for": { + "error-parsing": "", + "validation": "" + }, + "folder": { + "cancel": "", + "create": "", + "create-folder": "", + "creating-new-folder": "", + "label": "", + "name": "", + "new-folder": "", + "new-folder-or": "" + }, + "folder-and-labels": "", + "folders": { + "help-info": "" + }, + "labels": { + "help-info": "" + }, + "pause": { + "label": "" + }, + "threshold": { + "recovery": { + "stop-alerting-above": "", + "stop-alerting-bellow": "", + "stop-alerting-equal": "", + "stop-alerting-inside-range": "", + "stop-alerting-less": "", + "stop-alerting-more": "", + "stop-alerting-not-equal": "", + "stop-alerting-outside-range": "", + "title": "" + } + } + }, + "rule-groups": { + "delete": { + "success": "" + }, + "move": { + "success": "" + }, + "rename": { + "success": "" + }, + "update": { + "success": "" + } + }, + "rule-list": { + "configure-datasource": "", + "ds-error-boundary": { + "description": "", + "title": "" + }, + "filter-view": { + "no-more-results": "", + "no-rules-found": "" + }, + "new-alert-rule": "", + "pagination": { + "next-page": "", + "previous-page": "" + }, + "return-button": { + "title": "" + }, + "rulerrule-loading-error": "" + }, + "rule-state": { + "creating": "", + "deleting": "", + "paused": "", + "recording-rule": "" + }, + "rule-view": { + "query": { + "datasources-na": { + "description": "", + "title": "" + } + } + }, + "rule-viewer": { + "error-loading": "", + "prometheus-consistency-check": { + "alert-message": "", + "alert-title": "" + } + }, + "rules": { + "add-rule": { + "success": "" + }, + "delete-rule": { + "success": "" + }, + "pause-rule": { + "success": "" + }, + "resume-rule": { + "success": "" + }, + "update-rule": { + "success": "" + } + }, + "search": { + "property": { + "data-source": "", + "evaluation-group": "", + "labels": "", + "namespace": "", + "rule-health": "", + "rule-name": "", + "rule-type": "", + "state": "" + }, + "save-query": "" + }, + "silences": { + "affected-instances": "", + "only-firing-instances": "", + "preview-affected-instances": "" + }, + "simpleCondition": { + "alertCondition": "" + }, + "templates": { + "editor": { + "add-example": "", + "auto-complete": "", + "goto-docs": "" + }, + "help": { + "intro": "" + }, + "misconfigured-badge-text": "", + "misconfigured-warning": "", + "misconfigured-warning-details": "" + }, + "threshold": { + "to": "" + } + }, + "annotations": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + } + }, + "api-keys": { + "empty-state": { + "message": "" + } + }, + "app-chrome": { + "skip-content-button": "", + "top-bar": { + "sign-in": "" + } + }, + "app-notification": { + "item": { + "trace-id": "" + } + }, + "bookmarks-page": { + "empty": { + "message": "", + "tip": "" + } + }, + "bouncing-loader": { + "label": "" + }, + "browse-dashboards": { + "action": { + "cancel-button": "", + "cannot-move-folders": "", + "confirmation-text": "", + "delete-button": "", + "delete-modal-invalid-text": "", + "delete-modal-invalid-title": "", + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "delete-modal-title": "", + "deleting": "", + "manage-permissions-button": "", + "move-button": "", + "move-modal-alert": "", + "move-modal-field-label": "", + "move-modal-text": "", + "move-modal-title": "", + "moving": "", + "new-folder-name-required-phrase": "" + }, + "actions": { + "button-to-recently-deleted": "" + }, + "counts": { + "alertRule_one": "", + "alertRule_other": "", + "dashboard_one": "", + "dashboard_other": "", + "folder_one": "", + "folder_other": "", + "libraryPanel_one": "", + "libraryPanel_other": "", + "total_one": "", + "total_other": "" + }, + "dashboards-tree": { + "collapse-folder-button": "", + "expand-folder-button": "", + "name-column": "", + "select-all-header-checkbox": "", + "select-checkbox": "", + "tags-column": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "", + "title-folder": "" + }, + "folder-actions-button": { + "delete": "", + "folder-actions": "", + "manage-permissions": "", + "move": "" + }, + "folder-picker": { + "accessible-label": "", + "button-label": "", + "clear-selection": "", + "empty-message": "", + "error-title": "", + "non-folder-item": "", + "search-placeholder": "", + "unknown-error": "" + }, + "hard-delete": { + "success": "" + }, + "manage-folder-nav": { + "alert-rules": "", + "dashboards": "", + "panels": "" + }, + "new-folder-form": { + "cancel-label": "", + "create-label": "", + "name-label": "" + }, + "no-results": { + "clear": "", + "text": "" + }, + "soft-delete": { + "success": "" + } + }, + "clipboard-button": { + "inline-toast": { + "success": "" + } + }, + "combobox": { + "async": { + "error": "" + }, + "clear": { + "title": "" + }, + "custom-value": { + "description": "" + }, + "group": { + "undefined": "" + }, + "options": { + "no-found": "" + } + }, + "command-palette": { + "action": { + "change-theme": "", + "dark-theme": "", + "light-theme": "" + }, + "empty-state": { + "message": "" + }, + "search-box": { + "placeholder": "" + }, + "section": { + "actions": "", + "dashboard-search-results": "", + "folder-search-results": "", + "pages": "", + "preferences": "", + "recent-dashboards": "" + } + }, + "common": { + "apply": "", + "cancel": "", + "clear": "", + "close": "", + "collapse": "", + "edit": "", + "help": "", + "loading": "", + "locale": { + "default": "" + }, + "save": "", + "search": "", + "view": "" + }, + "configuration-tracker": { + "config-card": { + "complete": "" + } + }, + "connections": { + "connect-data": { + "category-header-label": "", + "empty-message": "", + "request-data-source": "", + "roadmap": "" + }, + "search": { + "placeholder": "" + } + }, + "core": { + "versionHistory": { + "comparison": { + "header": { + "hide-json-diff": "", + "show-json-diff": "", + "text": "" + }, + "select": "" + }, + "no-properties-changed": "", + "table": { + "updated": "", + "updatedBy": "", + "version": "" + }, + "view-json-diff": "" + } + }, + "correlations": { + "add-new": "", + "alert": { + "error-message": "", + "title": "" + }, + "basic-info-form": { + "description-description": "", + "description-label": "", + "label-description": "", + "label-label": "", + "label-placeholder": "", + "label-required": "", + "sub-text": "", + "title": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + }, + "list": { + "delete": "", + "label": "", + "loading": "", + "read-only": "", + "source": "", + "target": "" + }, + "navigation-form": { + "add-button": "", + "back-button": "", + "next-button": "", + "save-button": "" + }, + "page-content": "", + "page-heading": "", + "query-editor": { + "control-rules": "", + "data-source-text": "", + "data-source-title": "", + "error-text": "", + "error-title": "", + "loading": "", + "query-description": "", + "query-editor-title": "", + "query-label": "" + }, + "source-form": { + "control-required": "", + "description": "", + "description-external-pre": "", + "description-query-pre": "", + "external-title": "", + "heading-external": "", + "heading-query": "", + "query-title": "", + "results-description": "", + "results-label": "", + "results-required": "", + "source-description": "", + "source-label": "", + "sub-text": "" + }, + "sub-title": "", + "target-form": { + "control-rules": "", + "sub-text": "", + "target-description-external": "", + "target-description-query": "", + "target-label": "", + "target-type-description": "", + "title": "", + "type-label": "" + }, + "trans-details": { + "logfmt-description": "", + "logfmt-label": "", + "regex-description": "", + "regex-expression": "", + "regex-label": "", + "regex-map-values": "" + }, + "transform": { + "add-button": "", + "heading": "", + "no-transform": "" + }, + "transform-row": { + "expression-label": "", + "expression-required": "", + "expression-tooltip": "", + "field-input": "", + "field-label": "", + "field-tooltip": "", + "map-value-label": "", + "map-value-tooltip": "", + "remove-button": "", + "remove-tooltip": "", + "transform-required": "", + "type-label": "", + "type-tooltip": "" + } + }, + "dashboard": { + "add-menu": { + "import": "", + "paste-panel": "", + "row": "", + "visualization": "" + }, + "alert-rules-drawer": { + "redirect-link": "", + "subtitle": "" + }, + "default-layout": { + "description": "", + "item-options": { + "repeat": { + "direction": { + "horizontal": "", + "title": "", + "vertical": "" + }, + "max": "", + "title": "", + "variable": { + "description": "", + "title": "" + } + } + }, + "name": "", + "row-actions": { + "delete": "", + "modal": { + "alt-action": "", + "text": "", + "title": "" + } + }, + "row-options": { + "button": { + "label": "" + }, + "form": { + "cancel": "", + "repeat-for": { + "label": "", + "learn-more": "", + "warning": { + "text": "" + } + }, + "title": "", + "update": "" + }, + "modal": { + "title": "" + }, + "repeat": { + "title": "", + "variable": { + "title": "" + } + }, + "title": "" + } + }, + "edit-pane": { + "elements": { + "dashboard": "", + "objects": "", + "panel": "", + "panels": "", + "row": "", + "rows": "", + "tab": "", + "tabs": "" + }, + "open": "", + "row": { + "header": { + "hide": "", + "title": "" + } + } + }, + "editpane": { + "add": "", + "configure": "", + "outline": "" + }, + "empty": { + "add-library-panel-body": "", + "add-library-panel-button": "", + "add-library-panel-header": "", + "add-visualization-body": "", + "add-visualization-button": "", + "add-visualization-header": "", + "import-a-dashboard-body": "", + "import-a-dashboard-header": "", + "import-dashboard-button": "" + }, + "errors": { + "failed-to-load": "" + }, + "inspect": { + "data-tab": "", + "error-tab": "", + "json-tab": "", + "meta-tab": "", + "query-tab": "", + "stats-tab": "", + "subtitle": "", + "title": "" + }, + "inspect-data": { + "data-options": "", + "dataframe-aria-label": "", + "dataframe-label": "", + "download-csv": "", + "download-excel-description": "", + "download-excel-label": "", + "download-logs": "", + "download-service": "", + "download-traces": "", + "excel-header": "", + "formatted": "", + "formatted-data-description": "", + "formatted-data-label": "", + "panel-transforms": "", + "series-to-columns": "", + "transformation": "", + "transformations-description": "", + "transformations-label": "" + }, + "inspect-json": { + "dataframe-description": "", + "dataframe-label": "", + "panel-data-description": "", + "panel-data-label": "", + "panel-json-description": "", + "panel-json-label": "", + "select-source": "", + "unknown": "" + }, + "inspect-meta": { + "no-inspector": "" + }, + "inspect-stats": { + "data-title": "", + "data-traceids": "", + "processing-time": "", + "queries": "", + "request-time": "", + "rows": "", + "table-title": "" + }, + "layout": { + "common": { + "copy": "", + "copy-or-duplicate": "", + "delete": "", + "duplicate": "", + "layout": "" + } + }, + "options": { + "description": "", + "title-option": "" + }, + "outline": { + "tree": { + "item": { + "collapse": "", + "empty": "", + "expand": "" + } + } + }, + "panel-edit": { + "alerting-tab": { + "dashboard-not-saved": "", + "no-rules": "" + } + }, + "responsive-layout": { + "description": "", + "item-options": { + "hide-no-data": "", + "repeat": { + "variable": { + "description": "", + "title": "" + } + }, + "title": "" + }, + "name": "", + "options": { + "columns": "", + "fixed": "", + "min": "", + "one-column": "", + "rows": "", + "three-columns": "", + "two-columns": "" + } + }, + "rows-layout": { + "description": "", + "name": "", + "option": { + "height": "", + "hide-header": "", + "repeat": "", + "title": "" + }, + "options": { + "height-expand": "", + "height-min": "" + }, + "row": { + "collapse": "", + "expand": "", + "menu": { + "add": "", + "add-panel": "", + "add-row-above": "", + "add-row-below": "", + "move-down": "", + "move-row": "", + "move-up": "" + }, + "new": "", + "repeat": { + "learn-more": "", + "warning": "" + } + }, + "row-options": { + "title-option": "" + } + }, + "tabs-layout": { + "description": "", + "menu": { + "move-tab": "" + }, + "name": "", + "tab": { + "menu": { + "add": "", + "add-panel": "", + "add-tab-above": "", + "add-tab-after": "", + "add-tab-before": "", + "move-left": "", + "move-right": "" + }, + "new": "" + }, + "tab-options": { + "title-option": "" + } + }, + "toolbar": { + "add": "", + "add-panel": "", + "add-panel-description": "", + "add-panel-lib": "", + "add-row": "", + "add-tab": "", + "alert-rules": "", + "back-to-dashboard": "", + "dashboard-settings": { + "label": "", + "tooltip": "" + }, + "discard-library-panel-changes": "", + "discard-panel": "", + "discard-panel-new": "", + "edit": { + "label": "", + "tooltip": "" + }, + "edit-dashboard-v2-schema": "", + "enter-edit-mode": { + "label": "", + "tooltip": "" + }, + "exit-edit-mode": { + "label": "", + "tooltip": "" + }, + "libray-panel-description": "", + "mark-favorite": "", + "more-save-options": "", + "open-original": "", + "playlist-next": "", + "playlist-previous": "", + "playlist-stop": "", + "public-dashboard": "", + "refresh": "", + "row-description": "", + "save": "", + "save-dashboard": { + "label": "", + "tooltip": "" + }, + "save-dashboard-copy": { + "label": "", + "tooltip": "" + }, + "save-dashboard-short": "", + "save-library-panel": "", + "settings": "", + "share": { + "label": "", + "tooltip": "" + }, + "share-button": "", + "show-hidden-elements": "", + "switch-old-dashboard": "", + "tabs-description": "", + "unlink-library-panel": "", + "unmark-favorite": "" + }, + "validation": { + "invalid-dashboard-id": "", + "invalid-json": "", + "tags-expected-array": "", + "tags-expected-strings": "" + }, + "viz-panel": { + "options": { + "description": "", + "open-edit": "", + "plugin-type-image": "", + "title-option": "", + "transparent-background": "" + } + } + }, + "dashboard-import": { + "file-dropzone": { + "primary-text": "", + "secondary-text": "" + }, + "form-actions": { + "cancel": "", + "load": "" + }, + "gcom-field": { + "label": "", + "load-button": "", + "placeholder": "", + "validation-required": "" + }, + "json-field": { + "label": "", + "validation-required": "" + } + }, + "dashboard-links": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "title": "" + } + }, + "dashboard-settings": { + "annotations": { + "title": "" + }, + "dashboard-delete-button": "", + "delete-modal": { + "confirmation-text": "", + "delete-button": "", + "title": "" + }, + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "general": { + "auto-refresh-description": "", + "auto-refresh-label": "", + "description-label": "", + "editable-description": "", + "editable-label": "", + "folder-label": "", + "panel-options-graph-tooltip-description": "", + "panel-options-graph-tooltip-label": "", + "panel-options-label": "", + "panels-preload-description": "", + "panels-preload-label": "", + "tags-label": "", + "title": "", + "title-label": "" + }, + "json-editor": { + "save-button": "", + "subtitle": "", + "title": "" + }, + "links": { + "title": "" + }, + "permissions": { + "title": "" + }, + "provisioned-delete-modal": { + "confirm-button": "", + "text-1": "", + "text-2": "", + "text-3": "", + "text-link": "", + "title": "" + }, + "settings": { + "title": "" + }, + "time-picker": { + "hide-time-picker": "", + "now-delay-description": "", + "now-delay-label": "", + "refresh-live-dashboards-description": "", + "refresh-live-dashboards-label": "", + "time-options-label": "", + "time-zone-label": "", + "week-start-label": "" + }, + "time-regions": { + "advanced-description-cron": "", + "advanced-description-rest": "", + "advanced-description-use": "", + "advanced-label": "" + }, + "variables": { + "title": "" + }, + "versions": { + "title": "" + } + }, + "dashboards": { + "panel-edit": { + "angular-deprecation-button-open-panel-json": "", + "angular-deprecation-description": "", + "angular-deprecation-heading": "" + }, + "panel-queries": { + "add-query-from-library": "" + }, + "settings": { + "variables": { + "dependencies": { + "button": "", + "title": "" + } + } + } + }, + "data-source-list": { + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + } + }, + "data-source-picker": { + "add-new-data-source": "", + "built-in-list": { + "description-dashboard": "", + "description-grafana": "", + "description-mixed": "" + }, + "list": { + "no-data-source-message": "" + }, + "modal": { + "configure-new-data-source": "", + "input-placeholder": "", + "title": "" + }, + "open-advanced-button": "" + }, + "data-source-testing-status-page": { + "error-more-details-link": "", + "success-more-details-links": "" + }, + "data-sources": { + "datasource-add-button": { + "label": "" + }, + "empty-state": { + "message": "" + } + }, + "embed": { + "share": { + "time-range-description": "", + "time-range-label": "" + } + }, + "empty-list-cta": { + "pro-tip": "" + }, + "entity-not-found": { + "description": "" + }, + "errors": { + "dashboard-settings": { + "annotations": { + "datasource": "" + } + } + }, + "explore": { + "add-to-dashboard": "", + "drilldownInfo": { + "action": "", + "description": "", + "title": "" + }, + "logs": { + "logs-volume": { + "add-filters": "", + "decrease-timerange": "", + "much-data": "" + }, + "maximum-pinned-logs": "", + "no-logs-found": "", + "scan-for-older-logs": "", + "stop-scan": "" + }, + "rich-history": { + "close-tooltip": "", + "datasource-a-z": "", + "datasource-z-a": "", + "newest-first": "", + "oldest-first": "", + "query-history": "", + "query-library": "", + "settings": "", + "starred": "" + }, + "rich-history-card": { + "add-comment-form": "", + "add-comment-tooltip": "", + "add-to-library": "", + "cancel": "", + "confirm-delete": "", + "copy-query-tooltip": "", + "copy-shortened-link-tooltip": "", + "datasource-icon-label": "", + "datasource-name-label": "", + "datasource-not-exist": "", + "delete-query-confirmation-title": "", + "delete-query-title": "", + "delete-query-tooltip": "", + "delete-starred-query-confirmation-text": "", + "edit-comment-tooltip": "", + "optional-description": "", + "query-comment-label": "", + "query-text-label": "", + "save-comment": "", + "star-query-tooltip": "", + "unstar-query-tooltip": "", + "update-comment-form": "" + }, + "rich-history-container": { + "loading": "" + }, + "rich-history-notification": { + "query-copied": "", + "query-deleted": "" + }, + "rich-history-queries-tab": { + "displaying-partial-queries": "", + "displaying-queries": "", + "filter-aria-label": "", + "filter-history": "", + "filter-placeholder": "", + "history-local": "", + "loading": "", + "loading-results": "", + "search-placeholder": "", + "showing-queries": "", + "sort-aria-label": "", + "sort-placeholder": "" + }, + "rich-history-settings-tab": { + "alert-info": "", + "change-default-tab": "", + "clear-history-info": "", + "clear-query-history": "", + "clear-query-history-button": "", + "delete-confirm": "", + "delete-confirm-text": "", + "delete-title": "", + "history-time-span": "", + "history-time-span-description": "", + "only-show-active-datasource": "", + "query-history-deleted": "", + "retention-period": { + "1-week": "", + "2-days": "", + "2-weeks": "", + "5-days": "" + } + }, + "rich-history-starred-tab": { + "filter-queries-aria-label": "", + "filter-queries-placeholder": "", + "loading": "", + "loading-results": "", + "local-history-message": "", + "search-queries-placeholder": "", + "showing-queries": "", + "sort-queries-aria-label": "", + "sort-queries-placeholder": "" + }, + "rich-history-utils": { + "a-week-ago": "", + "days-ago": "", + "default-from": "", + "default-to": "", + "today": "", + "two-weeks-ago": "", + "yesterday": "" + }, + "rich-history-utils-notification": { + "saving-failed": "", + "update-failed": "" + }, + "run-query": { + "left-pane": "", + "right-pane": "", + "run-query-button": "", + "switch-datasource-button": "" + }, + "secondary-actions": { + "add-from-query-library": "", + "query-add-button": "", + "query-add-button-aria-label": "", + "query-history-button": "", + "query-history-button-aria-label": "", + "query-inspector-button": "", + "query-inspector-button-aria-label": "" + }, + "table": { + "no-data": "", + "title": "", + "title-with-name": "" + }, + "toolbar": { + "add-to-extensions": "", + "add-to-queryless-extensions": "", + "aria-label": "", + "copy-link": "", + "copy-link-abs-time": "", + "copy-links-absolute-category": "", + "copy-links-normal-category": "", + "copy-shortened-link": "", + "copy-shortened-link-abs-time": "", + "copy-shortened-link-label": "", + "copy-shortened-link-menu": "", + "refresh-picker-cancel": "", + "refresh-picker-run": "", + "split-close": "", + "split-close-tooltip": "", + "split-narrow": "", + "split-title": "", + "split-tooltip": "", + "split-widen": "" + } + }, + "explore-metrics": { + "breakdown": { + "clearFilter": "", + "labelSelect": "", + "missing-otel-labels": "", + "noMatchingValue": "", + "sortBy": "" + }, + "related-logs": { + "LrrDocsLink": "", + "openExploreLogs": "", + "relatedLogsUnavailable": "", + "warnExperimentalFeature": "" + }, + "viewBy": "" + }, + "export": { + "json": { + "cancel-button": "", + "copy-button": "", + "download-button": "", + "download-successful_toast_message": "", + "export-externally-label": "", + "info-text": "", + "title": "" + }, + "menu": { + "export-as-json-label": "", + "export-as-json-tooltip": "" + } + }, + "folder-filter": { + "clear-folder-button": "" + }, + "folder-picker": { + "create-instructions": "", + "loading": "" + }, + "forgot-password": { + "back-button": "", + "change-password": { + "skip-button": "", + "submit-button": "" + }, + "contact-admin": "", + "email-sent": "", + "reset-password-header": "", + "send-email-button": "" + }, + "form-prompt": { + "continue-button": "", + "description": "", + "discard-button": "" + }, + "gen-ai": { + "apply-suggestion": "", + "incomplete-request-error": "", + "send-custom-feedback": "" + }, + "get-enterprise": { + "requires-license": "", + "title": "" + }, + "grafana-ui": { + "action-editor": { + "button": { + "confirm": "", + "confirm-action": "" + }, + "inline": { + "add-action": "", + "edit-action": "" + }, + "modal": { + "action-body": "", + "action-method": "", + "action-query-params": "", + "action-title": "", + "action-title-placeholder": "", + "one-click-description": "" + } + }, + "alert": { + "close-button": "" + }, + "auto-save-field": { + "saved": "", + "saving": "" + }, + "card": { + "option": "" + }, + "cascader": { + "clear-button": "" + }, + "color-picker-popover": { + "palette-tab": "", + "spectrum-tab": "" + }, + "confirm-button": { + "cancel": "" + }, + "confirm-content": { + "placeholder": "" + }, + "data-link-editor": { + "info": "", + "new-tab-label": "", + "title-label": "", + "title-placeholder": "", + "url-label": "" + }, + "data-link-editor-modal": { + "cancel": "", + "one-click-description": "", + "save": "" + }, + "data-link-inline-editor": { + "one-click": "" + }, + "data-links-inline-editor": { + "add-link": "", + "edit-link": "", + "one-click": "", + "one-click-enabled": "", + "title-not-provided": "", + "tooltip-edit": "", + "tooltip-remove": "", + "url-not-provided": "" + }, + "data-source-basic-auth-settings": { + "user-label": "", + "user-placeholder": "" + }, + "data-source-http-proxy-settings": { + "oauth-identity-label": "", + "oauth-identity-tooltip": "", + "skip-tls-verify-label": "", + "ts-client-auth-label": "", + "with-ca-cert-label": "", + "with-ca-cert-tooltip": "" + }, + "data-source-http-settings": { + "access-help": "", + "access-help-details": "", + "access-label": "", + "access-options-browser": "", + "access-options-proxy": "", + "allowed-cookies": "", + "allowed-cookies-tooltip": "", + "auth": "", + "azure-auth-label": "", + "azure-auth-tooltip": "", + "basic-auth": "", + "basic-auth-label": "", + "browser-mode-description": "", + "browser-mode-title": "", + "default-url-access-select": "", + "default-url-tooltip": "", + "direct-url-tooltip": "", + "heading": "", + "proxy-url-tooltip": "", + "server-mode-description": "", + "server-mode-title": "", + "timeout-form-label": "", + "timeout-label": "", + "timeout-tooltip": "", + "url-label": "", + "with-credential-label": "", + "with-credential-tooltip": "" + }, + "data-source-settings": { + "alerting-settings-heading": "", + "alerting-settings-label": "", + "alerting-settings-tooltip": "", + "cert-key-reset": "", + "custom-headers-add": "", + "custom-headers-header": "", + "custom-headers-header-placeholder": "", + "custom-headers-header-remove": "", + "custom-headers-header-value": "", + "custom-headers-title": "", + "secure-socks-heading": "", + "secure-socks-label": "", + "secure-socks-tooltip": "", + "tls-certification-label": "", + "tls-certification-placeholder": "", + "tls-client-certification-label": "", + "tls-client-key-label": "", + "tls-client-key-placeholder": "", + "tls-heading": "", + "tls-server-name-label": "", + "tls-tooltip": "" + }, + "date-time-picker": { + "apply": "", + "calendar-icon-label": "", + "cancel": "", + "next-label": "", + "previous-label": "", + "select-placeholder": "" + }, + "drawer": { + "close": "" + }, + "feature-badge": { + "experimental": "", + "new": "", + "preview": "", + "private-preview": "" + }, + "field-link-list": { + "external-links-heading": "" + }, + "file-dropzone": { + "cancel-upload": "", + "file-too-large": "" + }, + "filter-input": { + "clear": "" + }, + "modal": { + "close-tooltip": "" + }, + "named-colors-palette": { + "text-color-swatch": "", + "transparent-swatch": "" + }, + "page-toolbar": { + "go-back": "", + "search-dashboard-name": "", + "search-links": "", + "search-parent-folder": "" + }, + "pagination": { + "next-page": "", + "previous-page": "" + }, + "secret-form-field": { + "reset": "" + }, + "segment-async": { + "error": "", + "loading": "", + "no-options": "" + }, + "select": { + "default-create-label": "", + "no-options-label": "", + "placeholder": "" + }, + "series-color-picker-popover": { + "y-axis-usage": "" + }, + "spinner": { + "aria-label": "" + }, + "table": { + "copy": "", + "csv-counts": "", + "filter-popup-apply": "", + "filter-popup-cancel": "", + "filter-popup-clear": "", + "filter-popup-heading": "", + "no-values-label": "", + "pagination-summary": "" + }, + "tags-input": { + "add": "" + }, + "user-icon": { + "active-text": "" + }, + "value-pill": { + "remove-button": "" + }, + "viz-legend": { + "right-axis-indicator": "" + }, + "viz-tooltip": { + "actions-confirmation-input-placeholder": "", + "actions-confirmation-label": "", + "actions-confirmation-message": "", + "footer-add-annotation": "", + "footer-click-to-action": "", + "footer-click-to-navigate": "" + } + }, + "graph": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "", + "title": "" + } + }, + "help-modal": { + "column-headers": { + "description": "", + "keys": "" + }, + "shortcuts-category": { + "dashboard": "", + "focused-panel": "", + "global": "", + "time-range": "" + }, + "shortcuts-description": { + "change-theme": "", + "collapse-all-rows": "", + "copy-time-range": "", + "dashboard-settings": "", + "duplicate-panel": "", + "exit-edit/setting-views": "", + "expand-all-rows": "", + "go-to-dashboards": "", + "go-to-explore": "", + "go-to-home-dashboard": "", + "go-to-profile": "", + "make-time-range-permanent": "", + "move-time-range-back": "", + "move-time-range-forward": "", + "open-search": "", + "open-shared-modal": "", + "paste-time-range": "", + "refresh-all-panels": "", + "remove-panel": "", + "save-dashboard": "", + "show-all-shortcuts": "", + "toggle-active-mode": "", + "toggle-all-panel-legends": "", + "toggle-auto-fit": "", + "toggle-exemplars": "", + "toggle-graph-crosshair": "", + "toggle-kiosk": "", + "toggle-panel-edit": "", + "toggle-panel-fullscreen": "", + "toggle-panel-legend": "", + "zoom-out-time-range": "" + }, + "title": "" + }, + "help-wizard": { + "download-snapshot": "", + "github-comment": "", + "support-bundle": "", + "troubleshooting-help": "" + }, + "inspector": { + "query": { + "collapse-all": "", + "copy-to-clipboard": "", + "description": "", + "expand-all": "", + "no-data": "", + "refresh": "" + } + }, + "ldap-drawer": { + "attributes-section": { + "description": "", + "email-label": "", + "label": "", + "member-of-label": "", + "name-label": "", + "surname-label": "", + "username-label": "" + }, + "extra-security-section": { + "client-cert-label": "", + "client-cert-placeholder": "", + "client-cert-value-label": "", + "client-cert-value-placeholder": "", + "client-key-label": "", + "client-key-placeholder": "", + "client-key-value-label": "", + "client-key-value-placeholder": "", + "encryption-provider-base-64": "", + "encryption-provider-description": "", + "encryption-provider-file-path": "", + "encryption-provider-label": "", + "label": "", + "min-tls-version-description": "", + "min-tls-version-label": "", + "root-ca-cert-label": "", + "root-ca-cert-placeholder": "", + "root-ca-cert-value-label": "", + "root-ca-cert-value-placeholder": "", + "start-tls-description": "", + "start-tls-label": "", + "tls-ciphers-label": "", + "tls-ciphers-placeholder": "", + "use-ssl-description": "", + "use-ssl-label": "", + "use-ssl-tooltip": "" + }, + "group-mapping": { + "grafana-admin": { + "description": "", + "label": "" + }, + "group-dn": { + "description": "", + "label": "" + }, + "org-id": { + "description": "", + "label": "" + }, + "org-role": { + "label": "" + }, + "remove": { + "button": "" + } + }, + "group-mapping-section": { + "add": { + "button": "" + }, + "description": "", + "group-search-base-dns-label": "", + "group-search-base-dns-placeholder": "", + "group-search-filter-description": "", + "group-search-filter-label": "", + "group-search-filter-user-attribute-description": "", + "group-search-filter-user-attribute-label": "", + "label": "", + "skip-org-role-sync-description": "", + "skip-org-role-sync-label": "" + }, + "misc-section": { + "allow-sign-up-descrition": "", + "allow-sign-up-label": "", + "label": "", + "port-description": "", + "port-label": "", + "timeout-description": "", + "timeout-label": "" + }, + "title": "" + }, + "ldap-settings-page": { + "advanced-settings-section": { + "edit-button": "", + "subtitle": "", + "title": "" + }, + "alert": { + "discard-success": "", + "error-fetching": "", + "error-saving": "", + "error-validate-form": "", + "feature-flag-disabled": "", + "saved": "" + }, + "bind-dn": { + "description": "", + "label": "", + "placeholder": "" + }, + "bind-password": { + "label": "" + }, + "buttons-section": { + "disable-button": "", + "discard-button": "", + "save-and-enable-button": "", + "save-button": "" + }, + "documentation": "", + "host": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "login-form-alert": { + "description": "", + "title": "" + }, + "search_filter": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "search-base-dns": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "subtitle": "", + "title": "" + }, + "library-panel": { + "add-modal": { + "cancel": "", + "create": "", + "error": "", + "folder": "", + "folder-description": "", + "name": "" + }, + "add-widget": { + "title": "" + }, + "empty-state": { + "message": "", + "more-info": "" + } + }, + "library-panels": { + "empty-state": { + "message": "" + }, + "loading-panel-text": "", + "modal": { + "button-cancel": "", + "button-view-panel1": "", + "button-view-panel2": "", + "panel-not-linked": "", + "select-no-options-message": "", + "select-placeholder": "", + "title": "", + "body_one": "", + "body_other": "" + }, + "save": { + "error": "", + "success": "" + } + }, + "link": { + "share": { + "config-alert-description": "", + "config-alert-title": "", + "config-description": "", + "copy-link-button": "", + "copy-to-clipboard": "", + "short-url-label": "", + "time-range-description": "", + "time-range-label": "" + }, + "share-panel": { + "config-description": "", + "download-image": "", + "render-image": "", + "render-image-error": "", + "render-image-error-description": "" + } + }, + "lock-icon": "", + "login": { + "divider": { + "connecting-text": "" + }, + "error": { + "blocked": "", + "invalid-user-or-password": "", + "title": "", + "unknown": "" + }, + "forgot-password": "", + "form": { + "confirmation-code": "", + "confirmation-code-label": "", + "confirmation-code-placeholder": "", + "email-label": "", + "email-placeholder": "", + "email-required": "", + "name-label": "", + "name-placeholder": "", + "password-label": "", + "password-placeholder": "", + "password-required": "", + "submit-label": "", + "submit-loading-label": "", + "username-label": "", + "username-placeholder": "", + "username-required": "", + "verify-email-label": "", + "verify-email-loading-label": "" + }, + "layout": { + "update-password": "" + }, + "services": { + "sing-in-with-prefix": "" + }, + "signup": { + "button-label": "", + "new-to-question": "" + } + }, + "logs": { + "infinite-scroll": { + "end-of-range": "", + "load-more": "", + "load-newer": "", + "load-older": "", + "older-logs": "" + }, + "log-details": { + "fields": "", + "links": "", + "log-line": "", + "no-details": "" + }, + "log-line-menu": { + "copy-link": "", + "copy-log": "", + "icon-label": "", + "pin-to-outline": "", + "show-context": "", + "unpin-from-outline": "" + }, + "log-row-message": { + "ellipsis": "", + "more": "", + "see-details": "" + }, + "log-rows": { + "disable-popover": { + "confirm": "", + "message": "", + "title": "" + }, + "disable-popover-message": { + "shortcut": "" + } + }, + "logs-navigation": { + "newer-logs": "", + "older-logs": "", + "scroll-bottom": "", + "scroll-top": "", + "start-of-range": "" + }, + "popover-menu": { + "copy": "", + "disable-menu": "", + "line-contains": "", + "line-contains-not": "" + } + }, + "migrate-to-cloud": { + "build-snapshot": { + "description": "", + "title": "", + "when-complete": "" + }, + "building-snapshot": { + "description": "", + "description-eta": "", + "title": "" + }, + "can-i-move": { + "body": "", + "link-title": "", + "title": "" + }, + "connect-modal": { + "body-cloud-stack": "", + "body-get-started": "", + "body-sign-up": "", + "body-token": "", + "body-token-field": "", + "body-token-field-placeholder": "", + "body-token-instructions": "", + "body-view-stacks": "", + "cancel": "", + "connect": "", + "connecting": "", + "title": "", + "token-error-title": "", + "token-errors": { + "instance-request-error": "", + "instance-unreachable": "", + "migration-disabled": "", + "session-creation-failure": "", + "token-invalid": "", + "token-not-saved": "", + "token-request-error": "", + "token-validation-failure": "" + }, + "token-required-error": "" + }, + "cta": { + "button": "", + "header": "" + }, + "delete-migration-token-confirm": { + "body": "", + "confirm-button": "", + "error-title": "", + "title": "" + }, + "disconnect-modal": { + "body": "", + "cancel": "", + "disconnect": "", + "disconnecting": "", + "error": "", + "title": "" + }, + "get-started": { + "body": "", + "configure-pdc-link": "", + "link-title": "", + "step-1": "", + "step-2": "", + "step-3": "", + "step-4": "", + "step-5": "", + "title": "" + }, + "is-it-secure": { + "body": "", + "link-title": "", + "title": "" + }, + "migrate-to-this-stack": { + "body": "", + "link-title": "", + "title": "" + }, + "migrated-counts": { + "alert_rule_groups": "", + "alert_rules": "", + "contact_points": "", + "dashboards": "", + "datasources": "", + "folders": "", + "library_elements": "", + "mute_timings": "", + "notification_policies": "", + "notification_templates": "", + "plugins": "" + }, + "migration-token": { + "delete-button": "", + "delete-modal-body": "", + "delete-modal-cancel": "", + "delete-modal-confirm": "", + "delete-modal-deleting": "", + "delete-modal-title": "", + "error-body": "", + "error-title": "", + "generate-button": "", + "generate-button-loading": "", + "modal-close": "", + "modal-copy-and-close": "", + "modal-copy-button": "", + "modal-field-description": "", + "modal-field-label": "", + "modal-title": "", + "status": "" + }, + "onprem": { + "cancel-snapshot-error-title": "", + "create-snapshot-error-title": "", + "disconnect-error-title": "", + "error-see-server-logs": "", + "get-session-error-title": "", + "get-snapshot-error-title": "", + "migration-finished-with-caveat-title": "", + "migration-finished-with-errors-body": "", + "migration-finished-with-warnings-body": "", + "snapshot-error-status-body": "", + "snapshot-error-status-title": "", + "success-message": "", + "success-message-generic": "", + "success-title": "", + "upload-snapshot-error-title": "" + }, + "pdc": { + "body": "", + "link-title": "", + "title": "" + }, + "pricing": { + "body": "", + "link-title": "", + "title": "" + }, + "public-preview": { + "button-text": "", + "message": "", + "message-cloud": "", + "title": "" + }, + "resource-details": { + "dismiss-button": "", + "error-messages": { + "dashboard-already-managed": "", + "datasource-already-managed": "", + "datasource-invalid-url": "", + "datasource-name-conflict": "", + "folder-name-conflict": "", + "generic-error": "", + "internal-service-error": "", + "library-element-name-conflict": "", + "resource-conflict": "", + "unexpected-error": "", + "unsupported-data-type": "" + }, + "error-title": "", + "generic-title": "", + "missing-message": "", + "resource-summary": "", + "title": "", + "warning-title": "" + }, + "resource-status": { + "error-details-button": "", + "failed": "", + "migrated": "", + "migrating": "", + "not-migrated": "", + "unknown": "", + "warning": "", + "warning-details-button": "" + }, + "resource-table": { + "dashboard-load-error": "", + "error-library-element-sub": "", + "error-library-element-title": "", + "unknown-datasource-title": "", + "unknown-datasource-type": "" + }, + "resource-type": { + "alert_rule": "", + "alert_rule_group": "", + "contact_point": "", + "dashboard": "", + "datasource": "", + "folder": "", + "library_element": "", + "mute_timing": "", + "notification_policy": "", + "notification_template": "", + "plugin": "", + "unknown": "" + }, + "summary": { + "cancel-snapshot": "", + "disconnect": "", + "errored-resource-count": "", + "page-loading": "", + "rebuild-snapshot": "", + "snapshot-date": "", + "snapshot-not-created": "", + "start-migration": "", + "successful-resource-count": "", + "target-stack-title": "", + "total-resource-count": "", + "upload-migration": "" + }, + "support-types-disclosure": { + "text": "" + }, + "token-status": { + "active": "", + "no-active": "", + "unknown": "", + "unknown-error": "" + }, + "what-is-cloud": { + "body": "", + "link-title": "", + "title": "" + }, + "why-host": { + "body": "", + "link-title": "", + "title": "" + } + }, + "multicombobox": { + "all": { + "title": "", + "title-filtered": "" + }, + "clear": { + "title": "" + } + }, + "nav": { + "add-new-connections": { + "title": "" + }, + "admin": { + "subtitle": "", + "title": "" + }, + "alert-list-legacy": { + "title": "" + }, + "alerting": { + "subtitle": "", + "title": "" + }, + "alerting-admin": { + "subtitle": "", + "title": "" + }, + "alerting-am-routes": { + "subtitle": "", + "title": "" + }, + "alerting-channels": { + "title": "" + }, + "alerting-groups": { + "subtitle": "", + "title": "" + }, + "alerting-home": { + "title": "" + }, + "alerting-legacy": { + "title": "" + }, + "alerting-list": { + "subtitle": "", + "title": "" + }, + "alerting-receivers": { + "subtitle": "", + "title": "" + }, + "alerting-silences": { + "subtitle": "", + "title": "" + }, + "alerting-upgrade": { + "subtitle": "", + "title": "" + }, + "alerts-and-incidents": { + "subtitle": "", + "title": "" + }, + "api-keys": { + "subtitle": "", + "title": "" + }, + "application": { + "title": "" + }, + "apps": { + "subtitle": "", + "title": "" + }, + "authentication": { + "title": "" + }, + "bookmarks": { + "title": "" + }, + "bookmarks-empty": { + "title": "" + }, + "collector": { + "title": "" + }, + "config": { + "title": "" + }, + "config-access": { + "subtitle": "", + "title": "" + }, + "config-general": { + "subtitle": "", + "title": "" + }, + "config-plugins": { + "subtitle": "", + "title": "" + }, + "connect-data": { + "title": "" + }, + "connections": { + "subtitle": "", + "title": "" + }, + "correlations": { + "subtitle": "", + "title": "" + }, + "create": { + "title": "" + }, + "create-alert": { + "title": "" + }, + "create-dashboard": { + "title": "" + }, + "create-folder": { + "title": "" + }, + "create-import": { + "title": "" + }, + "dashboards": { + "subtitle": "", + "title": "" + }, + "data-sources": { + "subtitle": "", + "title": "" + }, + "databases": { + "title": "" + }, + "datasources": { + "subtitle": "", + "title": "" + }, + "detect": { + "title": "" + }, + "drilldown": { + "title": "" + }, + "explore": { + "title": "" + }, + "frontend": { + "subtitle": "", + "title": "" + }, + "frontend-app": { + "title": "" + }, + "global-orgs": { + "subtitle": "", + "title": "" + }, + "global-users": { + "subtitle": "", + "title": "" + }, + "grafana-quaderno": { + "title": "" + }, + "groupsync": { + "subtitle": "" + }, + "help": { + "title": "" + }, + "help/community": "", + "help/documentation": "", + "help/keyboard-shortcuts": "", + "help/support": "", + "history-container": { + "drawer-tittle": "" + }, + "history-wrapper": { + "collapse": "", + "expand": "", + "icon-selected": "", + "icon-unselected": "", + "show-more": "", + "today": "", + "yesterday": "" + }, + "home": { + "title": "" + }, + "incidents": { + "title": "" + }, + "infrastructure": { + "subtitle": "", + "title": "" + }, + "integrations": { + "title": "" + }, + "k6": { + "title": "" + }, + "kubernetes": { + "title": "" + }, + "library-panels": { + "subtitle": "", + "title": "" + }, + "machine-learning": { + "title": "" + }, + "manage-folder": { + "subtitle": "" + }, + "migrate-to-cloud": { + "subtitle": "", + "title": "" + }, + "monitoring": { + "subtitle": "", + "title": "" + }, + "new": { + "title": "" + }, + "new-dashboard": { + "title": "" + }, + "new-folder": { + "title": "" + }, + "oncall": { + "title": "" + }, + "org-settings": { + "subtitle": "", + "title": "" + }, + "playlists": { + "subtitle": "", + "title": "" + }, + "plugins": { + "subtitle": "", + "title": "" + }, + "private-data-source-connections": { + "subtitle": "", + "title": "" + }, + "profile/notifications": { + "title": "" + }, + "profile/password": { + "title": "" + }, + "profile/settings": { + "title": "" + }, + "profiles": { + "title": "" + }, + "public": { + "title": "" + }, + "recently-deleted": { + "subtitle": "", + "title": "" + }, + "recorded-queries": { + "title": "" + }, + "reporting": { + "title": "" + }, + "scenes": { + "title": "" + }, + "search": { + "placeholderCommandPalette": "" + }, + "search-dashboards": { + "title": "" + }, + "server-settings": { + "subtitle": "", + "title": "" + }, + "service-accounts": { + "subtitle": "", + "title": "" + }, + "setup-guide": { + "title": "" + }, + "shared-dashboard": { + "subtitle": "", + "title": "" + }, + "sign-out": { + "title": "" + }, + "slo": { + "title": "" + }, + "snapshots": { + "subtitle": "", + "title": "" + }, + "starred": { + "title": "" + }, + "starred-empty": { + "title": "" + }, + "statistics-and-licensing": { + "title": "" + }, + "storage": { + "subtitle": "", + "title": "" + }, + "support-bundles": { + "subtitle": "", + "title": "" + }, + "synthetics": { + "title": "" + }, + "teams": { + "subtitle": "", + "title": "" + }, + "testing-and-synthetics": { + "subtitle": "", + "title": "" + }, + "upgrading": { + "title": "" + }, + "users": { + "subtitle": "", + "title": "" + } + }, + "navigation": { + "invite-user": { + "invite-button": "", + "invite-tooltip": "" + }, + "item": { + "add-bookmark": "", + "remove-bookmark": "" + }, + "kiosk": { + "tv-alert": "" + }, + "megamenu": { + "close": "", + "dock": "", + "list-label": "", + "open": "", + "undock": "" + }, + "rss-button": "" + }, + "news": { + "drawer": { + "close": "" + }, + "title": "" + }, + "notifications": { + "empty-state": { + "description": "", + "title": "" + }, + "starred-dashboard": "", + "unstarred-dashboard": "" + }, + "oauth": { + "form": { + "server-discovery-action-button": "", + "server-discovery-modal-close": "", + "server-discovery-modal-loading": "", + "server-discovery-modal-submit": "" + }, + "login": { + "error": "" + } + }, + "panel": { + "header-menu": { + "copy": "", + "create-library-panel": "", + "duplicate": "", + "edit": "", + "explore": "", + "get-help": "", + "hide-legend": "", + "inspect": "", + "inspect-data": "", + "inspect-json": "", + "more": "", + "new-alert-rule": "", + "query": "", + "remove": "", + "replace-library-panel": "", + "share": "", + "show-legend": "", + "unlink-library-panel": "", + "view": "" + } + }, + "panel-search": { + "no-matches": "", + "unsupported-layout": "" + }, + "panel-type-filter": { + "clear-button": "" + }, + "playlist-edit": { + "error-prefix": "", + "form": { + "add-tag-label": "", + "add-tag-placeholder": "", + "add-title-label": "", + "cancel": "", + "heading": "", + "interval-label": "", + "interval-placeholder": "", + "interval-required": "", + "name-label": "", + "name-placeholder": "", + "name-required": "", + "save": "", + "table-delete": "", + "table-drag": "", + "table-empty": "", + "table-heading": "" + }, + "sub-title": "", + "title": "" + }, + "playlist-page": { + "card": { + "delete": "", + "edit": "", + "start": "", + "tooltip": "" + }, + "create-button": { + "title": "" + }, + "delete-modal": { + "body": "", + "confirm-text": "" + }, + "empty": { + "button": "", + "pro-tip": "", + "title": "" + } + }, + "playlists": { + "empty-state": { + "message": "" + } + }, + "plugins": { + "catalog": { + "no-updates-available": "", + "update-all": { + "all-plugins-updated": "", + "available-header": "", + "button": "", + "cloud-update-message": "", + "error": "", + "error-status-text": "", + "header": "", + "installed-header": "", + "modal-confirmation": "", + "modal-dismiss": "", + "modal-in-progress": "", + "modal-title": "", + "name-header": "", + "update-header": "", + "update-status-text": "" + }, + "versions": { + "confirmation-text-1": "", + "confirmation-text-2": "", + "downgrade-confirm": "", + "downgrade-title": "" + } + }, + "details": { + "connections-tab": { + "description": "" + }, + "labels": { + "contactGrafanaLabs": "", + "customLinks": "", + "customLinksTooltip": "", + "dependencies": "", + "documentation": "", + "downloads": "", + "from": "", + "installedVersion": "", + "lastCommitDate": "", + "latestVersion": "", + "license": "", + "raiseAnIssue": "", + "reportAbuse": "", + "reportAbuseTooltip": "", + "repository": "", + "signature": "", + "status": "", + "updatedAt": "" + }, + "modal": { + "cancel": "", + "copyEmail": "", + "description": "", + "node": "", + "title": "" + } + }, + "empty-state": { + "message": "" + }, + "filter": { + "disabled": "", + "sort": "", + "sort-list": "", + "state": "" + }, + "plugin-help": { + "error": "", + "not-found": "" + } + }, + "profile": { + "change-password": { + "cancel-button": "", + "cannot-change-password-message": "", + "change-password-button": "", + "confirm-password-label": "", + "confirm-password-required": "", + "ldap-auth-proxy-message": "", + "new-password-label": "", + "new-password-required": "", + "new-password-same-as-old": "", + "old-password-label": "", + "old-password-required": "", + "passwords-must-match": "", + "strong-password-validation-register": "" + } + }, + "public-dashboard": { + "acknowledgment-checkboxes": { + "ack-title": "", + "data-src-ack-desc": "", + "data-src-ack-tooltip": "", + "public-ack-desc": "", + "public-ack-tooltip": "", + "usage-ack-desc": "", + "usage-ack-desc-tooltip": "" + }, + "config": { + "can-view-dashboard-radio-button-label": "", + "copy-button": "", + "dashboard-url-field-label": "", + "email-share-type-option-label": "", + "pause-sharing-dashboard-label": "", + "public-share-type-option-label": "", + "revoke-public-URL-button": "", + "revoke-public-URL-button-title": "", + "settings-title": "" + }, + "configuration": { + "display-annotations-description": "", + "display-annotations-label": "", + "enable-time-range-description": "", + "enable-time-range-label": "", + "settings-label": "", + "success-pause": "", + "success-resume": "", + "success-update": "", + "success-update-old": "", + "time-range-label": "", + "time-range-tooltip": "" + }, + "create-page": { + "generate-public-url-button": "", + "unsupported-features-desc": "", + "welcome-title": "" + }, + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "email-sharing": { + "accept-button": "", + "alert-text": "", + "bill-ack": "", + "cancel-button": "", + "input-invalid-email-text": "", + "input-required-email-text": "", + "invite-button": "", + "invite-field-desc": "", + "invite-field-label": "", + "learn-more-button": "", + "recipient-email-placeholder": "", + "recipient-invalid-email-text": "", + "recipient-invitation-button": "", + "recipient-invitation-description": "", + "recipient-invitation-tooltip": "", + "recipient-list-description": "", + "recipient-list-title": "", + "recipient-required-email-text": "", + "resend-button": "", + "resend-button-title": "", + "resend-invite-label": "", + "revoke-access-label": "", + "revoke-button": "", + "revoke-button-title": "", + "success-creation": "", + "success-share-type-change": "" + }, + "modal-alerts": { + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "save-dashboard-changes-alert-title": "", + "unsupport-data-source-alert-readmore-link": "", + "unsupported-data-source-alert-desc": "", + "unsupported-data-source-alert-title": "", + "unsupported-template-variable-alert-desc": "", + "unsupported-template-variable-alert-title": "" + }, + "public-sharing": { + "accept-button": "", + "alert-text": "", + "cancel-button": "", + "learn-more-button": "", + "public-ack": "", + "success-creation": "", + "success-share-type-change": "" + }, + "settings-bar-header": { + "collapse-settings-tooltip": "", + "expand-settings-tooltip": "" + }, + "settings-configuration": { + "default-time-range-label": "", + "default-time-range-label-desc": "", + "show-annotations-label": "", + "show-annotations-label-desc": "", + "time-range-picker-label": "", + "time-range-picker-label-desc": "" + }, + "settings-summary": { + "annotations-hide-text": "", + "annotations-show-text": "", + "time-range-picker-disabled-text": "", + "time-range-picker-enabled-text": "", + "time-range-text": "" + }, + "share": { + "success-delete": "", + "success-delete-old": "" + }, + "share-configuration": { + "share-type-label": "" + }, + "share-externally": { + "copy-link-button": "", + "email-share-type-option-description": "", + "email-share-type-option-label": "", + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "pause-access-button": "", + "pause-access-tooltip": "", + "public-share-type-option-description": "", + "public-share-type-option-label": "", + "resume-access-button": "", + "revoke-access-button": "", + "revoke-access-description": "", + "unsupported-data-source-alert-desc": "" + }, + "sharing": { + "success-creation": "" + } + }, + "public-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "public-dashboard-users-access-list": { + "dashboard-modal": { + "external-link": "", + "loading-text": "", + "open-dashboard-list-text": "", + "public-dashboard-link": "", + "public-dashboard-setting": "", + "sharing-setting": "" + }, + "delete-user-modal": { + "delete-user-button-text": "", + "delete-user-cancel-button": "", + "delete-user-revoke-access-button": "", + "revoke-access-title": "", + "revoke-user-access-modal-desc-line1": "", + "revoke-user-access-modal-desc-line2": "" + }, + "delete-user-shared-dashboards-modal": { + "revoke-user-access-modal-desc-line2": "" + }, + "modal": { + "dashboard-modal-title": "", + "shared-dashboard-modal-title": "" + }, + "table-body": { + "dashboard-count_one": "", + "dashboard-count_other": "" + }, + "table-header": { + "activated-label": "", + "activated-tooltip": "", + "email-label": "", + "last-active-label": "", + "origin-label": "", + "role-label": "" + } + }, + "query-operation": { + "header": { + "collapse-row": "", + "datasource-help": "", + "drag-and-drop": "", + "duplicate-query": "", + "expand-row": "", + "hide-response": "", + "remove-query": "", + "show-response": "", + "toggle-edit-mode": "" + }, + "query-editor-not-exported": "" + }, + "recently-deleted": { + "buttons": { + "delete": "", + "restore": "" + }, + "page": { + "no-deleted-dashboards": "", + "no-deleted-dashboards-text": "", + "no-search-result": "" + }, + "permanently-delete-modal": { + "confirm-text": "", + "delete-button": "", + "delete-loading": "", + "title": "", + "text_one": "", + "text_other": "" + }, + "restore-modal": { + "restore-button": "", + "restore-loading": "", + "title": "", + "folder-picker-text_one": "", + "folder-picker-text_other": "", + "text_one": "", + "text_other": "" + } + }, + "recentlyDeleted": { + "filter": { + "placeholder": "" + } + }, + "reduce": { + "strictMode": { + "description": "", + "title": "" + } + }, + "refresh-picker": { + "aria-label": { + "choose-interval": "", + "duration-selected": "" + }, + "auto-option": { + "aria-label": "", + "label": "" + }, + "live-option": { + "aria-label": "", + "label": "" + }, + "off-option": { + "aria-label": "", + "label": "" + }, + "tooltip": { + "interval-selected": "", + "turned-off": "" + } + }, + "return-to-previous": { + "button": { + "label": "" + }, + "dismissable-button": "" + }, + "role-picker": { + "built-in": { + "basic-roles": "" + }, + "input": { + "no-roles": "" + }, + "menu": { + "clear-button": "", + "tooltip": "" + }, + "sub-menu": { + "clear-button": "" + }, + "title": { + "description": "" + } + }, + "role-picker-drawer": { + "basic-roles": { + "label": "" + } + }, + "route-error": { + "description": "", + "reload-button": "", + "title": "" + }, + "save-dashboards": { + "message-length": { + "info": "", + "title": "" + }, + "name-exists": { + "message-info": "", + "message-suggestion": "", + "title": "" + } + }, + "scopes": { + "dashboards": { + "collapse": "", + "expand": "", + "loading": "", + "noResultsForFilter": "", + "noResultsForFilterClear": "", + "noResultsForScopes": "", + "noResultsNoScopes": "", + "search": "", + "toggle": { + "collapse": "", + "disabled": "", + "expand": "" + } + }, + "selector": { + "apply": "", + "cancel": "", + "input": { + "placeholder": "", + "removeAll": "" + }, + "title": "" + }, + "tree": { + "collapse": "", + "expand": "", + "headline": { + "noResults": "", + "recommended": "", + "results": "" + }, + "search": "" + } + }, + "search": { + "actions": { + "include-panels": "", + "remove-datasource-filter": "", + "sort-placeholder": "", + "starred": "", + "view-as-folders": "", + "view-as-list": "" + }, + "dashboard-actions": { + "import": "", + "new": "", + "new-dashboard": "", + "new-folder": "" + }, + "results-table": { + "datasource-header": "", + "deleted-less-than-1-min": "", + "deleted-remaining-header": "", + "location-header": "", + "name-header": "", + "tags-header": "", + "type-dashboard": "", + "type-folder": "", + "type-header": "" + }, + "search-input": { + "include-panels-placeholder": "", + "placeholder": "" + } + }, + "select": { + "select-menu": { + "selected-count": "" + } + }, + "service-account-create-page": { + "create": { + "button": "" + }, + "name": { + "label": "", + "required-error": "" + }, + "page-nav": { + "label": "" + }, + "role": { + "label": "" + } + }, + "service-accounts": { + "empty-state": { + "button-title": "", + "message": "", + "more-info": "", + "title": "" + } + }, + "share-dashboard": { + "menu": { + "export-json-title": "", + "share-externally-title": "", + "share-internally-title": "", + "share-snapshot-title": "" + }, + "share-button": "", + "share-button-tooltip": "" + }, + "share-drawer": { + "confirm-action": { + "back-arrow-button": "", + "cancel-button": "" + } + }, + "share-modal": { + "dashboard": { + "title": "" + }, + "embed": { + "copy": "", + "html": "", + "html-description": "", + "info": "", + "time-range": "" + }, + "export": { + "back-button": "", + "cancel-button": "", + "info-text": "", + "loading": "", + "save-button": "", + "share-externally-label": "", + "view-button": "" + }, + "library": { + "info": "" + }, + "link": { + "copy-link-button": "", + "info-text": "", + "link-url": "", + "render-alert": "", + "render-instructions": "", + "rendered-image": "", + "save-alert": "", + "save-dashboard": "", + "shorten-url": "", + "time-range-description": "", + "time-range-label": "" + }, + "panel": { + "title": "" + }, + "snapshot": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "deleted-message": "", + "expire": "", + "expire-day": "", + "expire-hour": "", + "expire-never": "", + "expire-week": "", + "info-text-1": "", + "info-text-2": "", + "local-button": "", + "mistake-message": "", + "name": "", + "timeout": "", + "timeout-description": "", + "url-label": "" + }, + "tab-title": { + "embed": "", + "export": "", + "library-panel": "", + "link": "", + "panel-embed": "", + "public-dashboard": "", + "public-dashboard-title": "", + "snapshot": "" + }, + "theme-picker": { + "current": "", + "dark": "", + "field-name": "", + "light": "" + }, + "view-json": { + "copy-button": "" + } + }, + "share-panel": { + "drawer": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "" + }, + "menu": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "", + "share-snapshot-title": "" + }, + "new-library-panel": { + "cancel-button": "", + "create-button": "" + } + }, + "share-panel-image": { + "preview": { + "title": "" + }, + "settings": { + "height-label": "", + "height-min": "", + "height-placeholder": "", + "height-required": "", + "max-warning": "", + "scale-factor-label": "", + "scale-factor-min": "", + "scale-factor-placeholder": "", + "scale-factor-required": "", + "title": "", + "width-label": "", + "width-min": "", + "width-placeholder": "", + "width-required": "" + } + }, + "share-playlist": { + "checkbox-description": "", + "checkbox-label": "", + "copy-link-button": "", + "link-url-label": "", + "mode": "", + "mode-kiosk": "", + "mode-normal": "", + "title": "" + }, + "shared": { + "preferences": { + "theme": { + "dark-label": "", + "light-label": "", + "system-label": "" + } + } + }, + "shared-dashboard": { + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "fields": { + "timezone-label": "" + } + }, + "shared-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "shared-preferences": { + "fields": { + "home-dashboard-label": "", + "home-dashboard-placeholder": "", + "locale-label": "", + "locale-placeholder": "", + "theme-description": "", + "theme-label": "", + "week-start-label": "" + }, + "theme": { + "default-label": "" + }, + "title": "" + }, + "sign-up": { + "back-button": "", + "submit-button": "", + "verify": { + "back-button": "", + "complete-button": "", + "header": "", + "info": "", + "send-button": "" + } + }, + "silences": { + "empty-state": { + "button-title": "", + "title": "" + }, + "table": { + "add-silence-button": "", + "edit-button": "", + "expired-silences": "", + "no-matching-silences": "", + "noConfig": "", + "recreate-button": "", + "unsilence-button": "" + } + }, + "silences-table": { + "header": { + "alert-name": "", + "state": "" + } + }, + "snapshot": { + "empty-state": { + "message": "", + "more-info": "" + }, + "external-badge": "", + "name-column-header": "", + "share": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "delete-description": "", + "delete-permission-tooltip": "", + "delete-title": "", + "deleted-alert": "", + "expiration-label": "", + "info-alert": "", + "learn-more-button": "", + "local-button": "", + "name-label": "", + "new-snapshot-button": "", + "success-creation": "", + "success-delete": "", + "view-all-button": "" + }, + "share-panel": { + "info-alert": "" + }, + "url-column-header": "", + "view-button": "" + }, + "table": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "" + } + }, + "tag-filter": { + "clear-button": "", + "loading": "", + "no-tags": "", + "placeholder": "" + }, + "teams": { + "empty-state": { + "button-title": "", + "message": "", + "pro-tip": "", + "title": "" + } + }, + "theme-preview": { + "breadcrumbs": { + "dashboards": "", + "home": "" + }, + "panel": { + "form-label": "", + "title": "" + } + }, + "time-picker": { + "absolute": { + "recent-title": "", + "title": "" + }, + "calendar": { + "apply-button": "", + "cancel-button": "", + "close": "", + "next-month": "", + "previous-month": "", + "select-time": "" + }, + "content": { + "empty-recent-list-docs": "", + "empty-recent-list-info": "", + "filter-placeholder": "" + }, + "copy-paste": { + "copy-success-message": "", + "default-error-message": "", + "default-error-title": "", + "tooltip-copy": "", + "tooltip-paste": "" + }, + "footer": { + "change-settings-button": "", + "fiscal-year-option": "", + "fiscal-year-start": "", + "time-zone-option": "", + "time-zone-selection": "" + }, + "range-content": { + "apply-button": "", + "default-error": "", + "fiscal-year": "", + "from-input": "", + "open-input-calendar": "", + "range-error": "", + "to-input": "" + }, + "range-picker": { + "backwards-time-aria-label": "", + "current-time-selected": "", + "forwards-time-aria-label": "", + "to": "", + "zoom-out-button": "", + "zoom-out-tooltip": "" + }, + "time-range": { + "apply": "", + "aria-role": "", + "default-title": "", + "example": "", + "example-details": "", + "example-title": "", + "from-label": "", + "from-to": "", + "more-info": "", + "specify": "", + "submit-button-label": "", + "supported-formats": "", + "to-label": "" + }, + "zone": { + "select-aria-label": "", + "select-search-input": "" + } + }, + "trails": { + "bookmarks": { + "or-view-bookmarks": "" + }, + "card": { + "date-created": "" + }, + "home": { + "learn-more": "", + "lets-start": "", + "start-your-metrics-exploration": "", + "subtitle": "" + }, + "metric-select": { + "filter-by": "", + "native-histogram": "", + "new-badge": "", + "otel-switch": "" + }, + "native-histogram-banner": { + "ch-heatmap": "", + "ch-histogram": "", + "click-histogram": "", + "hide-examples": "", + "learn-more": "", + "metric-examples": "", + "nh-heatmap": "", + "nh-histogram": "", + "now": "", + "previously": "", + "see-examples": "", + "sentence": "" + }, + "recent-metrics": { + "or-view-a-recent-exploration": "" + }, + "settings": { + "always-keep-selected-metric-graph-in-view": "", + "show-previews-of-metric-graphs": "" + } + }, + "transformations": { + "empty": { + "add-transformation-body": "", + "add-transformation-header": "" + } + }, + "upgrade-box": { + "discovery-text": "", + "discovery-text-continued": "", + "get-started": "", + "learn-more": "", + "upgrade-button": "" + }, + "user-orgs": { + "current-org-button": "", + "name-column": "", + "role-column": "", + "select-org-button": "", + "title": "" + }, + "user-profile": { + "fields": { + "email-error": "", + "email-label": "", + "name-error": "", + "name-label": "", + "username-label": "" + }, + "tabs": { + "general": "" + } + }, + "user-session": { + "auth-module-column": "", + "browser-column": "", + "created-at-column": "", + "identity-provider-column": "", + "ip-column": "", + "revoke": "", + "seen-at-column": "" + }, + "user-sessions": { + "loading": "" + }, + "users": { + "empty-state": { + "message": "" + } + }, + "users-access-list": { + "tabs": { + "public-dashboard-users-tab-title": "", + "shared-dashboard-users-tab-title": "" + } + }, + "variable": { + "adhoc": { + "placeholder": "" + }, + "dropdown": { + "placeholder": "" + }, + "picker": { + "link-all": "", + "option-all": "", + "option-selected-values": "", + "option-tooltip": "" + }, + "textbox": { + "placeholder": "" + } + }, + "variables": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + }, + "unknown-table": { + "loading": "", + "no-unknowns": "", + "renamed-or-missing-variables": "", + "variable": "" + } + } +} \ No newline at end of file diff --git a/public/locales/tr-TR/grafana.json b/public/locales/tr-TR/grafana.json new file mode 100644 index 00000000000..f3a7ee625b6 --- /dev/null +++ b/public/locales/tr-TR/grafana.json @@ -0,0 +1,4010 @@ +{ + "_comment": "", + "access-control": { + "add-permission": { + "role-label": "", + "serviceaccount-label": "", + "team-label": "", + "title": "", + "user-label": "" + }, + "add-permissions": { + "save": "" + }, + "permission-list": { + "permission": "" + }, + "permission-list-item": { + "inherited": "" + }, + "permissions": { + "add-label": "", + "no-permissions": "", + "permissions-change-warning": "", + "role": "", + "serviceaccount": "", + "team": "", + "title": "", + "user": "" + } + }, + "action-editor": { + "modal": { + "cancel-button": "", + "save-button": "" + } + }, + "admin": { + "anon-users": { + "not-found": "" + }, + "edit-org": { + "access-denied": "", + "heading": "", + "update-button": "", + "users-heading": "" + }, + "feature-toggles": { + "sub-title": "" + }, + "get-enterprise": { + "contact-us": "", + "description": "", + "features-heading": "", + "included-description": "", + "included-heading": "", + "service-title": "", + "team-sync-details": "", + "title": "" + }, + "ldap": { + "test-mapping-heading": "", + "test-mapping-run-button": "" + }, + "ldap-permissions": { + "active": "", + "admin": "", + "inactive": "" + }, + "ldap-status": { + "title": "" + }, + "ldap-sync": { + "debug-button": "", + "external-sync-description": "", + "external-sync-label": "", + "next-sync-label": "", + "not-enabled": "", + "sync-button": "", + "title": "" + }, + "ldap-sync-info": { + "title": "" + }, + "ldap-user-groups": { + "no-org-found": "" + }, + "ldap-user-info": { + "no-team": "" + }, + "org-uers": { + "last-seen-never": "" + }, + "org-users": { + "not-editable": "" + }, + "orgs": { + "delete-body": "", + "id-header": "", + "name-header": "", + "new-org-button": "" + }, + "server-settings": { + "alerts-button": "", + "dashboards-button": "", + "data-sources-button": "", + "not-found": "", + "title": "", + "users-button": "" + }, + "settings": { + "info-description": "" + }, + "upgrade-info": { + "title": "" + }, + "user-orgs": { + "add-button": "", + "change-role-button": "", + "external-user-tooltip": "", + "remove-button": "", + "role-not-editable": "", + "title": "" + }, + "user-orgs-modal": { + "add-button": "", + "cancel-button": "" + }, + "user-permissions": { + "change-button": "", + "grafana-admin-key": "", + "grafana-admin-no": "", + "grafana-admin-yes": "", + "title": "" + }, + "user-profile": { + "delete-button": "", + "disable-button": "", + "edit-button": "", + "enable-button": "", + "title": "" + }, + "user-sessions": { + "browser-column": "", + "force-logout-all-button": "", + "force-logout-button": "", + "ip-column": "", + "last-seen-column": "", + "logged-on-column": "", + "title": "" + }, + "users-create": { + "create-button": "" + }, + "users-list": { + "create-button": "" + }, + "users-table": { + "last-seen-never": "", + "no-licensed-roles": "" + } + }, + "alert-labels": { + "button": { + "hide": "", + "show": { + "tooltip": "" + } + } + }, + "alerting": { + "alert": { + "alert-state": "", + "annotations": "", + "evaluation": "", + "evaluation-paused": "", + "evaluation-paused-description": "", + "last-evaluated": "", + "last-evaluation-duration": "", + "last-updated-at": "", + "last-updated-by": "", + "no-annotations": "", + "pending-period": "", + "rule": "", + "rule-identifier": "", + "rule-type": "", + "state-error-timeout": "", + "state-no-data": "", + "target-datasource-uid": "" + }, + "alert-recording-rule-form": { + "evaluation-behaviour": { + "description": { + "text": "" + } + } + }, + "alert-rules": { + "firing-for": "", + "next-evaluation": "", + "next-evaluation-in": "", + "rule-definition": "" + }, + "alertform": { + "labels": { + "alerting": "", + "recording": "" + } + }, + "alertVersionHistory": { + "alerting": "", + "alerting-change-description": "", + "annotations": "", + "compare": "", + "compare-with-latest": "", + "compareVersions": "", + "comparing-versions": "", + "condition": "", + "contactPointRouting": "", + "description": "", + "errorloading": "", + "execErrorState": "", + "intervalSeconds": "", + "labels": "", + "latest": "", + "name": "", + "namespace_uid": "", + "noDataState": "", + "noVersionsFound": "", + "paused": "", + "pendingPeriod": "", + "provisioning": "", + "provisioning-change-description": "", + "queryAndAlertCondition": "", + "restore": "", + "restore-manually": "", + "restore-modal": { + "body": "", + "confirm": "", + "error": "", + "summary": "", + "title": "" + }, + "restore-version": "", + "rule_group": "", + "unknown": "", + "unknown-change-description": "", + "user-id": "", + "warning-restore-manually": "", + "warning-restore-manually-title": "" + }, + "annotations": { + "description": "", + "title": "" + }, + "central-alert-history": { + "details": { + "error": "", + "header": { + "alert-rule": "", + "instance": "", + "state": "", + "timestamp": "" + }, + "loading": "", + "no-recognized-state": "", + "no-values": "", + "not-found": "", + "number-transitions": "", + "state": { + "alerting": "", + "error": "", + "no-data": "", + "normal": "", + "pending": "" + }, + "state-transitions": "", + "unknown-event-state": "", + "unknown-rule": "", + "value-in-transition": "" + }, + "error": "", + "filter": { + "clear": "", + "info": { + "label1": "", + "label2": "", + "label3": "", + "label4": "" + } + }, + "filterBy": "", + "too-many-events": { + "text": "", + "title": "" + } + }, + "common": { + "cancel": "", + "clear-filters": "", + "delete": "", + "edit": "", + "export": "", + "export-all": "", + "loading": "", + "search-by-matchers": "", + "titles": { + "notification-templates": "" + }, + "view": "" + }, + "contact-points": { + "create": "", + "custom-template-value": "", + "delete-reasons": { + "heading": "", + "no-permissions": "", + "policies": "", + "provisioned": "", + "rules": "" + }, + "delivered-to": "", + "delivery-duration": "", + "empty-state": { + "title": "" + }, + "key-value-map": { + "add": "", + "confirm-add": "" + }, + "last-delivery-attempt": "", + "last-delivery-failed": "", + "no-contact-points-found": "", + "no-delivery-attempts": "", + "no-integrations": "", + "only-firing": "", + "receiver-summary": { + "jira": "" + }, + "telegram": { + "parse-mode-warning-body": "", + "parse-mode-warning-title": "" + }, + "used-by_one": "", + "used-by_other": "", + "used-by-rules_one": "", + "used-by-rules_other": "" + }, + "contactPointFilter": { + "label": "" + }, + "copy-to-clipboard": "", + "dag": { + "missing-reference": "", + "self-reference": "" + }, + "export": { + "subtitle": { + "formats": "", + "one-format": "" + } + }, + "folderAndGroup": { + "evaluation": { + "modal": { + "text": { + "alerting": "", + "recording": "" + } + } + } + }, + "group-actions": { + "actions-trigger": "", + "delete": "", + "edit": "", + "export": "", + "reorder": "" + }, + "list-view": { + "empty": { + "new-alert-rule": "", + "new-recording-rule": "", + "provisioning": "" + }, + "section": { + "dataSourceManaged": { + "title": "" + }, + "grafanaManaged": { + "export-new-rule": "", + "export-rules": "", + "loading": "", + "new-recording-rule": "", + "title": "" + } + } + }, + "manage-permissions": { + "button": "", + "title": "" + }, + "mute_timings": { + "error-loading": { + "description": "", + "title": "" + } + }, + "mute-timings": { + "add-mute-timing": "", + "description": "", + "save": "", + "saving": "" + }, + "notification-preview": { + "alertmanager": "", + "error": "", + "initialized": "", + "preview-routing": "", + "title": "", + "uninitialized": "" + }, + "notification-templates": { + "duplicate": { + "subTitle": "", + "title": "" + }, + "edit": { + "subTitle": "", + "title": "" + }, + "new": { + "subTitle": "", + "title": "" + } + }, + "policies": { + "default-policy": { + "description": "", + "title": "", + "update": "" + }, + "delete": { + "confirm": "", + "warning-1": "", + "warning-2": "" + }, + "filter-description": "", + "generated-policies": "", + "matchers": "", + "metadata": { + "active-time": "", + "delivered-to": "", + "grouped-by": "", + "grouping": { + "none": "", + "single-group": "" + }, + "inherited": "", + "mute-time": "", + "timingOptions": { + "groupInterval": { + "description": "", + "label": "" + }, + "groupWait": { + "description": "", + "label": "" + }, + "repeatInterval": { + "description": "", + "label": "" + } + }, + "n-instances_one": "", + "n-instances_other": "" + }, + "new-child": "", + "new-policy": "", + "no-matchers": "", + "reload-policies": "", + "save-policy": "", + "update": { + "please-wait": "", + "update-policy": "", + "updating": "" + }, + "update-errors": { + "conflict": "", + "error-code": "", + "fallback": "", + "suffix": "", + "title": "" + }, + "n-more-policies_one": "", + "n-more-policies_other": "" + }, + "provisioning": { + "badge-tooltip-provenance": "", + "badge-tooltip-standard": "" + }, + "queryAndExpressionsStep": { + "disableAdvancedOptions": { + "text": "" + }, + "preview": "", + "previewCondition": "" + }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, + "rule-form": { + "evaluation": { + "evaluation-group-and-interval": "", + "group": { + "cancel": "", + "create": "", + "interval": "" + }, + "group-name": "", + "group-text": "", + "new-group": "", + "pause": { + "alerting": "", + "recording": "" + }, + "select-folder-before": "" + }, + "evaluation-behaviour": { + "description": { + "text": "" + }, + "info-help": { + "text": "" + }, + "pending-period": "" + }, + "evaluation-behaviour-description1": "", + "evaluation-behaviour-description2": "", + "evaluation-behaviour-description3": "", + "evaluation-behaviour-for": { + "error-parsing": "", + "validation": "" + }, + "folder": { + "cancel": "", + "create": "", + "create-folder": "", + "creating-new-folder": "", + "label": "", + "name": "", + "new-folder": "", + "new-folder-or": "" + }, + "folder-and-labels": "", + "folders": { + "help-info": "" + }, + "labels": { + "help-info": "" + }, + "pause": { + "label": "" + }, + "threshold": { + "recovery": { + "stop-alerting-above": "", + "stop-alerting-bellow": "", + "stop-alerting-equal": "", + "stop-alerting-inside-range": "", + "stop-alerting-less": "", + "stop-alerting-more": "", + "stop-alerting-not-equal": "", + "stop-alerting-outside-range": "", + "title": "" + } + } + }, + "rule-groups": { + "delete": { + "success": "" + }, + "move": { + "success": "" + }, + "rename": { + "success": "" + }, + "update": { + "success": "" + } + }, + "rule-list": { + "configure-datasource": "", + "ds-error-boundary": { + "description": "", + "title": "" + }, + "filter-view": { + "no-more-results": "", + "no-rules-found": "" + }, + "new-alert-rule": "", + "pagination": { + "next-page": "", + "previous-page": "" + }, + "return-button": { + "title": "" + }, + "rulerrule-loading-error": "" + }, + "rule-state": { + "creating": "", + "deleting": "", + "paused": "", + "recording-rule": "" + }, + "rule-view": { + "query": { + "datasources-na": { + "description": "", + "title": "" + } + } + }, + "rule-viewer": { + "error-loading": "", + "prometheus-consistency-check": { + "alert-message": "", + "alert-title": "" + } + }, + "rules": { + "add-rule": { + "success": "" + }, + "delete-rule": { + "success": "" + }, + "pause-rule": { + "success": "" + }, + "resume-rule": { + "success": "" + }, + "update-rule": { + "success": "" + } + }, + "search": { + "property": { + "data-source": "", + "evaluation-group": "", + "labels": "", + "namespace": "", + "rule-health": "", + "rule-name": "", + "rule-type": "", + "state": "" + }, + "save-query": "" + }, + "silences": { + "affected-instances": "", + "only-firing-instances": "", + "preview-affected-instances": "" + }, + "simpleCondition": { + "alertCondition": "" + }, + "templates": { + "editor": { + "add-example": "", + "auto-complete": "", + "goto-docs": "" + }, + "help": { + "intro": "" + }, + "misconfigured-badge-text": "", + "misconfigured-warning": "", + "misconfigured-warning-details": "" + }, + "threshold": { + "to": "" + } + }, + "annotations": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + } + }, + "api-keys": { + "empty-state": { + "message": "" + } + }, + "app-chrome": { + "skip-content-button": "", + "top-bar": { + "sign-in": "" + } + }, + "app-notification": { + "item": { + "trace-id": "" + } + }, + "bookmarks-page": { + "empty": { + "message": "", + "tip": "" + } + }, + "bouncing-loader": { + "label": "" + }, + "browse-dashboards": { + "action": { + "cancel-button": "", + "cannot-move-folders": "", + "confirmation-text": "", + "delete-button": "", + "delete-modal-invalid-text": "", + "delete-modal-invalid-title": "", + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "delete-modal-title": "", + "deleting": "", + "manage-permissions-button": "", + "move-button": "", + "move-modal-alert": "", + "move-modal-field-label": "", + "move-modal-text": "", + "move-modal-title": "", + "moving": "", + "new-folder-name-required-phrase": "" + }, + "actions": { + "button-to-recently-deleted": "" + }, + "counts": { + "alertRule_one": "", + "alertRule_other": "", + "dashboard_one": "", + "dashboard_other": "", + "folder_one": "", + "folder_other": "", + "libraryPanel_one": "", + "libraryPanel_other": "", + "total_one": "", + "total_other": "" + }, + "dashboards-tree": { + "collapse-folder-button": "", + "expand-folder-button": "", + "name-column": "", + "select-all-header-checkbox": "", + "select-checkbox": "", + "tags-column": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "", + "title-folder": "" + }, + "folder-actions-button": { + "delete": "", + "folder-actions": "", + "manage-permissions": "", + "move": "" + }, + "folder-picker": { + "accessible-label": "", + "button-label": "", + "clear-selection": "", + "empty-message": "", + "error-title": "", + "non-folder-item": "", + "search-placeholder": "", + "unknown-error": "" + }, + "hard-delete": { + "success": "" + }, + "manage-folder-nav": { + "alert-rules": "", + "dashboards": "", + "panels": "" + }, + "new-folder-form": { + "cancel-label": "", + "create-label": "", + "name-label": "" + }, + "no-results": { + "clear": "", + "text": "" + }, + "soft-delete": { + "success": "" + } + }, + "clipboard-button": { + "inline-toast": { + "success": "" + } + }, + "combobox": { + "async": { + "error": "" + }, + "clear": { + "title": "" + }, + "custom-value": { + "description": "" + }, + "group": { + "undefined": "" + }, + "options": { + "no-found": "" + } + }, + "command-palette": { + "action": { + "change-theme": "", + "dark-theme": "", + "light-theme": "" + }, + "empty-state": { + "message": "" + }, + "search-box": { + "placeholder": "" + }, + "section": { + "actions": "", + "dashboard-search-results": "", + "folder-search-results": "", + "pages": "", + "preferences": "", + "recent-dashboards": "" + } + }, + "common": { + "apply": "", + "cancel": "", + "clear": "", + "close": "", + "collapse": "", + "edit": "", + "help": "", + "loading": "", + "locale": { + "default": "" + }, + "save": "", + "search": "", + "view": "" + }, + "configuration-tracker": { + "config-card": { + "complete": "" + } + }, + "connections": { + "connect-data": { + "category-header-label": "", + "empty-message": "", + "request-data-source": "", + "roadmap": "" + }, + "search": { + "placeholder": "" + } + }, + "core": { + "versionHistory": { + "comparison": { + "header": { + "hide-json-diff": "", + "show-json-diff": "", + "text": "" + }, + "select": "" + }, + "no-properties-changed": "", + "table": { + "updated": "", + "updatedBy": "", + "version": "" + }, + "view-json-diff": "" + } + }, + "correlations": { + "add-new": "", + "alert": { + "error-message": "", + "title": "" + }, + "basic-info-form": { + "description-description": "", + "description-label": "", + "label-description": "", + "label-label": "", + "label-placeholder": "", + "label-required": "", + "sub-text": "", + "title": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + }, + "list": { + "delete": "", + "label": "", + "loading": "", + "read-only": "", + "source": "", + "target": "" + }, + "navigation-form": { + "add-button": "", + "back-button": "", + "next-button": "", + "save-button": "" + }, + "page-content": "", + "page-heading": "", + "query-editor": { + "control-rules": "", + "data-source-text": "", + "data-source-title": "", + "error-text": "", + "error-title": "", + "loading": "", + "query-description": "", + "query-editor-title": "", + "query-label": "" + }, + "source-form": { + "control-required": "", + "description": "", + "description-external-pre": "", + "description-query-pre": "", + "external-title": "", + "heading-external": "", + "heading-query": "", + "query-title": "", + "results-description": "", + "results-label": "", + "results-required": "", + "source-description": "", + "source-label": "", + "sub-text": "" + }, + "sub-title": "", + "target-form": { + "control-rules": "", + "sub-text": "", + "target-description-external": "", + "target-description-query": "", + "target-label": "", + "target-type-description": "", + "title": "", + "type-label": "" + }, + "trans-details": { + "logfmt-description": "", + "logfmt-label": "", + "regex-description": "", + "regex-expression": "", + "regex-label": "", + "regex-map-values": "" + }, + "transform": { + "add-button": "", + "heading": "", + "no-transform": "" + }, + "transform-row": { + "expression-label": "", + "expression-required": "", + "expression-tooltip": "", + "field-input": "", + "field-label": "", + "field-tooltip": "", + "map-value-label": "", + "map-value-tooltip": "", + "remove-button": "", + "remove-tooltip": "", + "transform-required": "", + "type-label": "", + "type-tooltip": "" + } + }, + "dashboard": { + "add-menu": { + "import": "", + "paste-panel": "", + "row": "", + "visualization": "" + }, + "alert-rules-drawer": { + "redirect-link": "", + "subtitle": "" + }, + "default-layout": { + "description": "", + "item-options": { + "repeat": { + "direction": { + "horizontal": "", + "title": "", + "vertical": "" + }, + "max": "", + "title": "", + "variable": { + "description": "", + "title": "" + } + } + }, + "name": "", + "row-actions": { + "delete": "", + "modal": { + "alt-action": "", + "text": "", + "title": "" + } + }, + "row-options": { + "button": { + "label": "" + }, + "form": { + "cancel": "", + "repeat-for": { + "label": "", + "learn-more": "", + "warning": { + "text": "" + } + }, + "title": "", + "update": "" + }, + "modal": { + "title": "" + }, + "repeat": { + "title": "", + "variable": { + "title": "" + } + }, + "title": "" + } + }, + "edit-pane": { + "elements": { + "dashboard": "", + "objects": "", + "panel": "", + "panels": "", + "row": "", + "rows": "", + "tab": "", + "tabs": "" + }, + "open": "", + "row": { + "header": { + "hide": "", + "title": "" + } + } + }, + "editpane": { + "add": "", + "configure": "", + "outline": "" + }, + "empty": { + "add-library-panel-body": "", + "add-library-panel-button": "", + "add-library-panel-header": "", + "add-visualization-body": "", + "add-visualization-button": "", + "add-visualization-header": "", + "import-a-dashboard-body": "", + "import-a-dashboard-header": "", + "import-dashboard-button": "" + }, + "errors": { + "failed-to-load": "" + }, + "inspect": { + "data-tab": "", + "error-tab": "", + "json-tab": "", + "meta-tab": "", + "query-tab": "", + "stats-tab": "", + "subtitle": "", + "title": "" + }, + "inspect-data": { + "data-options": "", + "dataframe-aria-label": "", + "dataframe-label": "", + "download-csv": "", + "download-excel-description": "", + "download-excel-label": "", + "download-logs": "", + "download-service": "", + "download-traces": "", + "excel-header": "", + "formatted": "", + "formatted-data-description": "", + "formatted-data-label": "", + "panel-transforms": "", + "series-to-columns": "", + "transformation": "", + "transformations-description": "", + "transformations-label": "" + }, + "inspect-json": { + "dataframe-description": "", + "dataframe-label": "", + "panel-data-description": "", + "panel-data-label": "", + "panel-json-description": "", + "panel-json-label": "", + "select-source": "", + "unknown": "" + }, + "inspect-meta": { + "no-inspector": "" + }, + "inspect-stats": { + "data-title": "", + "data-traceids": "", + "processing-time": "", + "queries": "", + "request-time": "", + "rows": "", + "table-title": "" + }, + "layout": { + "common": { + "copy": "", + "copy-or-duplicate": "", + "delete": "", + "duplicate": "", + "layout": "" + } + }, + "options": { + "description": "", + "title-option": "" + }, + "outline": { + "tree": { + "item": { + "collapse": "", + "empty": "", + "expand": "" + } + } + }, + "panel-edit": { + "alerting-tab": { + "dashboard-not-saved": "", + "no-rules": "" + } + }, + "responsive-layout": { + "description": "", + "item-options": { + "hide-no-data": "", + "repeat": { + "variable": { + "description": "", + "title": "" + } + }, + "title": "" + }, + "name": "", + "options": { + "columns": "", + "fixed": "", + "min": "", + "one-column": "", + "rows": "", + "three-columns": "", + "two-columns": "" + } + }, + "rows-layout": { + "description": "", + "name": "", + "option": { + "height": "", + "hide-header": "", + "repeat": "", + "title": "" + }, + "options": { + "height-expand": "", + "height-min": "" + }, + "row": { + "collapse": "", + "expand": "", + "menu": { + "add": "", + "add-panel": "", + "add-row-above": "", + "add-row-below": "", + "move-down": "", + "move-row": "", + "move-up": "" + }, + "new": "", + "repeat": { + "learn-more": "", + "warning": "" + } + }, + "row-options": { + "title-option": "" + } + }, + "tabs-layout": { + "description": "", + "menu": { + "move-tab": "" + }, + "name": "", + "tab": { + "menu": { + "add": "", + "add-panel": "", + "add-tab-above": "", + "add-tab-after": "", + "add-tab-before": "", + "move-left": "", + "move-right": "" + }, + "new": "" + }, + "tab-options": { + "title-option": "" + } + }, + "toolbar": { + "add": "", + "add-panel": "", + "add-panel-description": "", + "add-panel-lib": "", + "add-row": "", + "add-tab": "", + "alert-rules": "", + "back-to-dashboard": "", + "dashboard-settings": { + "label": "", + "tooltip": "" + }, + "discard-library-panel-changes": "", + "discard-panel": "", + "discard-panel-new": "", + "edit": { + "label": "", + "tooltip": "" + }, + "edit-dashboard-v2-schema": "", + "enter-edit-mode": { + "label": "", + "tooltip": "" + }, + "exit-edit-mode": { + "label": "", + "tooltip": "" + }, + "libray-panel-description": "", + "mark-favorite": "", + "more-save-options": "", + "open-original": "", + "playlist-next": "", + "playlist-previous": "", + "playlist-stop": "", + "public-dashboard": "", + "refresh": "", + "row-description": "", + "save": "", + "save-dashboard": { + "label": "", + "tooltip": "" + }, + "save-dashboard-copy": { + "label": "", + "tooltip": "" + }, + "save-dashboard-short": "", + "save-library-panel": "", + "settings": "", + "share": { + "label": "", + "tooltip": "" + }, + "share-button": "", + "show-hidden-elements": "", + "switch-old-dashboard": "", + "tabs-description": "", + "unlink-library-panel": "", + "unmark-favorite": "" + }, + "validation": { + "invalid-dashboard-id": "", + "invalid-json": "", + "tags-expected-array": "", + "tags-expected-strings": "" + }, + "viz-panel": { + "options": { + "description": "", + "open-edit": "", + "plugin-type-image": "", + "title-option": "", + "transparent-background": "" + } + } + }, + "dashboard-import": { + "file-dropzone": { + "primary-text": "", + "secondary-text": "" + }, + "form-actions": { + "cancel": "", + "load": "" + }, + "gcom-field": { + "label": "", + "load-button": "", + "placeholder": "", + "validation-required": "" + }, + "json-field": { + "label": "", + "validation-required": "" + } + }, + "dashboard-links": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "title": "" + } + }, + "dashboard-settings": { + "annotations": { + "title": "" + }, + "dashboard-delete-button": "", + "delete-modal": { + "confirmation-text": "", + "delete-button": "", + "title": "" + }, + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "general": { + "auto-refresh-description": "", + "auto-refresh-label": "", + "description-label": "", + "editable-description": "", + "editable-label": "", + "folder-label": "", + "panel-options-graph-tooltip-description": "", + "panel-options-graph-tooltip-label": "", + "panel-options-label": "", + "panels-preload-description": "", + "panels-preload-label": "", + "tags-label": "", + "title": "", + "title-label": "" + }, + "json-editor": { + "save-button": "", + "subtitle": "", + "title": "" + }, + "links": { + "title": "" + }, + "permissions": { + "title": "" + }, + "provisioned-delete-modal": { + "confirm-button": "", + "text-1": "", + "text-2": "", + "text-3": "", + "text-link": "", + "title": "" + }, + "settings": { + "title": "" + }, + "time-picker": { + "hide-time-picker": "", + "now-delay-description": "", + "now-delay-label": "", + "refresh-live-dashboards-description": "", + "refresh-live-dashboards-label": "", + "time-options-label": "", + "time-zone-label": "", + "week-start-label": "" + }, + "time-regions": { + "advanced-description-cron": "", + "advanced-description-rest": "", + "advanced-description-use": "", + "advanced-label": "" + }, + "variables": { + "title": "" + }, + "versions": { + "title": "" + } + }, + "dashboards": { + "panel-edit": { + "angular-deprecation-button-open-panel-json": "", + "angular-deprecation-description": "", + "angular-deprecation-heading": "" + }, + "panel-queries": { + "add-query-from-library": "" + }, + "settings": { + "variables": { + "dependencies": { + "button": "", + "title": "" + } + } + } + }, + "data-source-list": { + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + } + }, + "data-source-picker": { + "add-new-data-source": "", + "built-in-list": { + "description-dashboard": "", + "description-grafana": "", + "description-mixed": "" + }, + "list": { + "no-data-source-message": "" + }, + "modal": { + "configure-new-data-source": "", + "input-placeholder": "", + "title": "" + }, + "open-advanced-button": "" + }, + "data-source-testing-status-page": { + "error-more-details-link": "", + "success-more-details-links": "" + }, + "data-sources": { + "datasource-add-button": { + "label": "" + }, + "empty-state": { + "message": "" + } + }, + "embed": { + "share": { + "time-range-description": "", + "time-range-label": "" + } + }, + "empty-list-cta": { + "pro-tip": "" + }, + "entity-not-found": { + "description": "" + }, + "errors": { + "dashboard-settings": { + "annotations": { + "datasource": "" + } + } + }, + "explore": { + "add-to-dashboard": "", + "drilldownInfo": { + "action": "", + "description": "", + "title": "" + }, + "logs": { + "logs-volume": { + "add-filters": "", + "decrease-timerange": "", + "much-data": "" + }, + "maximum-pinned-logs": "", + "no-logs-found": "", + "scan-for-older-logs": "", + "stop-scan": "" + }, + "rich-history": { + "close-tooltip": "", + "datasource-a-z": "", + "datasource-z-a": "", + "newest-first": "", + "oldest-first": "", + "query-history": "", + "query-library": "", + "settings": "", + "starred": "" + }, + "rich-history-card": { + "add-comment-form": "", + "add-comment-tooltip": "", + "add-to-library": "", + "cancel": "", + "confirm-delete": "", + "copy-query-tooltip": "", + "copy-shortened-link-tooltip": "", + "datasource-icon-label": "", + "datasource-name-label": "", + "datasource-not-exist": "", + "delete-query-confirmation-title": "", + "delete-query-title": "", + "delete-query-tooltip": "", + "delete-starred-query-confirmation-text": "", + "edit-comment-tooltip": "", + "optional-description": "", + "query-comment-label": "", + "query-text-label": "", + "save-comment": "", + "star-query-tooltip": "", + "unstar-query-tooltip": "", + "update-comment-form": "" + }, + "rich-history-container": { + "loading": "" + }, + "rich-history-notification": { + "query-copied": "", + "query-deleted": "" + }, + "rich-history-queries-tab": { + "displaying-partial-queries": "", + "displaying-queries": "", + "filter-aria-label": "", + "filter-history": "", + "filter-placeholder": "", + "history-local": "", + "loading": "", + "loading-results": "", + "search-placeholder": "", + "showing-queries": "", + "sort-aria-label": "", + "sort-placeholder": "" + }, + "rich-history-settings-tab": { + "alert-info": "", + "change-default-tab": "", + "clear-history-info": "", + "clear-query-history": "", + "clear-query-history-button": "", + "delete-confirm": "", + "delete-confirm-text": "", + "delete-title": "", + "history-time-span": "", + "history-time-span-description": "", + "only-show-active-datasource": "", + "query-history-deleted": "", + "retention-period": { + "1-week": "", + "2-days": "", + "2-weeks": "", + "5-days": "" + } + }, + "rich-history-starred-tab": { + "filter-queries-aria-label": "", + "filter-queries-placeholder": "", + "loading": "", + "loading-results": "", + "local-history-message": "", + "search-queries-placeholder": "", + "showing-queries": "", + "sort-queries-aria-label": "", + "sort-queries-placeholder": "" + }, + "rich-history-utils": { + "a-week-ago": "", + "days-ago": "", + "default-from": "", + "default-to": "", + "today": "", + "two-weeks-ago": "", + "yesterday": "" + }, + "rich-history-utils-notification": { + "saving-failed": "", + "update-failed": "" + }, + "run-query": { + "left-pane": "", + "right-pane": "", + "run-query-button": "", + "switch-datasource-button": "" + }, + "secondary-actions": { + "add-from-query-library": "", + "query-add-button": "", + "query-add-button-aria-label": "", + "query-history-button": "", + "query-history-button-aria-label": "", + "query-inspector-button": "", + "query-inspector-button-aria-label": "" + }, + "table": { + "no-data": "", + "title": "", + "title-with-name": "" + }, + "toolbar": { + "add-to-extensions": "", + "add-to-queryless-extensions": "", + "aria-label": "", + "copy-link": "", + "copy-link-abs-time": "", + "copy-links-absolute-category": "", + "copy-links-normal-category": "", + "copy-shortened-link": "", + "copy-shortened-link-abs-time": "", + "copy-shortened-link-label": "", + "copy-shortened-link-menu": "", + "refresh-picker-cancel": "", + "refresh-picker-run": "", + "split-close": "", + "split-close-tooltip": "", + "split-narrow": "", + "split-title": "", + "split-tooltip": "", + "split-widen": "" + } + }, + "explore-metrics": { + "breakdown": { + "clearFilter": "", + "labelSelect": "", + "missing-otel-labels": "", + "noMatchingValue": "", + "sortBy": "" + }, + "related-logs": { + "LrrDocsLink": "", + "openExploreLogs": "", + "relatedLogsUnavailable": "", + "warnExperimentalFeature": "" + }, + "viewBy": "" + }, + "export": { + "json": { + "cancel-button": "", + "copy-button": "", + "download-button": "", + "download-successful_toast_message": "", + "export-externally-label": "", + "info-text": "", + "title": "" + }, + "menu": { + "export-as-json-label": "", + "export-as-json-tooltip": "" + } + }, + "folder-filter": { + "clear-folder-button": "" + }, + "folder-picker": { + "create-instructions": "", + "loading": "" + }, + "forgot-password": { + "back-button": "", + "change-password": { + "skip-button": "", + "submit-button": "" + }, + "contact-admin": "", + "email-sent": "", + "reset-password-header": "", + "send-email-button": "" + }, + "form-prompt": { + "continue-button": "", + "description": "", + "discard-button": "" + }, + "gen-ai": { + "apply-suggestion": "", + "incomplete-request-error": "", + "send-custom-feedback": "" + }, + "get-enterprise": { + "requires-license": "", + "title": "" + }, + "grafana-ui": { + "action-editor": { + "button": { + "confirm": "", + "confirm-action": "" + }, + "inline": { + "add-action": "", + "edit-action": "" + }, + "modal": { + "action-body": "", + "action-method": "", + "action-query-params": "", + "action-title": "", + "action-title-placeholder": "", + "one-click-description": "" + } + }, + "alert": { + "close-button": "" + }, + "auto-save-field": { + "saved": "", + "saving": "" + }, + "card": { + "option": "" + }, + "cascader": { + "clear-button": "" + }, + "color-picker-popover": { + "palette-tab": "", + "spectrum-tab": "" + }, + "confirm-button": { + "cancel": "" + }, + "confirm-content": { + "placeholder": "" + }, + "data-link-editor": { + "info": "", + "new-tab-label": "", + "title-label": "", + "title-placeholder": "", + "url-label": "" + }, + "data-link-editor-modal": { + "cancel": "", + "one-click-description": "", + "save": "" + }, + "data-link-inline-editor": { + "one-click": "" + }, + "data-links-inline-editor": { + "add-link": "", + "edit-link": "", + "one-click": "", + "one-click-enabled": "", + "title-not-provided": "", + "tooltip-edit": "", + "tooltip-remove": "", + "url-not-provided": "" + }, + "data-source-basic-auth-settings": { + "user-label": "", + "user-placeholder": "" + }, + "data-source-http-proxy-settings": { + "oauth-identity-label": "", + "oauth-identity-tooltip": "", + "skip-tls-verify-label": "", + "ts-client-auth-label": "", + "with-ca-cert-label": "", + "with-ca-cert-tooltip": "" + }, + "data-source-http-settings": { + "access-help": "", + "access-help-details": "", + "access-label": "", + "access-options-browser": "", + "access-options-proxy": "", + "allowed-cookies": "", + "allowed-cookies-tooltip": "", + "auth": "", + "azure-auth-label": "", + "azure-auth-tooltip": "", + "basic-auth": "", + "basic-auth-label": "", + "browser-mode-description": "", + "browser-mode-title": "", + "default-url-access-select": "", + "default-url-tooltip": "", + "direct-url-tooltip": "", + "heading": "", + "proxy-url-tooltip": "", + "server-mode-description": "", + "server-mode-title": "", + "timeout-form-label": "", + "timeout-label": "", + "timeout-tooltip": "", + "url-label": "", + "with-credential-label": "", + "with-credential-tooltip": "" + }, + "data-source-settings": { + "alerting-settings-heading": "", + "alerting-settings-label": "", + "alerting-settings-tooltip": "", + "cert-key-reset": "", + "custom-headers-add": "", + "custom-headers-header": "", + "custom-headers-header-placeholder": "", + "custom-headers-header-remove": "", + "custom-headers-header-value": "", + "custom-headers-title": "", + "secure-socks-heading": "", + "secure-socks-label": "", + "secure-socks-tooltip": "", + "tls-certification-label": "", + "tls-certification-placeholder": "", + "tls-client-certification-label": "", + "tls-client-key-label": "", + "tls-client-key-placeholder": "", + "tls-heading": "", + "tls-server-name-label": "", + "tls-tooltip": "" + }, + "date-time-picker": { + "apply": "", + "calendar-icon-label": "", + "cancel": "", + "next-label": "", + "previous-label": "", + "select-placeholder": "" + }, + "drawer": { + "close": "" + }, + "feature-badge": { + "experimental": "", + "new": "", + "preview": "", + "private-preview": "" + }, + "field-link-list": { + "external-links-heading": "" + }, + "file-dropzone": { + "cancel-upload": "", + "file-too-large": "" + }, + "filter-input": { + "clear": "" + }, + "modal": { + "close-tooltip": "" + }, + "named-colors-palette": { + "text-color-swatch": "", + "transparent-swatch": "" + }, + "page-toolbar": { + "go-back": "", + "search-dashboard-name": "", + "search-links": "", + "search-parent-folder": "" + }, + "pagination": { + "next-page": "", + "previous-page": "" + }, + "secret-form-field": { + "reset": "" + }, + "segment-async": { + "error": "", + "loading": "", + "no-options": "" + }, + "select": { + "default-create-label": "", + "no-options-label": "", + "placeholder": "" + }, + "series-color-picker-popover": { + "y-axis-usage": "" + }, + "spinner": { + "aria-label": "" + }, + "table": { + "copy": "", + "csv-counts": "", + "filter-popup-apply": "", + "filter-popup-cancel": "", + "filter-popup-clear": "", + "filter-popup-heading": "", + "no-values-label": "", + "pagination-summary": "" + }, + "tags-input": { + "add": "" + }, + "user-icon": { + "active-text": "" + }, + "value-pill": { + "remove-button": "" + }, + "viz-legend": { + "right-axis-indicator": "" + }, + "viz-tooltip": { + "actions-confirmation-input-placeholder": "", + "actions-confirmation-label": "", + "actions-confirmation-message": "", + "footer-add-annotation": "", + "footer-click-to-action": "", + "footer-click-to-navigate": "" + } + }, + "graph": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "", + "title": "" + } + }, + "help-modal": { + "column-headers": { + "description": "", + "keys": "" + }, + "shortcuts-category": { + "dashboard": "", + "focused-panel": "", + "global": "", + "time-range": "" + }, + "shortcuts-description": { + "change-theme": "", + "collapse-all-rows": "", + "copy-time-range": "", + "dashboard-settings": "", + "duplicate-panel": "", + "exit-edit/setting-views": "", + "expand-all-rows": "", + "go-to-dashboards": "", + "go-to-explore": "", + "go-to-home-dashboard": "", + "go-to-profile": "", + "make-time-range-permanent": "", + "move-time-range-back": "", + "move-time-range-forward": "", + "open-search": "", + "open-shared-modal": "", + "paste-time-range": "", + "refresh-all-panels": "", + "remove-panel": "", + "save-dashboard": "", + "show-all-shortcuts": "", + "toggle-active-mode": "", + "toggle-all-panel-legends": "", + "toggle-auto-fit": "", + "toggle-exemplars": "", + "toggle-graph-crosshair": "", + "toggle-kiosk": "", + "toggle-panel-edit": "", + "toggle-panel-fullscreen": "", + "toggle-panel-legend": "", + "zoom-out-time-range": "" + }, + "title": "" + }, + "help-wizard": { + "download-snapshot": "", + "github-comment": "", + "support-bundle": "", + "troubleshooting-help": "" + }, + "inspector": { + "query": { + "collapse-all": "", + "copy-to-clipboard": "", + "description": "", + "expand-all": "", + "no-data": "", + "refresh": "" + } + }, + "ldap-drawer": { + "attributes-section": { + "description": "", + "email-label": "", + "label": "", + "member-of-label": "", + "name-label": "", + "surname-label": "", + "username-label": "" + }, + "extra-security-section": { + "client-cert-label": "", + "client-cert-placeholder": "", + "client-cert-value-label": "", + "client-cert-value-placeholder": "", + "client-key-label": "", + "client-key-placeholder": "", + "client-key-value-label": "", + "client-key-value-placeholder": "", + "encryption-provider-base-64": "", + "encryption-provider-description": "", + "encryption-provider-file-path": "", + "encryption-provider-label": "", + "label": "", + "min-tls-version-description": "", + "min-tls-version-label": "", + "root-ca-cert-label": "", + "root-ca-cert-placeholder": "", + "root-ca-cert-value-label": "", + "root-ca-cert-value-placeholder": "", + "start-tls-description": "", + "start-tls-label": "", + "tls-ciphers-label": "", + "tls-ciphers-placeholder": "", + "use-ssl-description": "", + "use-ssl-label": "", + "use-ssl-tooltip": "" + }, + "group-mapping": { + "grafana-admin": { + "description": "", + "label": "" + }, + "group-dn": { + "description": "", + "label": "" + }, + "org-id": { + "description": "", + "label": "" + }, + "org-role": { + "label": "" + }, + "remove": { + "button": "" + } + }, + "group-mapping-section": { + "add": { + "button": "" + }, + "description": "", + "group-search-base-dns-label": "", + "group-search-base-dns-placeholder": "", + "group-search-filter-description": "", + "group-search-filter-label": "", + "group-search-filter-user-attribute-description": "", + "group-search-filter-user-attribute-label": "", + "label": "", + "skip-org-role-sync-description": "", + "skip-org-role-sync-label": "" + }, + "misc-section": { + "allow-sign-up-descrition": "", + "allow-sign-up-label": "", + "label": "", + "port-description": "", + "port-label": "", + "timeout-description": "", + "timeout-label": "" + }, + "title": "" + }, + "ldap-settings-page": { + "advanced-settings-section": { + "edit-button": "", + "subtitle": "", + "title": "" + }, + "alert": { + "discard-success": "", + "error-fetching": "", + "error-saving": "", + "error-validate-form": "", + "feature-flag-disabled": "", + "saved": "" + }, + "bind-dn": { + "description": "", + "label": "", + "placeholder": "" + }, + "bind-password": { + "label": "" + }, + "buttons-section": { + "disable-button": "", + "discard-button": "", + "save-and-enable-button": "", + "save-button": "" + }, + "documentation": "", + "host": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "login-form-alert": { + "description": "", + "title": "" + }, + "search_filter": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "search-base-dns": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "subtitle": "", + "title": "" + }, + "library-panel": { + "add-modal": { + "cancel": "", + "create": "", + "error": "", + "folder": "", + "folder-description": "", + "name": "" + }, + "add-widget": { + "title": "" + }, + "empty-state": { + "message": "", + "more-info": "" + } + }, + "library-panels": { + "empty-state": { + "message": "" + }, + "loading-panel-text": "", + "modal": { + "button-cancel": "", + "button-view-panel1": "", + "button-view-panel2": "", + "panel-not-linked": "", + "select-no-options-message": "", + "select-placeholder": "", + "title": "", + "body_one": "", + "body_other": "" + }, + "save": { + "error": "", + "success": "" + } + }, + "link": { + "share": { + "config-alert-description": "", + "config-alert-title": "", + "config-description": "", + "copy-link-button": "", + "copy-to-clipboard": "", + "short-url-label": "", + "time-range-description": "", + "time-range-label": "" + }, + "share-panel": { + "config-description": "", + "download-image": "", + "render-image": "", + "render-image-error": "", + "render-image-error-description": "" + } + }, + "lock-icon": "", + "login": { + "divider": { + "connecting-text": "" + }, + "error": { + "blocked": "", + "invalid-user-or-password": "", + "title": "", + "unknown": "" + }, + "forgot-password": "", + "form": { + "confirmation-code": "", + "confirmation-code-label": "", + "confirmation-code-placeholder": "", + "email-label": "", + "email-placeholder": "", + "email-required": "", + "name-label": "", + "name-placeholder": "", + "password-label": "", + "password-placeholder": "", + "password-required": "", + "submit-label": "", + "submit-loading-label": "", + "username-label": "", + "username-placeholder": "", + "username-required": "", + "verify-email-label": "", + "verify-email-loading-label": "" + }, + "layout": { + "update-password": "" + }, + "services": { + "sing-in-with-prefix": "" + }, + "signup": { + "button-label": "", + "new-to-question": "" + } + }, + "logs": { + "infinite-scroll": { + "end-of-range": "", + "load-more": "", + "load-newer": "", + "load-older": "", + "older-logs": "" + }, + "log-details": { + "fields": "", + "links": "", + "log-line": "", + "no-details": "" + }, + "log-line-menu": { + "copy-link": "", + "copy-log": "", + "icon-label": "", + "pin-to-outline": "", + "show-context": "", + "unpin-from-outline": "" + }, + "log-row-message": { + "ellipsis": "", + "more": "", + "see-details": "" + }, + "log-rows": { + "disable-popover": { + "confirm": "", + "message": "", + "title": "" + }, + "disable-popover-message": { + "shortcut": "" + } + }, + "logs-navigation": { + "newer-logs": "", + "older-logs": "", + "scroll-bottom": "", + "scroll-top": "", + "start-of-range": "" + }, + "popover-menu": { + "copy": "", + "disable-menu": "", + "line-contains": "", + "line-contains-not": "" + } + }, + "migrate-to-cloud": { + "build-snapshot": { + "description": "", + "title": "", + "when-complete": "" + }, + "building-snapshot": { + "description": "", + "description-eta": "", + "title": "" + }, + "can-i-move": { + "body": "", + "link-title": "", + "title": "" + }, + "connect-modal": { + "body-cloud-stack": "", + "body-get-started": "", + "body-sign-up": "", + "body-token": "", + "body-token-field": "", + "body-token-field-placeholder": "", + "body-token-instructions": "", + "body-view-stacks": "", + "cancel": "", + "connect": "", + "connecting": "", + "title": "", + "token-error-title": "", + "token-errors": { + "instance-request-error": "", + "instance-unreachable": "", + "migration-disabled": "", + "session-creation-failure": "", + "token-invalid": "", + "token-not-saved": "", + "token-request-error": "", + "token-validation-failure": "" + }, + "token-required-error": "" + }, + "cta": { + "button": "", + "header": "" + }, + "delete-migration-token-confirm": { + "body": "", + "confirm-button": "", + "error-title": "", + "title": "" + }, + "disconnect-modal": { + "body": "", + "cancel": "", + "disconnect": "", + "disconnecting": "", + "error": "", + "title": "" + }, + "get-started": { + "body": "", + "configure-pdc-link": "", + "link-title": "", + "step-1": "", + "step-2": "", + "step-3": "", + "step-4": "", + "step-5": "", + "title": "" + }, + "is-it-secure": { + "body": "", + "link-title": "", + "title": "" + }, + "migrate-to-this-stack": { + "body": "", + "link-title": "", + "title": "" + }, + "migrated-counts": { + "alert_rule_groups": "", + "alert_rules": "", + "contact_points": "", + "dashboards": "", + "datasources": "", + "folders": "", + "library_elements": "", + "mute_timings": "", + "notification_policies": "", + "notification_templates": "", + "plugins": "" + }, + "migration-token": { + "delete-button": "", + "delete-modal-body": "", + "delete-modal-cancel": "", + "delete-modal-confirm": "", + "delete-modal-deleting": "", + "delete-modal-title": "", + "error-body": "", + "error-title": "", + "generate-button": "", + "generate-button-loading": "", + "modal-close": "", + "modal-copy-and-close": "", + "modal-copy-button": "", + "modal-field-description": "", + "modal-field-label": "", + "modal-title": "", + "status": "" + }, + "onprem": { + "cancel-snapshot-error-title": "", + "create-snapshot-error-title": "", + "disconnect-error-title": "", + "error-see-server-logs": "", + "get-session-error-title": "", + "get-snapshot-error-title": "", + "migration-finished-with-caveat-title": "", + "migration-finished-with-errors-body": "", + "migration-finished-with-warnings-body": "", + "snapshot-error-status-body": "", + "snapshot-error-status-title": "", + "success-message": "", + "success-message-generic": "", + "success-title": "", + "upload-snapshot-error-title": "" + }, + "pdc": { + "body": "", + "link-title": "", + "title": "" + }, + "pricing": { + "body": "", + "link-title": "", + "title": "" + }, + "public-preview": { + "button-text": "", + "message": "", + "message-cloud": "", + "title": "" + }, + "resource-details": { + "dismiss-button": "", + "error-messages": { + "dashboard-already-managed": "", + "datasource-already-managed": "", + "datasource-invalid-url": "", + "datasource-name-conflict": "", + "folder-name-conflict": "", + "generic-error": "", + "internal-service-error": "", + "library-element-name-conflict": "", + "resource-conflict": "", + "unexpected-error": "", + "unsupported-data-type": "" + }, + "error-title": "", + "generic-title": "", + "missing-message": "", + "resource-summary": "", + "title": "", + "warning-title": "" + }, + "resource-status": { + "error-details-button": "", + "failed": "", + "migrated": "", + "migrating": "", + "not-migrated": "", + "unknown": "", + "warning": "", + "warning-details-button": "" + }, + "resource-table": { + "dashboard-load-error": "", + "error-library-element-sub": "", + "error-library-element-title": "", + "unknown-datasource-title": "", + "unknown-datasource-type": "" + }, + "resource-type": { + "alert_rule": "", + "alert_rule_group": "", + "contact_point": "", + "dashboard": "", + "datasource": "", + "folder": "", + "library_element": "", + "mute_timing": "", + "notification_policy": "", + "notification_template": "", + "plugin": "", + "unknown": "" + }, + "summary": { + "cancel-snapshot": "", + "disconnect": "", + "errored-resource-count": "", + "page-loading": "", + "rebuild-snapshot": "", + "snapshot-date": "", + "snapshot-not-created": "", + "start-migration": "", + "successful-resource-count": "", + "target-stack-title": "", + "total-resource-count": "", + "upload-migration": "" + }, + "support-types-disclosure": { + "text": "" + }, + "token-status": { + "active": "", + "no-active": "", + "unknown": "", + "unknown-error": "" + }, + "what-is-cloud": { + "body": "", + "link-title": "", + "title": "" + }, + "why-host": { + "body": "", + "link-title": "", + "title": "" + } + }, + "multicombobox": { + "all": { + "title": "", + "title-filtered": "" + }, + "clear": { + "title": "" + } + }, + "nav": { + "add-new-connections": { + "title": "" + }, + "admin": { + "subtitle": "", + "title": "" + }, + "alert-list-legacy": { + "title": "" + }, + "alerting": { + "subtitle": "", + "title": "" + }, + "alerting-admin": { + "subtitle": "", + "title": "" + }, + "alerting-am-routes": { + "subtitle": "", + "title": "" + }, + "alerting-channels": { + "title": "" + }, + "alerting-groups": { + "subtitle": "", + "title": "" + }, + "alerting-home": { + "title": "" + }, + "alerting-legacy": { + "title": "" + }, + "alerting-list": { + "subtitle": "", + "title": "" + }, + "alerting-receivers": { + "subtitle": "", + "title": "" + }, + "alerting-silences": { + "subtitle": "", + "title": "" + }, + "alerting-upgrade": { + "subtitle": "", + "title": "" + }, + "alerts-and-incidents": { + "subtitle": "", + "title": "" + }, + "api-keys": { + "subtitle": "", + "title": "" + }, + "application": { + "title": "" + }, + "apps": { + "subtitle": "", + "title": "" + }, + "authentication": { + "title": "" + }, + "bookmarks": { + "title": "" + }, + "bookmarks-empty": { + "title": "" + }, + "collector": { + "title": "" + }, + "config": { + "title": "" + }, + "config-access": { + "subtitle": "", + "title": "" + }, + "config-general": { + "subtitle": "", + "title": "" + }, + "config-plugins": { + "subtitle": "", + "title": "" + }, + "connect-data": { + "title": "" + }, + "connections": { + "subtitle": "", + "title": "" + }, + "correlations": { + "subtitle": "", + "title": "" + }, + "create": { + "title": "" + }, + "create-alert": { + "title": "" + }, + "create-dashboard": { + "title": "" + }, + "create-folder": { + "title": "" + }, + "create-import": { + "title": "" + }, + "dashboards": { + "subtitle": "", + "title": "" + }, + "data-sources": { + "subtitle": "", + "title": "" + }, + "databases": { + "title": "" + }, + "datasources": { + "subtitle": "", + "title": "" + }, + "detect": { + "title": "" + }, + "drilldown": { + "title": "" + }, + "explore": { + "title": "" + }, + "frontend": { + "subtitle": "", + "title": "" + }, + "frontend-app": { + "title": "" + }, + "global-orgs": { + "subtitle": "", + "title": "" + }, + "global-users": { + "subtitle": "", + "title": "" + }, + "grafana-quaderno": { + "title": "" + }, + "groupsync": { + "subtitle": "" + }, + "help": { + "title": "" + }, + "help/community": "", + "help/documentation": "", + "help/keyboard-shortcuts": "", + "help/support": "", + "history-container": { + "drawer-tittle": "" + }, + "history-wrapper": { + "collapse": "", + "expand": "", + "icon-selected": "", + "icon-unselected": "", + "show-more": "", + "today": "", + "yesterday": "" + }, + "home": { + "title": "" + }, + "incidents": { + "title": "" + }, + "infrastructure": { + "subtitle": "", + "title": "" + }, + "integrations": { + "title": "" + }, + "k6": { + "title": "" + }, + "kubernetes": { + "title": "" + }, + "library-panels": { + "subtitle": "", + "title": "" + }, + "machine-learning": { + "title": "" + }, + "manage-folder": { + "subtitle": "" + }, + "migrate-to-cloud": { + "subtitle": "", + "title": "" + }, + "monitoring": { + "subtitle": "", + "title": "" + }, + "new": { + "title": "" + }, + "new-dashboard": { + "title": "" + }, + "new-folder": { + "title": "" + }, + "oncall": { + "title": "" + }, + "org-settings": { + "subtitle": "", + "title": "" + }, + "playlists": { + "subtitle": "", + "title": "" + }, + "plugins": { + "subtitle": "", + "title": "" + }, + "private-data-source-connections": { + "subtitle": "", + "title": "" + }, + "profile/notifications": { + "title": "" + }, + "profile/password": { + "title": "" + }, + "profile/settings": { + "title": "" + }, + "profiles": { + "title": "" + }, + "public": { + "title": "" + }, + "recently-deleted": { + "subtitle": "", + "title": "" + }, + "recorded-queries": { + "title": "" + }, + "reporting": { + "title": "" + }, + "scenes": { + "title": "" + }, + "search": { + "placeholderCommandPalette": "" + }, + "search-dashboards": { + "title": "" + }, + "server-settings": { + "subtitle": "", + "title": "" + }, + "service-accounts": { + "subtitle": "", + "title": "" + }, + "setup-guide": { + "title": "" + }, + "shared-dashboard": { + "subtitle": "", + "title": "" + }, + "sign-out": { + "title": "" + }, + "slo": { + "title": "" + }, + "snapshots": { + "subtitle": "", + "title": "" + }, + "starred": { + "title": "" + }, + "starred-empty": { + "title": "" + }, + "statistics-and-licensing": { + "title": "" + }, + "storage": { + "subtitle": "", + "title": "" + }, + "support-bundles": { + "subtitle": "", + "title": "" + }, + "synthetics": { + "title": "" + }, + "teams": { + "subtitle": "", + "title": "" + }, + "testing-and-synthetics": { + "subtitle": "", + "title": "" + }, + "upgrading": { + "title": "" + }, + "users": { + "subtitle": "", + "title": "" + } + }, + "navigation": { + "invite-user": { + "invite-button": "", + "invite-tooltip": "" + }, + "item": { + "add-bookmark": "", + "remove-bookmark": "" + }, + "kiosk": { + "tv-alert": "" + }, + "megamenu": { + "close": "", + "dock": "", + "list-label": "", + "open": "", + "undock": "" + }, + "rss-button": "" + }, + "news": { + "drawer": { + "close": "" + }, + "title": "" + }, + "notifications": { + "empty-state": { + "description": "", + "title": "" + }, + "starred-dashboard": "", + "unstarred-dashboard": "" + }, + "oauth": { + "form": { + "server-discovery-action-button": "", + "server-discovery-modal-close": "", + "server-discovery-modal-loading": "", + "server-discovery-modal-submit": "" + }, + "login": { + "error": "" + } + }, + "panel": { + "header-menu": { + "copy": "", + "create-library-panel": "", + "duplicate": "", + "edit": "", + "explore": "", + "get-help": "", + "hide-legend": "", + "inspect": "", + "inspect-data": "", + "inspect-json": "", + "more": "", + "new-alert-rule": "", + "query": "", + "remove": "", + "replace-library-panel": "", + "share": "", + "show-legend": "", + "unlink-library-panel": "", + "view": "" + } + }, + "panel-search": { + "no-matches": "", + "unsupported-layout": "" + }, + "panel-type-filter": { + "clear-button": "" + }, + "playlist-edit": { + "error-prefix": "", + "form": { + "add-tag-label": "", + "add-tag-placeholder": "", + "add-title-label": "", + "cancel": "", + "heading": "", + "interval-label": "", + "interval-placeholder": "", + "interval-required": "", + "name-label": "", + "name-placeholder": "", + "name-required": "", + "save": "", + "table-delete": "", + "table-drag": "", + "table-empty": "", + "table-heading": "" + }, + "sub-title": "", + "title": "" + }, + "playlist-page": { + "card": { + "delete": "", + "edit": "", + "start": "", + "tooltip": "" + }, + "create-button": { + "title": "" + }, + "delete-modal": { + "body": "", + "confirm-text": "" + }, + "empty": { + "button": "", + "pro-tip": "", + "title": "" + } + }, + "playlists": { + "empty-state": { + "message": "" + } + }, + "plugins": { + "catalog": { + "no-updates-available": "", + "update-all": { + "all-plugins-updated": "", + "available-header": "", + "button": "", + "cloud-update-message": "", + "error": "", + "error-status-text": "", + "header": "", + "installed-header": "", + "modal-confirmation": "", + "modal-dismiss": "", + "modal-in-progress": "", + "modal-title": "", + "name-header": "", + "update-header": "", + "update-status-text": "" + }, + "versions": { + "confirmation-text-1": "", + "confirmation-text-2": "", + "downgrade-confirm": "", + "downgrade-title": "" + } + }, + "details": { + "connections-tab": { + "description": "" + }, + "labels": { + "contactGrafanaLabs": "", + "customLinks": "", + "customLinksTooltip": "", + "dependencies": "", + "documentation": "", + "downloads": "", + "from": "", + "installedVersion": "", + "lastCommitDate": "", + "latestVersion": "", + "license": "", + "raiseAnIssue": "", + "reportAbuse": "", + "reportAbuseTooltip": "", + "repository": "", + "signature": "", + "status": "", + "updatedAt": "" + }, + "modal": { + "cancel": "", + "copyEmail": "", + "description": "", + "node": "", + "title": "" + } + }, + "empty-state": { + "message": "" + }, + "filter": { + "disabled": "", + "sort": "", + "sort-list": "", + "state": "" + }, + "plugin-help": { + "error": "", + "not-found": "" + } + }, + "profile": { + "change-password": { + "cancel-button": "", + "cannot-change-password-message": "", + "change-password-button": "", + "confirm-password-label": "", + "confirm-password-required": "", + "ldap-auth-proxy-message": "", + "new-password-label": "", + "new-password-required": "", + "new-password-same-as-old": "", + "old-password-label": "", + "old-password-required": "", + "passwords-must-match": "", + "strong-password-validation-register": "" + } + }, + "public-dashboard": { + "acknowledgment-checkboxes": { + "ack-title": "", + "data-src-ack-desc": "", + "data-src-ack-tooltip": "", + "public-ack-desc": "", + "public-ack-tooltip": "", + "usage-ack-desc": "", + "usage-ack-desc-tooltip": "" + }, + "config": { + "can-view-dashboard-radio-button-label": "", + "copy-button": "", + "dashboard-url-field-label": "", + "email-share-type-option-label": "", + "pause-sharing-dashboard-label": "", + "public-share-type-option-label": "", + "revoke-public-URL-button": "", + "revoke-public-URL-button-title": "", + "settings-title": "" + }, + "configuration": { + "display-annotations-description": "", + "display-annotations-label": "", + "enable-time-range-description": "", + "enable-time-range-label": "", + "settings-label": "", + "success-pause": "", + "success-resume": "", + "success-update": "", + "success-update-old": "", + "time-range-label": "", + "time-range-tooltip": "" + }, + "create-page": { + "generate-public-url-button": "", + "unsupported-features-desc": "", + "welcome-title": "" + }, + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "email-sharing": { + "accept-button": "", + "alert-text": "", + "bill-ack": "", + "cancel-button": "", + "input-invalid-email-text": "", + "input-required-email-text": "", + "invite-button": "", + "invite-field-desc": "", + "invite-field-label": "", + "learn-more-button": "", + "recipient-email-placeholder": "", + "recipient-invalid-email-text": "", + "recipient-invitation-button": "", + "recipient-invitation-description": "", + "recipient-invitation-tooltip": "", + "recipient-list-description": "", + "recipient-list-title": "", + "recipient-required-email-text": "", + "resend-button": "", + "resend-button-title": "", + "resend-invite-label": "", + "revoke-access-label": "", + "revoke-button": "", + "revoke-button-title": "", + "success-creation": "", + "success-share-type-change": "" + }, + "modal-alerts": { + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "save-dashboard-changes-alert-title": "", + "unsupport-data-source-alert-readmore-link": "", + "unsupported-data-source-alert-desc": "", + "unsupported-data-source-alert-title": "", + "unsupported-template-variable-alert-desc": "", + "unsupported-template-variable-alert-title": "" + }, + "public-sharing": { + "accept-button": "", + "alert-text": "", + "cancel-button": "", + "learn-more-button": "", + "public-ack": "", + "success-creation": "", + "success-share-type-change": "" + }, + "settings-bar-header": { + "collapse-settings-tooltip": "", + "expand-settings-tooltip": "" + }, + "settings-configuration": { + "default-time-range-label": "", + "default-time-range-label-desc": "", + "show-annotations-label": "", + "show-annotations-label-desc": "", + "time-range-picker-label": "", + "time-range-picker-label-desc": "" + }, + "settings-summary": { + "annotations-hide-text": "", + "annotations-show-text": "", + "time-range-picker-disabled-text": "", + "time-range-picker-enabled-text": "", + "time-range-text": "" + }, + "share": { + "success-delete": "", + "success-delete-old": "" + }, + "share-configuration": { + "share-type-label": "" + }, + "share-externally": { + "copy-link-button": "", + "email-share-type-option-description": "", + "email-share-type-option-label": "", + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "pause-access-button": "", + "pause-access-tooltip": "", + "public-share-type-option-description": "", + "public-share-type-option-label": "", + "resume-access-button": "", + "revoke-access-button": "", + "revoke-access-description": "", + "unsupported-data-source-alert-desc": "" + }, + "sharing": { + "success-creation": "" + } + }, + "public-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "public-dashboard-users-access-list": { + "dashboard-modal": { + "external-link": "", + "loading-text": "", + "open-dashboard-list-text": "", + "public-dashboard-link": "", + "public-dashboard-setting": "", + "sharing-setting": "" + }, + "delete-user-modal": { + "delete-user-button-text": "", + "delete-user-cancel-button": "", + "delete-user-revoke-access-button": "", + "revoke-access-title": "", + "revoke-user-access-modal-desc-line1": "", + "revoke-user-access-modal-desc-line2": "" + }, + "delete-user-shared-dashboards-modal": { + "revoke-user-access-modal-desc-line2": "" + }, + "modal": { + "dashboard-modal-title": "", + "shared-dashboard-modal-title": "" + }, + "table-body": { + "dashboard-count_one": "", + "dashboard-count_other": "" + }, + "table-header": { + "activated-label": "", + "activated-tooltip": "", + "email-label": "", + "last-active-label": "", + "origin-label": "", + "role-label": "" + } + }, + "query-operation": { + "header": { + "collapse-row": "", + "datasource-help": "", + "drag-and-drop": "", + "duplicate-query": "", + "expand-row": "", + "hide-response": "", + "remove-query": "", + "show-response": "", + "toggle-edit-mode": "" + }, + "query-editor-not-exported": "" + }, + "recently-deleted": { + "buttons": { + "delete": "", + "restore": "" + }, + "page": { + "no-deleted-dashboards": "", + "no-deleted-dashboards-text": "", + "no-search-result": "" + }, + "permanently-delete-modal": { + "confirm-text": "", + "delete-button": "", + "delete-loading": "", + "title": "", + "text_one": "", + "text_other": "" + }, + "restore-modal": { + "restore-button": "", + "restore-loading": "", + "title": "", + "folder-picker-text_one": "", + "folder-picker-text_other": "", + "text_one": "", + "text_other": "" + } + }, + "recentlyDeleted": { + "filter": { + "placeholder": "" + } + }, + "reduce": { + "strictMode": { + "description": "", + "title": "" + } + }, + "refresh-picker": { + "aria-label": { + "choose-interval": "", + "duration-selected": "" + }, + "auto-option": { + "aria-label": "", + "label": "" + }, + "live-option": { + "aria-label": "", + "label": "" + }, + "off-option": { + "aria-label": "", + "label": "" + }, + "tooltip": { + "interval-selected": "", + "turned-off": "" + } + }, + "return-to-previous": { + "button": { + "label": "" + }, + "dismissable-button": "" + }, + "role-picker": { + "built-in": { + "basic-roles": "" + }, + "input": { + "no-roles": "" + }, + "menu": { + "clear-button": "", + "tooltip": "" + }, + "sub-menu": { + "clear-button": "" + }, + "title": { + "description": "" + } + }, + "role-picker-drawer": { + "basic-roles": { + "label": "" + } + }, + "route-error": { + "description": "", + "reload-button": "", + "title": "" + }, + "save-dashboards": { + "message-length": { + "info": "", + "title": "" + }, + "name-exists": { + "message-info": "", + "message-suggestion": "", + "title": "" + } + }, + "scopes": { + "dashboards": { + "collapse": "", + "expand": "", + "loading": "", + "noResultsForFilter": "", + "noResultsForFilterClear": "", + "noResultsForScopes": "", + "noResultsNoScopes": "", + "search": "", + "toggle": { + "collapse": "", + "disabled": "", + "expand": "" + } + }, + "selector": { + "apply": "", + "cancel": "", + "input": { + "placeholder": "", + "removeAll": "" + }, + "title": "" + }, + "tree": { + "collapse": "", + "expand": "", + "headline": { + "noResults": "", + "recommended": "", + "results": "" + }, + "search": "" + } + }, + "search": { + "actions": { + "include-panels": "", + "remove-datasource-filter": "", + "sort-placeholder": "", + "starred": "", + "view-as-folders": "", + "view-as-list": "" + }, + "dashboard-actions": { + "import": "", + "new": "", + "new-dashboard": "", + "new-folder": "" + }, + "results-table": { + "datasource-header": "", + "deleted-less-than-1-min": "", + "deleted-remaining-header": "", + "location-header": "", + "name-header": "", + "tags-header": "", + "type-dashboard": "", + "type-folder": "", + "type-header": "" + }, + "search-input": { + "include-panels-placeholder": "", + "placeholder": "" + } + }, + "select": { + "select-menu": { + "selected-count": "" + } + }, + "service-account-create-page": { + "create": { + "button": "" + }, + "name": { + "label": "", + "required-error": "" + }, + "page-nav": { + "label": "" + }, + "role": { + "label": "" + } + }, + "service-accounts": { + "empty-state": { + "button-title": "", + "message": "", + "more-info": "", + "title": "" + } + }, + "share-dashboard": { + "menu": { + "export-json-title": "", + "share-externally-title": "", + "share-internally-title": "", + "share-snapshot-title": "" + }, + "share-button": "", + "share-button-tooltip": "" + }, + "share-drawer": { + "confirm-action": { + "back-arrow-button": "", + "cancel-button": "" + } + }, + "share-modal": { + "dashboard": { + "title": "" + }, + "embed": { + "copy": "", + "html": "", + "html-description": "", + "info": "", + "time-range": "" + }, + "export": { + "back-button": "", + "cancel-button": "", + "info-text": "", + "loading": "", + "save-button": "", + "share-externally-label": "", + "view-button": "" + }, + "library": { + "info": "" + }, + "link": { + "copy-link-button": "", + "info-text": "", + "link-url": "", + "render-alert": "", + "render-instructions": "", + "rendered-image": "", + "save-alert": "", + "save-dashboard": "", + "shorten-url": "", + "time-range-description": "", + "time-range-label": "" + }, + "panel": { + "title": "" + }, + "snapshot": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "deleted-message": "", + "expire": "", + "expire-day": "", + "expire-hour": "", + "expire-never": "", + "expire-week": "", + "info-text-1": "", + "info-text-2": "", + "local-button": "", + "mistake-message": "", + "name": "", + "timeout": "", + "timeout-description": "", + "url-label": "" + }, + "tab-title": { + "embed": "", + "export": "", + "library-panel": "", + "link": "", + "panel-embed": "", + "public-dashboard": "", + "public-dashboard-title": "", + "snapshot": "" + }, + "theme-picker": { + "current": "", + "dark": "", + "field-name": "", + "light": "" + }, + "view-json": { + "copy-button": "" + } + }, + "share-panel": { + "drawer": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "" + }, + "menu": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "", + "share-snapshot-title": "" + }, + "new-library-panel": { + "cancel-button": "", + "create-button": "" + } + }, + "share-panel-image": { + "preview": { + "title": "" + }, + "settings": { + "height-label": "", + "height-min": "", + "height-placeholder": "", + "height-required": "", + "max-warning": "", + "scale-factor-label": "", + "scale-factor-min": "", + "scale-factor-placeholder": "", + "scale-factor-required": "", + "title": "", + "width-label": "", + "width-min": "", + "width-placeholder": "", + "width-required": "" + } + }, + "share-playlist": { + "checkbox-description": "", + "checkbox-label": "", + "copy-link-button": "", + "link-url-label": "", + "mode": "", + "mode-kiosk": "", + "mode-normal": "", + "title": "" + }, + "shared": { + "preferences": { + "theme": { + "dark-label": "", + "light-label": "", + "system-label": "" + } + } + }, + "shared-dashboard": { + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "fields": { + "timezone-label": "" + } + }, + "shared-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "shared-preferences": { + "fields": { + "home-dashboard-label": "", + "home-dashboard-placeholder": "", + "locale-label": "", + "locale-placeholder": "", + "theme-description": "", + "theme-label": "", + "week-start-label": "" + }, + "theme": { + "default-label": "" + }, + "title": "" + }, + "sign-up": { + "back-button": "", + "submit-button": "", + "verify": { + "back-button": "", + "complete-button": "", + "header": "", + "info": "", + "send-button": "" + } + }, + "silences": { + "empty-state": { + "button-title": "", + "title": "" + }, + "table": { + "add-silence-button": "", + "edit-button": "", + "expired-silences": "", + "no-matching-silences": "", + "noConfig": "", + "recreate-button": "", + "unsilence-button": "" + } + }, + "silences-table": { + "header": { + "alert-name": "", + "state": "" + } + }, + "snapshot": { + "empty-state": { + "message": "", + "more-info": "" + }, + "external-badge": "", + "name-column-header": "", + "share": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "delete-description": "", + "delete-permission-tooltip": "", + "delete-title": "", + "deleted-alert": "", + "expiration-label": "", + "info-alert": "", + "learn-more-button": "", + "local-button": "", + "name-label": "", + "new-snapshot-button": "", + "success-creation": "", + "success-delete": "", + "view-all-button": "" + }, + "share-panel": { + "info-alert": "" + }, + "url-column-header": "", + "view-button": "" + }, + "table": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "" + } + }, + "tag-filter": { + "clear-button": "", + "loading": "", + "no-tags": "", + "placeholder": "" + }, + "teams": { + "empty-state": { + "button-title": "", + "message": "", + "pro-tip": "", + "title": "" + } + }, + "theme-preview": { + "breadcrumbs": { + "dashboards": "", + "home": "" + }, + "panel": { + "form-label": "", + "title": "" + } + }, + "time-picker": { + "absolute": { + "recent-title": "", + "title": "" + }, + "calendar": { + "apply-button": "", + "cancel-button": "", + "close": "", + "next-month": "", + "previous-month": "", + "select-time": "" + }, + "content": { + "empty-recent-list-docs": "", + "empty-recent-list-info": "", + "filter-placeholder": "" + }, + "copy-paste": { + "copy-success-message": "", + "default-error-message": "", + "default-error-title": "", + "tooltip-copy": "", + "tooltip-paste": "" + }, + "footer": { + "change-settings-button": "", + "fiscal-year-option": "", + "fiscal-year-start": "", + "time-zone-option": "", + "time-zone-selection": "" + }, + "range-content": { + "apply-button": "", + "default-error": "", + "fiscal-year": "", + "from-input": "", + "open-input-calendar": "", + "range-error": "", + "to-input": "" + }, + "range-picker": { + "backwards-time-aria-label": "", + "current-time-selected": "", + "forwards-time-aria-label": "", + "to": "", + "zoom-out-button": "", + "zoom-out-tooltip": "" + }, + "time-range": { + "apply": "", + "aria-role": "", + "default-title": "", + "example": "", + "example-details": "", + "example-title": "", + "from-label": "", + "from-to": "", + "more-info": "", + "specify": "", + "submit-button-label": "", + "supported-formats": "", + "to-label": "" + }, + "zone": { + "select-aria-label": "", + "select-search-input": "" + } + }, + "trails": { + "bookmarks": { + "or-view-bookmarks": "" + }, + "card": { + "date-created": "" + }, + "home": { + "learn-more": "", + "lets-start": "", + "start-your-metrics-exploration": "", + "subtitle": "" + }, + "metric-select": { + "filter-by": "", + "native-histogram": "", + "new-badge": "", + "otel-switch": "" + }, + "native-histogram-banner": { + "ch-heatmap": "", + "ch-histogram": "", + "click-histogram": "", + "hide-examples": "", + "learn-more": "", + "metric-examples": "", + "nh-heatmap": "", + "nh-histogram": "", + "now": "", + "previously": "", + "see-examples": "", + "sentence": "" + }, + "recent-metrics": { + "or-view-a-recent-exploration": "" + }, + "settings": { + "always-keep-selected-metric-graph-in-view": "", + "show-previews-of-metric-graphs": "" + } + }, + "transformations": { + "empty": { + "add-transformation-body": "", + "add-transformation-header": "" + } + }, + "upgrade-box": { + "discovery-text": "", + "discovery-text-continued": "", + "get-started": "", + "learn-more": "", + "upgrade-button": "" + }, + "user-orgs": { + "current-org-button": "", + "name-column": "", + "role-column": "", + "select-org-button": "", + "title": "" + }, + "user-profile": { + "fields": { + "email-error": "", + "email-label": "", + "name-error": "", + "name-label": "", + "username-label": "" + }, + "tabs": { + "general": "" + } + }, + "user-session": { + "auth-module-column": "", + "browser-column": "", + "created-at-column": "", + "identity-provider-column": "", + "ip-column": "", + "revoke": "", + "seen-at-column": "" + }, + "user-sessions": { + "loading": "" + }, + "users": { + "empty-state": { + "message": "" + } + }, + "users-access-list": { + "tabs": { + "public-dashboard-users-tab-title": "", + "shared-dashboard-users-tab-title": "" + } + }, + "variable": { + "adhoc": { + "placeholder": "" + }, + "dropdown": { + "placeholder": "" + }, + "picker": { + "link-all": "", + "option-all": "", + "option-selected-values": "", + "option-tooltip": "" + }, + "textbox": { + "placeholder": "" + } + }, + "variables": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + }, + "unknown-table": { + "loading": "", + "no-unknowns": "", + "renamed-or-missing-variables": "", + "variable": "" + } + } +} \ No newline at end of file diff --git a/public/locales/zh-Hans/grafana.json b/public/locales/zh-Hans/grafana.json index 03da0813eb6..4d5daac76cc 100644 --- a/public/locales/zh-Hans/grafana.json +++ b/public/locales/zh-Hans/grafana.json @@ -184,7 +184,8 @@ "rule-identifier": "", "rule-type": "", "state-error-timeout": "", - "state-no-data": "" + "state-no-data": "", + "target-datasource-uid": "" }, "alert-recording-rule-form": { "evaluation-behaviour": { @@ -500,6 +501,10 @@ "preview": "", "previewCondition": "" }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, "rule-form": { "evaluation": { "evaluation-group-and-interval": "", @@ -1059,23 +1064,18 @@ "elements": { "dashboard": "", "objects": "", + "panel": "", "panels": "", + "row": "", "rows": "", + "tab": "", "tabs": "" }, - "objects": { - "multi-select": { - "selection-number": "" - } - }, "open": "", "row": { "header": { "hide": "", "title": "" - }, - "multi-select": { - "title": "" } } }, @@ -1156,13 +1156,11 @@ "copy-or-duplicate": "", "delete": "", "duplicate": "", - "layout": "", - "panels-title": "" + "layout": "" } }, "options": { "description": "", - "title": "", "title-option": "" }, "outline": { @@ -1205,7 +1203,6 @@ }, "rows-layout": { "description": "", - "item-name": "", "name": "", "option": { "height": "", @@ -1244,9 +1241,6 @@ "menu": { "move-tab": "" }, - "multi-select": { - "title": "" - }, "name": "", "tab": { "menu": { @@ -1261,7 +1255,6 @@ "new": "" }, "tab-options": { - "title": "", "title-option": "" } }, @@ -1338,7 +1331,6 @@ "description": "", "open-edit": "", "plugin-type-image": "", - "title": "", "title-option": "", "transparent-background": "" } diff --git a/public/locales/zh-Hant/grafana.json b/public/locales/zh-Hant/grafana.json new file mode 100644 index 00000000000..7d47740aff8 --- /dev/null +++ b/public/locales/zh-Hant/grafana.json @@ -0,0 +1,3996 @@ +{ + "_comment": "", + "access-control": { + "add-permission": { + "role-label": "", + "serviceaccount-label": "", + "team-label": "", + "title": "", + "user-label": "" + }, + "add-permissions": { + "save": "" + }, + "permission-list": { + "permission": "" + }, + "permission-list-item": { + "inherited": "" + }, + "permissions": { + "add-label": "", + "no-permissions": "", + "permissions-change-warning": "", + "role": "", + "serviceaccount": "", + "team": "", + "title": "", + "user": "" + } + }, + "action-editor": { + "modal": { + "cancel-button": "", + "save-button": "" + } + }, + "admin": { + "anon-users": { + "not-found": "" + }, + "edit-org": { + "access-denied": "", + "heading": "", + "update-button": "", + "users-heading": "" + }, + "feature-toggles": { + "sub-title": "" + }, + "get-enterprise": { + "contact-us": "", + "description": "", + "features-heading": "", + "included-description": "", + "included-heading": "", + "service-title": "", + "team-sync-details": "", + "title": "" + }, + "ldap": { + "test-mapping-heading": "", + "test-mapping-run-button": "" + }, + "ldap-permissions": { + "active": "", + "admin": "", + "inactive": "" + }, + "ldap-status": { + "title": "" + }, + "ldap-sync": { + "debug-button": "", + "external-sync-description": "", + "external-sync-label": "", + "next-sync-label": "", + "not-enabled": "", + "sync-button": "", + "title": "" + }, + "ldap-sync-info": { + "title": "" + }, + "ldap-user-groups": { + "no-org-found": "" + }, + "ldap-user-info": { + "no-team": "" + }, + "org-uers": { + "last-seen-never": "" + }, + "org-users": { + "not-editable": "" + }, + "orgs": { + "delete-body": "", + "id-header": "", + "name-header": "", + "new-org-button": "" + }, + "server-settings": { + "alerts-button": "", + "dashboards-button": "", + "data-sources-button": "", + "not-found": "", + "title": "", + "users-button": "" + }, + "settings": { + "info-description": "" + }, + "upgrade-info": { + "title": "" + }, + "user-orgs": { + "add-button": "", + "change-role-button": "", + "external-user-tooltip": "", + "remove-button": "", + "role-not-editable": "", + "title": "" + }, + "user-orgs-modal": { + "add-button": "", + "cancel-button": "" + }, + "user-permissions": { + "change-button": "", + "grafana-admin-key": "", + "grafana-admin-no": "", + "grafana-admin-yes": "", + "title": "" + }, + "user-profile": { + "delete-button": "", + "disable-button": "", + "edit-button": "", + "enable-button": "", + "title": "" + }, + "user-sessions": { + "browser-column": "", + "force-logout-all-button": "", + "force-logout-button": "", + "ip-column": "", + "last-seen-column": "", + "logged-on-column": "", + "title": "" + }, + "users-create": { + "create-button": "" + }, + "users-list": { + "create-button": "" + }, + "users-table": { + "last-seen-never": "", + "no-licensed-roles": "" + } + }, + "alert-labels": { + "button": { + "hide": "", + "show": { + "tooltip": "" + } + } + }, + "alerting": { + "alert": { + "alert-state": "", + "annotations": "", + "evaluation": "", + "evaluation-paused": "", + "evaluation-paused-description": "", + "last-evaluated": "", + "last-evaluation-duration": "", + "last-updated-at": "", + "last-updated-by": "", + "no-annotations": "", + "pending-period": "", + "rule": "", + "rule-identifier": "", + "rule-type": "", + "state-error-timeout": "", + "state-no-data": "", + "target-datasource-uid": "" + }, + "alert-recording-rule-form": { + "evaluation-behaviour": { + "description": { + "text": "" + } + } + }, + "alert-rules": { + "firing-for": "", + "next-evaluation": "", + "next-evaluation-in": "", + "rule-definition": "" + }, + "alertform": { + "labels": { + "alerting": "", + "recording": "" + } + }, + "alertVersionHistory": { + "alerting": "", + "alerting-change-description": "", + "annotations": "", + "compare": "", + "compare-with-latest": "", + "compareVersions": "", + "comparing-versions": "", + "condition": "", + "contactPointRouting": "", + "description": "", + "errorloading": "", + "execErrorState": "", + "intervalSeconds": "", + "labels": "", + "latest": "", + "name": "", + "namespace_uid": "", + "noDataState": "", + "noVersionsFound": "", + "paused": "", + "pendingPeriod": "", + "provisioning": "", + "provisioning-change-description": "", + "queryAndAlertCondition": "", + "restore": "", + "restore-manually": "", + "restore-modal": { + "body": "", + "confirm": "", + "error": "", + "summary": "", + "title": "" + }, + "restore-version": "", + "rule_group": "", + "unknown": "", + "unknown-change-description": "", + "user-id": "", + "warning-restore-manually": "", + "warning-restore-manually-title": "" + }, + "annotations": { + "description": "", + "title": "" + }, + "central-alert-history": { + "details": { + "error": "", + "header": { + "alert-rule": "", + "instance": "", + "state": "", + "timestamp": "" + }, + "loading": "", + "no-recognized-state": "", + "no-values": "", + "not-found": "", + "number-transitions": "", + "state": { + "alerting": "", + "error": "", + "no-data": "", + "normal": "", + "pending": "" + }, + "state-transitions": "", + "unknown-event-state": "", + "unknown-rule": "", + "value-in-transition": "" + }, + "error": "", + "filter": { + "clear": "", + "info": { + "label1": "", + "label2": "", + "label3": "", + "label4": "" + } + }, + "filterBy": "", + "too-many-events": { + "text": "", + "title": "" + } + }, + "common": { + "cancel": "", + "clear-filters": "", + "delete": "", + "edit": "", + "export": "", + "export-all": "", + "loading": "", + "search-by-matchers": "", + "titles": { + "notification-templates": "" + }, + "view": "" + }, + "contact-points": { + "create": "", + "custom-template-value": "", + "delete-reasons": { + "heading": "", + "no-permissions": "", + "policies": "", + "provisioned": "", + "rules": "" + }, + "delivered-to": "", + "delivery-duration": "", + "empty-state": { + "title": "" + }, + "key-value-map": { + "add": "", + "confirm-add": "" + }, + "last-delivery-attempt": "", + "last-delivery-failed": "", + "no-contact-points-found": "", + "no-delivery-attempts": "", + "no-integrations": "", + "only-firing": "", + "receiver-summary": { + "jira": "" + }, + "telegram": { + "parse-mode-warning-body": "", + "parse-mode-warning-title": "" + }, + "used-by_other": "", + "used-by-rules_other": "" + }, + "contactPointFilter": { + "label": "" + }, + "copy-to-clipboard": "", + "dag": { + "missing-reference": "", + "self-reference": "" + }, + "export": { + "subtitle": { + "formats": "", + "one-format": "" + } + }, + "folderAndGroup": { + "evaluation": { + "modal": { + "text": { + "alerting": "", + "recording": "" + } + } + } + }, + "group-actions": { + "actions-trigger": "", + "delete": "", + "edit": "", + "export": "", + "reorder": "" + }, + "list-view": { + "empty": { + "new-alert-rule": "", + "new-recording-rule": "", + "provisioning": "" + }, + "section": { + "dataSourceManaged": { + "title": "" + }, + "grafanaManaged": { + "export-new-rule": "", + "export-rules": "", + "loading": "", + "new-recording-rule": "", + "title": "" + } + } + }, + "manage-permissions": { + "button": "", + "title": "" + }, + "mute_timings": { + "error-loading": { + "description": "", + "title": "" + } + }, + "mute-timings": { + "add-mute-timing": "", + "description": "", + "save": "", + "saving": "" + }, + "notification-preview": { + "alertmanager": "", + "error": "", + "initialized": "", + "preview-routing": "", + "title": "", + "uninitialized": "" + }, + "notification-templates": { + "duplicate": { + "subTitle": "", + "title": "" + }, + "edit": { + "subTitle": "", + "title": "" + }, + "new": { + "subTitle": "", + "title": "" + } + }, + "policies": { + "default-policy": { + "description": "", + "title": "", + "update": "" + }, + "delete": { + "confirm": "", + "warning-1": "", + "warning-2": "" + }, + "filter-description": "", + "generated-policies": "", + "matchers": "", + "metadata": { + "active-time": "", + "delivered-to": "", + "grouped-by": "", + "grouping": { + "none": "", + "single-group": "" + }, + "inherited": "", + "mute-time": "", + "timingOptions": { + "groupInterval": { + "description": "", + "label": "" + }, + "groupWait": { + "description": "", + "label": "" + }, + "repeatInterval": { + "description": "", + "label": "" + } + }, + "n-instances_other": "" + }, + "new-child": "", + "new-policy": "", + "no-matchers": "", + "reload-policies": "", + "save-policy": "", + "update": { + "please-wait": "", + "update-policy": "", + "updating": "" + }, + "update-errors": { + "conflict": "", + "error-code": "", + "fallback": "", + "suffix": "", + "title": "" + }, + "n-more-policies_other": "" + }, + "provisioning": { + "badge-tooltip-provenance": "", + "badge-tooltip-standard": "" + }, + "queryAndExpressionsStep": { + "disableAdvancedOptions": { + "text": "" + }, + "preview": "", + "previewCondition": "" + }, + "recording-rules": { + "description-target-data-source": "", + "label-target-data-source": "" + }, + "rule-form": { + "evaluation": { + "evaluation-group-and-interval": "", + "group": { + "cancel": "", + "create": "", + "interval": "" + }, + "group-name": "", + "group-text": "", + "new-group": "", + "pause": { + "alerting": "", + "recording": "" + }, + "select-folder-before": "" + }, + "evaluation-behaviour": { + "description": { + "text": "" + }, + "info-help": { + "text": "" + }, + "pending-period": "" + }, + "evaluation-behaviour-description1": "", + "evaluation-behaviour-description2": "", + "evaluation-behaviour-description3": "", + "evaluation-behaviour-for": { + "error-parsing": "", + "validation": "" + }, + "folder": { + "cancel": "", + "create": "", + "create-folder": "", + "creating-new-folder": "", + "label": "", + "name": "", + "new-folder": "", + "new-folder-or": "" + }, + "folder-and-labels": "", + "folders": { + "help-info": "" + }, + "labels": { + "help-info": "" + }, + "pause": { + "label": "" + }, + "threshold": { + "recovery": { + "stop-alerting-above": "", + "stop-alerting-bellow": "", + "stop-alerting-equal": "", + "stop-alerting-inside-range": "", + "stop-alerting-less": "", + "stop-alerting-more": "", + "stop-alerting-not-equal": "", + "stop-alerting-outside-range": "", + "title": "" + } + } + }, + "rule-groups": { + "delete": { + "success": "" + }, + "move": { + "success": "" + }, + "rename": { + "success": "" + }, + "update": { + "success": "" + } + }, + "rule-list": { + "configure-datasource": "", + "ds-error-boundary": { + "description": "", + "title": "" + }, + "filter-view": { + "no-more-results": "", + "no-rules-found": "" + }, + "new-alert-rule": "", + "pagination": { + "next-page": "", + "previous-page": "" + }, + "return-button": { + "title": "" + }, + "rulerrule-loading-error": "" + }, + "rule-state": { + "creating": "", + "deleting": "", + "paused": "", + "recording-rule": "" + }, + "rule-view": { + "query": { + "datasources-na": { + "description": "", + "title": "" + } + } + }, + "rule-viewer": { + "error-loading": "", + "prometheus-consistency-check": { + "alert-message": "", + "alert-title": "" + } + }, + "rules": { + "add-rule": { + "success": "" + }, + "delete-rule": { + "success": "" + }, + "pause-rule": { + "success": "" + }, + "resume-rule": { + "success": "" + }, + "update-rule": { + "success": "" + } + }, + "search": { + "property": { + "data-source": "", + "evaluation-group": "", + "labels": "", + "namespace": "", + "rule-health": "", + "rule-name": "", + "rule-type": "", + "state": "" + }, + "save-query": "" + }, + "silences": { + "affected-instances": "", + "only-firing-instances": "", + "preview-affected-instances": "" + }, + "simpleCondition": { + "alertCondition": "" + }, + "templates": { + "editor": { + "add-example": "", + "auto-complete": "", + "goto-docs": "" + }, + "help": { + "intro": "" + }, + "misconfigured-badge-text": "", + "misconfigured-warning": "", + "misconfigured-warning-details": "" + }, + "threshold": { + "to": "" + } + }, + "annotations": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + } + }, + "api-keys": { + "empty-state": { + "message": "" + } + }, + "app-chrome": { + "skip-content-button": "", + "top-bar": { + "sign-in": "" + } + }, + "app-notification": { + "item": { + "trace-id": "" + } + }, + "bookmarks-page": { + "empty": { + "message": "", + "tip": "" + } + }, + "bouncing-loader": { + "label": "" + }, + "browse-dashboards": { + "action": { + "cancel-button": "", + "cannot-move-folders": "", + "confirmation-text": "", + "delete-button": "", + "delete-modal-invalid-text": "", + "delete-modal-invalid-title": "", + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "delete-modal-title": "", + "deleting": "", + "manage-permissions-button": "", + "move-button": "", + "move-modal-alert": "", + "move-modal-field-label": "", + "move-modal-text": "", + "move-modal-title": "", + "moving": "", + "new-folder-name-required-phrase": "" + }, + "actions": { + "button-to-recently-deleted": "" + }, + "counts": { + "alertRule_other": "", + "dashboard_other": "", + "folder_other": "", + "libraryPanel_other": "", + "total_other": "" + }, + "dashboards-tree": { + "collapse-folder-button": "", + "expand-folder-button": "", + "name-column": "", + "select-all-header-checkbox": "", + "select-checkbox": "", + "tags-column": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "", + "title-folder": "" + }, + "folder-actions-button": { + "delete": "", + "folder-actions": "", + "manage-permissions": "", + "move": "" + }, + "folder-picker": { + "accessible-label": "", + "button-label": "", + "clear-selection": "", + "empty-message": "", + "error-title": "", + "non-folder-item": "", + "search-placeholder": "", + "unknown-error": "" + }, + "hard-delete": { + "success": "" + }, + "manage-folder-nav": { + "alert-rules": "", + "dashboards": "", + "panels": "" + }, + "new-folder-form": { + "cancel-label": "", + "create-label": "", + "name-label": "" + }, + "no-results": { + "clear": "", + "text": "" + }, + "soft-delete": { + "success": "" + } + }, + "clipboard-button": { + "inline-toast": { + "success": "" + } + }, + "combobox": { + "async": { + "error": "" + }, + "clear": { + "title": "" + }, + "custom-value": { + "description": "" + }, + "group": { + "undefined": "" + }, + "options": { + "no-found": "" + } + }, + "command-palette": { + "action": { + "change-theme": "", + "dark-theme": "", + "light-theme": "" + }, + "empty-state": { + "message": "" + }, + "search-box": { + "placeholder": "" + }, + "section": { + "actions": "", + "dashboard-search-results": "", + "folder-search-results": "", + "pages": "", + "preferences": "", + "recent-dashboards": "" + } + }, + "common": { + "apply": "", + "cancel": "", + "clear": "", + "close": "", + "collapse": "", + "edit": "", + "help": "", + "loading": "", + "locale": { + "default": "" + }, + "save": "", + "search": "", + "view": "" + }, + "configuration-tracker": { + "config-card": { + "complete": "" + } + }, + "connections": { + "connect-data": { + "category-header-label": "", + "empty-message": "", + "request-data-source": "", + "roadmap": "" + }, + "search": { + "placeholder": "" + } + }, + "core": { + "versionHistory": { + "comparison": { + "header": { + "hide-json-diff": "", + "show-json-diff": "", + "text": "" + }, + "select": "" + }, + "no-properties-changed": "", + "table": { + "updated": "", + "updatedBy": "", + "version": "" + }, + "view-json-diff": "" + } + }, + "correlations": { + "add-new": "", + "alert": { + "error-message": "", + "title": "" + }, + "basic-info-form": { + "description-description": "", + "description-label": "", + "label-description": "", + "label-label": "", + "label-placeholder": "", + "label-required": "", + "sub-text": "", + "title": "" + }, + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + }, + "list": { + "delete": "", + "label": "", + "loading": "", + "read-only": "", + "source": "", + "target": "" + }, + "navigation-form": { + "add-button": "", + "back-button": "", + "next-button": "", + "save-button": "" + }, + "page-content": "", + "page-heading": "", + "query-editor": { + "control-rules": "", + "data-source-text": "", + "data-source-title": "", + "error-text": "", + "error-title": "", + "loading": "", + "query-description": "", + "query-editor-title": "", + "query-label": "" + }, + "source-form": { + "control-required": "", + "description": "", + "description-external-pre": "", + "description-query-pre": "", + "external-title": "", + "heading-external": "", + "heading-query": "", + "query-title": "", + "results-description": "", + "results-label": "", + "results-required": "", + "source-description": "", + "source-label": "", + "sub-text": "" + }, + "sub-title": "", + "target-form": { + "control-rules": "", + "sub-text": "", + "target-description-external": "", + "target-description-query": "", + "target-label": "", + "target-type-description": "", + "title": "", + "type-label": "" + }, + "trans-details": { + "logfmt-description": "", + "logfmt-label": "", + "regex-description": "", + "regex-expression": "", + "regex-label": "", + "regex-map-values": "" + }, + "transform": { + "add-button": "", + "heading": "", + "no-transform": "" + }, + "transform-row": { + "expression-label": "", + "expression-required": "", + "expression-tooltip": "", + "field-input": "", + "field-label": "", + "field-tooltip": "", + "map-value-label": "", + "map-value-tooltip": "", + "remove-button": "", + "remove-tooltip": "", + "transform-required": "", + "type-label": "", + "type-tooltip": "" + } + }, + "dashboard": { + "add-menu": { + "import": "", + "paste-panel": "", + "row": "", + "visualization": "" + }, + "alert-rules-drawer": { + "redirect-link": "", + "subtitle": "" + }, + "default-layout": { + "description": "", + "item-options": { + "repeat": { + "direction": { + "horizontal": "", + "title": "", + "vertical": "" + }, + "max": "", + "title": "", + "variable": { + "description": "", + "title": "" + } + } + }, + "name": "", + "row-actions": { + "delete": "", + "modal": { + "alt-action": "", + "text": "", + "title": "" + } + }, + "row-options": { + "button": { + "label": "" + }, + "form": { + "cancel": "", + "repeat-for": { + "label": "", + "learn-more": "", + "warning": { + "text": "" + } + }, + "title": "", + "update": "" + }, + "modal": { + "title": "" + }, + "repeat": { + "title": "", + "variable": { + "title": "" + } + }, + "title": "" + } + }, + "edit-pane": { + "elements": { + "dashboard": "", + "objects": "", + "panel": "", + "panels": "", + "row": "", + "rows": "", + "tab": "", + "tabs": "" + }, + "open": "", + "row": { + "header": { + "hide": "", + "title": "" + } + } + }, + "editpane": { + "add": "", + "configure": "", + "outline": "" + }, + "empty": { + "add-library-panel-body": "", + "add-library-panel-button": "", + "add-library-panel-header": "", + "add-visualization-body": "", + "add-visualization-button": "", + "add-visualization-header": "", + "import-a-dashboard-body": "", + "import-a-dashboard-header": "", + "import-dashboard-button": "" + }, + "errors": { + "failed-to-load": "" + }, + "inspect": { + "data-tab": "", + "error-tab": "", + "json-tab": "", + "meta-tab": "", + "query-tab": "", + "stats-tab": "", + "subtitle": "", + "title": "" + }, + "inspect-data": { + "data-options": "", + "dataframe-aria-label": "", + "dataframe-label": "", + "download-csv": "", + "download-excel-description": "", + "download-excel-label": "", + "download-logs": "", + "download-service": "", + "download-traces": "", + "excel-header": "", + "formatted": "", + "formatted-data-description": "", + "formatted-data-label": "", + "panel-transforms": "", + "series-to-columns": "", + "transformation": "", + "transformations-description": "", + "transformations-label": "" + }, + "inspect-json": { + "dataframe-description": "", + "dataframe-label": "", + "panel-data-description": "", + "panel-data-label": "", + "panel-json-description": "", + "panel-json-label": "", + "select-source": "", + "unknown": "" + }, + "inspect-meta": { + "no-inspector": "" + }, + "inspect-stats": { + "data-title": "", + "data-traceids": "", + "processing-time": "", + "queries": "", + "request-time": "", + "rows": "", + "table-title": "" + }, + "layout": { + "common": { + "copy": "", + "copy-or-duplicate": "", + "delete": "", + "duplicate": "", + "layout": "" + } + }, + "options": { + "description": "", + "title-option": "" + }, + "outline": { + "tree": { + "item": { + "collapse": "", + "empty": "", + "expand": "" + } + } + }, + "panel-edit": { + "alerting-tab": { + "dashboard-not-saved": "", + "no-rules": "" + } + }, + "responsive-layout": { + "description": "", + "item-options": { + "hide-no-data": "", + "repeat": { + "variable": { + "description": "", + "title": "" + } + }, + "title": "" + }, + "name": "", + "options": { + "columns": "", + "fixed": "", + "min": "", + "one-column": "", + "rows": "", + "three-columns": "", + "two-columns": "" + } + }, + "rows-layout": { + "description": "", + "name": "", + "option": { + "height": "", + "hide-header": "", + "repeat": "", + "title": "" + }, + "options": { + "height-expand": "", + "height-min": "" + }, + "row": { + "collapse": "", + "expand": "", + "menu": { + "add": "", + "add-panel": "", + "add-row-above": "", + "add-row-below": "", + "move-down": "", + "move-row": "", + "move-up": "" + }, + "new": "", + "repeat": { + "learn-more": "", + "warning": "" + } + }, + "row-options": { + "title-option": "" + } + }, + "tabs-layout": { + "description": "", + "menu": { + "move-tab": "" + }, + "name": "", + "tab": { + "menu": { + "add": "", + "add-panel": "", + "add-tab-above": "", + "add-tab-after": "", + "add-tab-before": "", + "move-left": "", + "move-right": "" + }, + "new": "" + }, + "tab-options": { + "title-option": "" + } + }, + "toolbar": { + "add": "", + "add-panel": "", + "add-panel-description": "", + "add-panel-lib": "", + "add-row": "", + "add-tab": "", + "alert-rules": "", + "back-to-dashboard": "", + "dashboard-settings": { + "label": "", + "tooltip": "" + }, + "discard-library-panel-changes": "", + "discard-panel": "", + "discard-panel-new": "", + "edit": { + "label": "", + "tooltip": "" + }, + "edit-dashboard-v2-schema": "", + "enter-edit-mode": { + "label": "", + "tooltip": "" + }, + "exit-edit-mode": { + "label": "", + "tooltip": "" + }, + "libray-panel-description": "", + "mark-favorite": "", + "more-save-options": "", + "open-original": "", + "playlist-next": "", + "playlist-previous": "", + "playlist-stop": "", + "public-dashboard": "", + "refresh": "", + "row-description": "", + "save": "", + "save-dashboard": { + "label": "", + "tooltip": "" + }, + "save-dashboard-copy": { + "label": "", + "tooltip": "" + }, + "save-dashboard-short": "", + "save-library-panel": "", + "settings": "", + "share": { + "label": "", + "tooltip": "" + }, + "share-button": "", + "show-hidden-elements": "", + "switch-old-dashboard": "", + "tabs-description": "", + "unlink-library-panel": "", + "unmark-favorite": "" + }, + "validation": { + "invalid-dashboard-id": "", + "invalid-json": "", + "tags-expected-array": "", + "tags-expected-strings": "" + }, + "viz-panel": { + "options": { + "description": "", + "open-edit": "", + "plugin-type-image": "", + "title-option": "", + "transparent-background": "" + } + } + }, + "dashboard-import": { + "file-dropzone": { + "primary-text": "", + "secondary-text": "" + }, + "form-actions": { + "cancel": "", + "load": "" + }, + "gcom-field": { + "label": "", + "load-button": "", + "placeholder": "", + "validation-required": "" + }, + "json-field": { + "label": "", + "validation-required": "" + } + }, + "dashboard-links": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "title": "" + } + }, + "dashboard-settings": { + "annotations": { + "title": "" + }, + "dashboard-delete-button": "", + "delete-modal": { + "confirmation-text": "", + "delete-button": "", + "title": "" + }, + "delete-modal-restore-dashboards-text": "", + "delete-modal-text": "", + "general": { + "auto-refresh-description": "", + "auto-refresh-label": "", + "description-label": "", + "editable-description": "", + "editable-label": "", + "folder-label": "", + "panel-options-graph-tooltip-description": "", + "panel-options-graph-tooltip-label": "", + "panel-options-label": "", + "panels-preload-description": "", + "panels-preload-label": "", + "tags-label": "", + "title": "", + "title-label": "" + }, + "json-editor": { + "save-button": "", + "subtitle": "", + "title": "" + }, + "links": { + "title": "" + }, + "permissions": { + "title": "" + }, + "provisioned-delete-modal": { + "confirm-button": "", + "text-1": "", + "text-2": "", + "text-3": "", + "text-link": "", + "title": "" + }, + "settings": { + "title": "" + }, + "time-picker": { + "hide-time-picker": "", + "now-delay-description": "", + "now-delay-label": "", + "refresh-live-dashboards-description": "", + "refresh-live-dashboards-label": "", + "time-options-label": "", + "time-zone-label": "", + "week-start-label": "" + }, + "time-regions": { + "advanced-description-cron": "", + "advanced-description-rest": "", + "advanced-description-use": "", + "advanced-label": "" + }, + "variables": { + "title": "" + }, + "versions": { + "title": "" + } + }, + "dashboards": { + "panel-edit": { + "angular-deprecation-button-open-panel-json": "", + "angular-deprecation-description": "", + "angular-deprecation-heading": "" + }, + "panel-queries": { + "add-query-from-library": "" + }, + "settings": { + "variables": { + "dependencies": { + "button": "", + "title": "" + } + } + } + }, + "data-source-list": { + "empty-state": { + "button-title": "", + "pro-tip": "", + "title": "" + } + }, + "data-source-picker": { + "add-new-data-source": "", + "built-in-list": { + "description-dashboard": "", + "description-grafana": "", + "description-mixed": "" + }, + "list": { + "no-data-source-message": "" + }, + "modal": { + "configure-new-data-source": "", + "input-placeholder": "", + "title": "" + }, + "open-advanced-button": "" + }, + "data-source-testing-status-page": { + "error-more-details-link": "", + "success-more-details-links": "" + }, + "data-sources": { + "datasource-add-button": { + "label": "" + }, + "empty-state": { + "message": "" + } + }, + "embed": { + "share": { + "time-range-description": "", + "time-range-label": "" + } + }, + "empty-list-cta": { + "pro-tip": "" + }, + "entity-not-found": { + "description": "" + }, + "errors": { + "dashboard-settings": { + "annotations": { + "datasource": "" + } + } + }, + "explore": { + "add-to-dashboard": "", + "drilldownInfo": { + "action": "", + "description": "", + "title": "" + }, + "logs": { + "logs-volume": { + "add-filters": "", + "decrease-timerange": "", + "much-data": "" + }, + "maximum-pinned-logs": "", + "no-logs-found": "", + "scan-for-older-logs": "", + "stop-scan": "" + }, + "rich-history": { + "close-tooltip": "", + "datasource-a-z": "", + "datasource-z-a": "", + "newest-first": "", + "oldest-first": "", + "query-history": "", + "query-library": "", + "settings": "", + "starred": "" + }, + "rich-history-card": { + "add-comment-form": "", + "add-comment-tooltip": "", + "add-to-library": "", + "cancel": "", + "confirm-delete": "", + "copy-query-tooltip": "", + "copy-shortened-link-tooltip": "", + "datasource-icon-label": "", + "datasource-name-label": "", + "datasource-not-exist": "", + "delete-query-confirmation-title": "", + "delete-query-title": "", + "delete-query-tooltip": "", + "delete-starred-query-confirmation-text": "", + "edit-comment-tooltip": "", + "optional-description": "", + "query-comment-label": "", + "query-text-label": "", + "save-comment": "", + "star-query-tooltip": "", + "unstar-query-tooltip": "", + "update-comment-form": "" + }, + "rich-history-container": { + "loading": "" + }, + "rich-history-notification": { + "query-copied": "", + "query-deleted": "" + }, + "rich-history-queries-tab": { + "displaying-partial-queries": "", + "displaying-queries": "", + "filter-aria-label": "", + "filter-history": "", + "filter-placeholder": "", + "history-local": "", + "loading": "", + "loading-results": "", + "search-placeholder": "", + "showing-queries": "", + "sort-aria-label": "", + "sort-placeholder": "" + }, + "rich-history-settings-tab": { + "alert-info": "", + "change-default-tab": "", + "clear-history-info": "", + "clear-query-history": "", + "clear-query-history-button": "", + "delete-confirm": "", + "delete-confirm-text": "", + "delete-title": "", + "history-time-span": "", + "history-time-span-description": "", + "only-show-active-datasource": "", + "query-history-deleted": "", + "retention-period": { + "1-week": "", + "2-days": "", + "2-weeks": "", + "5-days": "" + } + }, + "rich-history-starred-tab": { + "filter-queries-aria-label": "", + "filter-queries-placeholder": "", + "loading": "", + "loading-results": "", + "local-history-message": "", + "search-queries-placeholder": "", + "showing-queries": "", + "sort-queries-aria-label": "", + "sort-queries-placeholder": "" + }, + "rich-history-utils": { + "a-week-ago": "", + "days-ago": "", + "default-from": "", + "default-to": "", + "today": "", + "two-weeks-ago": "", + "yesterday": "" + }, + "rich-history-utils-notification": { + "saving-failed": "", + "update-failed": "" + }, + "run-query": { + "left-pane": "", + "right-pane": "", + "run-query-button": "", + "switch-datasource-button": "" + }, + "secondary-actions": { + "add-from-query-library": "", + "query-add-button": "", + "query-add-button-aria-label": "", + "query-history-button": "", + "query-history-button-aria-label": "", + "query-inspector-button": "", + "query-inspector-button-aria-label": "" + }, + "table": { + "no-data": "", + "title": "", + "title-with-name": "" + }, + "toolbar": { + "add-to-extensions": "", + "add-to-queryless-extensions": "", + "aria-label": "", + "copy-link": "", + "copy-link-abs-time": "", + "copy-links-absolute-category": "", + "copy-links-normal-category": "", + "copy-shortened-link": "", + "copy-shortened-link-abs-time": "", + "copy-shortened-link-label": "", + "copy-shortened-link-menu": "", + "refresh-picker-cancel": "", + "refresh-picker-run": "", + "split-close": "", + "split-close-tooltip": "", + "split-narrow": "", + "split-title": "", + "split-tooltip": "", + "split-widen": "" + } + }, + "explore-metrics": { + "breakdown": { + "clearFilter": "", + "labelSelect": "", + "missing-otel-labels": "", + "noMatchingValue": "", + "sortBy": "" + }, + "related-logs": { + "LrrDocsLink": "", + "openExploreLogs": "", + "relatedLogsUnavailable": "", + "warnExperimentalFeature": "" + }, + "viewBy": "" + }, + "export": { + "json": { + "cancel-button": "", + "copy-button": "", + "download-button": "", + "download-successful_toast_message": "", + "export-externally-label": "", + "info-text": "", + "title": "" + }, + "menu": { + "export-as-json-label": "", + "export-as-json-tooltip": "" + } + }, + "folder-filter": { + "clear-folder-button": "" + }, + "folder-picker": { + "create-instructions": "", + "loading": "" + }, + "forgot-password": { + "back-button": "", + "change-password": { + "skip-button": "", + "submit-button": "" + }, + "contact-admin": "", + "email-sent": "", + "reset-password-header": "", + "send-email-button": "" + }, + "form-prompt": { + "continue-button": "", + "description": "", + "discard-button": "" + }, + "gen-ai": { + "apply-suggestion": "", + "incomplete-request-error": "", + "send-custom-feedback": "" + }, + "get-enterprise": { + "requires-license": "", + "title": "" + }, + "grafana-ui": { + "action-editor": { + "button": { + "confirm": "", + "confirm-action": "" + }, + "inline": { + "add-action": "", + "edit-action": "" + }, + "modal": { + "action-body": "", + "action-method": "", + "action-query-params": "", + "action-title": "", + "action-title-placeholder": "", + "one-click-description": "" + } + }, + "alert": { + "close-button": "" + }, + "auto-save-field": { + "saved": "", + "saving": "" + }, + "card": { + "option": "" + }, + "cascader": { + "clear-button": "" + }, + "color-picker-popover": { + "palette-tab": "", + "spectrum-tab": "" + }, + "confirm-button": { + "cancel": "" + }, + "confirm-content": { + "placeholder": "" + }, + "data-link-editor": { + "info": "", + "new-tab-label": "", + "title-label": "", + "title-placeholder": "", + "url-label": "" + }, + "data-link-editor-modal": { + "cancel": "", + "one-click-description": "", + "save": "" + }, + "data-link-inline-editor": { + "one-click": "" + }, + "data-links-inline-editor": { + "add-link": "", + "edit-link": "", + "one-click": "", + "one-click-enabled": "", + "title-not-provided": "", + "tooltip-edit": "", + "tooltip-remove": "", + "url-not-provided": "" + }, + "data-source-basic-auth-settings": { + "user-label": "", + "user-placeholder": "" + }, + "data-source-http-proxy-settings": { + "oauth-identity-label": "", + "oauth-identity-tooltip": "", + "skip-tls-verify-label": "", + "ts-client-auth-label": "", + "with-ca-cert-label": "", + "with-ca-cert-tooltip": "" + }, + "data-source-http-settings": { + "access-help": "", + "access-help-details": "", + "access-label": "", + "access-options-browser": "", + "access-options-proxy": "", + "allowed-cookies": "", + "allowed-cookies-tooltip": "", + "auth": "", + "azure-auth-label": "", + "azure-auth-tooltip": "", + "basic-auth": "", + "basic-auth-label": "", + "browser-mode-description": "", + "browser-mode-title": "", + "default-url-access-select": "", + "default-url-tooltip": "", + "direct-url-tooltip": "", + "heading": "", + "proxy-url-tooltip": "", + "server-mode-description": "", + "server-mode-title": "", + "timeout-form-label": "", + "timeout-label": "", + "timeout-tooltip": "", + "url-label": "", + "with-credential-label": "", + "with-credential-tooltip": "" + }, + "data-source-settings": { + "alerting-settings-heading": "", + "alerting-settings-label": "", + "alerting-settings-tooltip": "", + "cert-key-reset": "", + "custom-headers-add": "", + "custom-headers-header": "", + "custom-headers-header-placeholder": "", + "custom-headers-header-remove": "", + "custom-headers-header-value": "", + "custom-headers-title": "", + "secure-socks-heading": "", + "secure-socks-label": "", + "secure-socks-tooltip": "", + "tls-certification-label": "", + "tls-certification-placeholder": "", + "tls-client-certification-label": "", + "tls-client-key-label": "", + "tls-client-key-placeholder": "", + "tls-heading": "", + "tls-server-name-label": "", + "tls-tooltip": "" + }, + "date-time-picker": { + "apply": "", + "calendar-icon-label": "", + "cancel": "", + "next-label": "", + "previous-label": "", + "select-placeholder": "" + }, + "drawer": { + "close": "" + }, + "feature-badge": { + "experimental": "", + "new": "", + "preview": "", + "private-preview": "" + }, + "field-link-list": { + "external-links-heading": "" + }, + "file-dropzone": { + "cancel-upload": "", + "file-too-large": "" + }, + "filter-input": { + "clear": "" + }, + "modal": { + "close-tooltip": "" + }, + "named-colors-palette": { + "text-color-swatch": "", + "transparent-swatch": "" + }, + "page-toolbar": { + "go-back": "", + "search-dashboard-name": "", + "search-links": "", + "search-parent-folder": "" + }, + "pagination": { + "next-page": "", + "previous-page": "" + }, + "secret-form-field": { + "reset": "" + }, + "segment-async": { + "error": "", + "loading": "", + "no-options": "" + }, + "select": { + "default-create-label": "", + "no-options-label": "", + "placeholder": "" + }, + "series-color-picker-popover": { + "y-axis-usage": "" + }, + "spinner": { + "aria-label": "" + }, + "table": { + "copy": "", + "csv-counts": "", + "filter-popup-apply": "", + "filter-popup-cancel": "", + "filter-popup-clear": "", + "filter-popup-heading": "", + "no-values-label": "", + "pagination-summary": "" + }, + "tags-input": { + "add": "" + }, + "user-icon": { + "active-text": "" + }, + "value-pill": { + "remove-button": "" + }, + "viz-legend": { + "right-axis-indicator": "" + }, + "viz-tooltip": { + "actions-confirmation-input-placeholder": "", + "actions-confirmation-label": "", + "actions-confirmation-message": "", + "footer-add-annotation": "", + "footer-click-to-action": "", + "footer-click-to-navigate": "" + } + }, + "graph": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "", + "title": "" + } + }, + "help-modal": { + "column-headers": { + "description": "", + "keys": "" + }, + "shortcuts-category": { + "dashboard": "", + "focused-panel": "", + "global": "", + "time-range": "" + }, + "shortcuts-description": { + "change-theme": "", + "collapse-all-rows": "", + "copy-time-range": "", + "dashboard-settings": "", + "duplicate-panel": "", + "exit-edit/setting-views": "", + "expand-all-rows": "", + "go-to-dashboards": "", + "go-to-explore": "", + "go-to-home-dashboard": "", + "go-to-profile": "", + "make-time-range-permanent": "", + "move-time-range-back": "", + "move-time-range-forward": "", + "open-search": "", + "open-shared-modal": "", + "paste-time-range": "", + "refresh-all-panels": "", + "remove-panel": "", + "save-dashboard": "", + "show-all-shortcuts": "", + "toggle-active-mode": "", + "toggle-all-panel-legends": "", + "toggle-auto-fit": "", + "toggle-exemplars": "", + "toggle-graph-crosshair": "", + "toggle-kiosk": "", + "toggle-panel-edit": "", + "toggle-panel-fullscreen": "", + "toggle-panel-legend": "", + "zoom-out-time-range": "" + }, + "title": "" + }, + "help-wizard": { + "download-snapshot": "", + "github-comment": "", + "support-bundle": "", + "troubleshooting-help": "" + }, + "inspector": { + "query": { + "collapse-all": "", + "copy-to-clipboard": "", + "description": "", + "expand-all": "", + "no-data": "", + "refresh": "" + } + }, + "ldap-drawer": { + "attributes-section": { + "description": "", + "email-label": "", + "label": "", + "member-of-label": "", + "name-label": "", + "surname-label": "", + "username-label": "" + }, + "extra-security-section": { + "client-cert-label": "", + "client-cert-placeholder": "", + "client-cert-value-label": "", + "client-cert-value-placeholder": "", + "client-key-label": "", + "client-key-placeholder": "", + "client-key-value-label": "", + "client-key-value-placeholder": "", + "encryption-provider-base-64": "", + "encryption-provider-description": "", + "encryption-provider-file-path": "", + "encryption-provider-label": "", + "label": "", + "min-tls-version-description": "", + "min-tls-version-label": "", + "root-ca-cert-label": "", + "root-ca-cert-placeholder": "", + "root-ca-cert-value-label": "", + "root-ca-cert-value-placeholder": "", + "start-tls-description": "", + "start-tls-label": "", + "tls-ciphers-label": "", + "tls-ciphers-placeholder": "", + "use-ssl-description": "", + "use-ssl-label": "", + "use-ssl-tooltip": "" + }, + "group-mapping": { + "grafana-admin": { + "description": "", + "label": "" + }, + "group-dn": { + "description": "", + "label": "" + }, + "org-id": { + "description": "", + "label": "" + }, + "org-role": { + "label": "" + }, + "remove": { + "button": "" + } + }, + "group-mapping-section": { + "add": { + "button": "" + }, + "description": "", + "group-search-base-dns-label": "", + "group-search-base-dns-placeholder": "", + "group-search-filter-description": "", + "group-search-filter-label": "", + "group-search-filter-user-attribute-description": "", + "group-search-filter-user-attribute-label": "", + "label": "", + "skip-org-role-sync-description": "", + "skip-org-role-sync-label": "" + }, + "misc-section": { + "allow-sign-up-descrition": "", + "allow-sign-up-label": "", + "label": "", + "port-description": "", + "port-label": "", + "timeout-description": "", + "timeout-label": "" + }, + "title": "" + }, + "ldap-settings-page": { + "advanced-settings-section": { + "edit-button": "", + "subtitle": "", + "title": "" + }, + "alert": { + "discard-success": "", + "error-fetching": "", + "error-saving": "", + "error-validate-form": "", + "feature-flag-disabled": "", + "saved": "" + }, + "bind-dn": { + "description": "", + "label": "", + "placeholder": "" + }, + "bind-password": { + "label": "" + }, + "buttons-section": { + "disable-button": "", + "discard-button": "", + "save-and-enable-button": "", + "save-button": "" + }, + "documentation": "", + "host": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "login-form-alert": { + "description": "", + "title": "" + }, + "search_filter": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "search-base-dns": { + "description": "", + "error": "", + "label": "", + "placeholder": "" + }, + "subtitle": "", + "title": "" + }, + "library-panel": { + "add-modal": { + "cancel": "", + "create": "", + "error": "", + "folder": "", + "folder-description": "", + "name": "" + }, + "add-widget": { + "title": "" + }, + "empty-state": { + "message": "", + "more-info": "" + } + }, + "library-panels": { + "empty-state": { + "message": "" + }, + "loading-panel-text": "", + "modal": { + "button-cancel": "", + "button-view-panel1": "", + "button-view-panel2": "", + "panel-not-linked": "", + "select-no-options-message": "", + "select-placeholder": "", + "title": "", + "body_other": "" + }, + "save": { + "error": "", + "success": "" + } + }, + "link": { + "share": { + "config-alert-description": "", + "config-alert-title": "", + "config-description": "", + "copy-link-button": "", + "copy-to-clipboard": "", + "short-url-label": "", + "time-range-description": "", + "time-range-label": "" + }, + "share-panel": { + "config-description": "", + "download-image": "", + "render-image": "", + "render-image-error": "", + "render-image-error-description": "" + } + }, + "lock-icon": "", + "login": { + "divider": { + "connecting-text": "" + }, + "error": { + "blocked": "", + "invalid-user-or-password": "", + "title": "", + "unknown": "" + }, + "forgot-password": "", + "form": { + "confirmation-code": "", + "confirmation-code-label": "", + "confirmation-code-placeholder": "", + "email-label": "", + "email-placeholder": "", + "email-required": "", + "name-label": "", + "name-placeholder": "", + "password-label": "", + "password-placeholder": "", + "password-required": "", + "submit-label": "", + "submit-loading-label": "", + "username-label": "", + "username-placeholder": "", + "username-required": "", + "verify-email-label": "", + "verify-email-loading-label": "" + }, + "layout": { + "update-password": "" + }, + "services": { + "sing-in-with-prefix": "" + }, + "signup": { + "button-label": "", + "new-to-question": "" + } + }, + "logs": { + "infinite-scroll": { + "end-of-range": "", + "load-more": "", + "load-newer": "", + "load-older": "", + "older-logs": "" + }, + "log-details": { + "fields": "", + "links": "", + "log-line": "", + "no-details": "" + }, + "log-line-menu": { + "copy-link": "", + "copy-log": "", + "icon-label": "", + "pin-to-outline": "", + "show-context": "", + "unpin-from-outline": "" + }, + "log-row-message": { + "ellipsis": "", + "more": "", + "see-details": "" + }, + "log-rows": { + "disable-popover": { + "confirm": "", + "message": "", + "title": "" + }, + "disable-popover-message": { + "shortcut": "" + } + }, + "logs-navigation": { + "newer-logs": "", + "older-logs": "", + "scroll-bottom": "", + "scroll-top": "", + "start-of-range": "" + }, + "popover-menu": { + "copy": "", + "disable-menu": "", + "line-contains": "", + "line-contains-not": "" + } + }, + "migrate-to-cloud": { + "build-snapshot": { + "description": "", + "title": "", + "when-complete": "" + }, + "building-snapshot": { + "description": "", + "description-eta": "", + "title": "" + }, + "can-i-move": { + "body": "", + "link-title": "", + "title": "" + }, + "connect-modal": { + "body-cloud-stack": "", + "body-get-started": "", + "body-sign-up": "", + "body-token": "", + "body-token-field": "", + "body-token-field-placeholder": "", + "body-token-instructions": "", + "body-view-stacks": "", + "cancel": "", + "connect": "", + "connecting": "", + "title": "", + "token-error-title": "", + "token-errors": { + "instance-request-error": "", + "instance-unreachable": "", + "migration-disabled": "", + "session-creation-failure": "", + "token-invalid": "", + "token-not-saved": "", + "token-request-error": "", + "token-validation-failure": "" + }, + "token-required-error": "" + }, + "cta": { + "button": "", + "header": "" + }, + "delete-migration-token-confirm": { + "body": "", + "confirm-button": "", + "error-title": "", + "title": "" + }, + "disconnect-modal": { + "body": "", + "cancel": "", + "disconnect": "", + "disconnecting": "", + "error": "", + "title": "" + }, + "get-started": { + "body": "", + "configure-pdc-link": "", + "link-title": "", + "step-1": "", + "step-2": "", + "step-3": "", + "step-4": "", + "step-5": "", + "title": "" + }, + "is-it-secure": { + "body": "", + "link-title": "", + "title": "" + }, + "migrate-to-this-stack": { + "body": "", + "link-title": "", + "title": "" + }, + "migrated-counts": { + "alert_rule_groups": "", + "alert_rules": "", + "contact_points": "", + "dashboards": "", + "datasources": "", + "folders": "", + "library_elements": "", + "mute_timings": "", + "notification_policies": "", + "notification_templates": "", + "plugins": "" + }, + "migration-token": { + "delete-button": "", + "delete-modal-body": "", + "delete-modal-cancel": "", + "delete-modal-confirm": "", + "delete-modal-deleting": "", + "delete-modal-title": "", + "error-body": "", + "error-title": "", + "generate-button": "", + "generate-button-loading": "", + "modal-close": "", + "modal-copy-and-close": "", + "modal-copy-button": "", + "modal-field-description": "", + "modal-field-label": "", + "modal-title": "", + "status": "" + }, + "onprem": { + "cancel-snapshot-error-title": "", + "create-snapshot-error-title": "", + "disconnect-error-title": "", + "error-see-server-logs": "", + "get-session-error-title": "", + "get-snapshot-error-title": "", + "migration-finished-with-caveat-title": "", + "migration-finished-with-errors-body": "", + "migration-finished-with-warnings-body": "", + "snapshot-error-status-body": "", + "snapshot-error-status-title": "", + "success-message": "", + "success-message-generic": "", + "success-title": "", + "upload-snapshot-error-title": "" + }, + "pdc": { + "body": "", + "link-title": "", + "title": "" + }, + "pricing": { + "body": "", + "link-title": "", + "title": "" + }, + "public-preview": { + "button-text": "", + "message": "", + "message-cloud": "", + "title": "" + }, + "resource-details": { + "dismiss-button": "", + "error-messages": { + "dashboard-already-managed": "", + "datasource-already-managed": "", + "datasource-invalid-url": "", + "datasource-name-conflict": "", + "folder-name-conflict": "", + "generic-error": "", + "internal-service-error": "", + "library-element-name-conflict": "", + "resource-conflict": "", + "unexpected-error": "", + "unsupported-data-type": "" + }, + "error-title": "", + "generic-title": "", + "missing-message": "", + "resource-summary": "", + "title": "", + "warning-title": "" + }, + "resource-status": { + "error-details-button": "", + "failed": "", + "migrated": "", + "migrating": "", + "not-migrated": "", + "unknown": "", + "warning": "", + "warning-details-button": "" + }, + "resource-table": { + "dashboard-load-error": "", + "error-library-element-sub": "", + "error-library-element-title": "", + "unknown-datasource-title": "", + "unknown-datasource-type": "" + }, + "resource-type": { + "alert_rule": "", + "alert_rule_group": "", + "contact_point": "", + "dashboard": "", + "datasource": "", + "folder": "", + "library_element": "", + "mute_timing": "", + "notification_policy": "", + "notification_template": "", + "plugin": "", + "unknown": "" + }, + "summary": { + "cancel-snapshot": "", + "disconnect": "", + "errored-resource-count": "", + "page-loading": "", + "rebuild-snapshot": "", + "snapshot-date": "", + "snapshot-not-created": "", + "start-migration": "", + "successful-resource-count": "", + "target-stack-title": "", + "total-resource-count": "", + "upload-migration": "" + }, + "support-types-disclosure": { + "text": "" + }, + "token-status": { + "active": "", + "no-active": "", + "unknown": "", + "unknown-error": "" + }, + "what-is-cloud": { + "body": "", + "link-title": "", + "title": "" + }, + "why-host": { + "body": "", + "link-title": "", + "title": "" + } + }, + "multicombobox": { + "all": { + "title": "", + "title-filtered": "" + }, + "clear": { + "title": "" + } + }, + "nav": { + "add-new-connections": { + "title": "" + }, + "admin": { + "subtitle": "", + "title": "" + }, + "alert-list-legacy": { + "title": "" + }, + "alerting": { + "subtitle": "", + "title": "" + }, + "alerting-admin": { + "subtitle": "", + "title": "" + }, + "alerting-am-routes": { + "subtitle": "", + "title": "" + }, + "alerting-channels": { + "title": "" + }, + "alerting-groups": { + "subtitle": "", + "title": "" + }, + "alerting-home": { + "title": "" + }, + "alerting-legacy": { + "title": "" + }, + "alerting-list": { + "subtitle": "", + "title": "" + }, + "alerting-receivers": { + "subtitle": "", + "title": "" + }, + "alerting-silences": { + "subtitle": "", + "title": "" + }, + "alerting-upgrade": { + "subtitle": "", + "title": "" + }, + "alerts-and-incidents": { + "subtitle": "", + "title": "" + }, + "api-keys": { + "subtitle": "", + "title": "" + }, + "application": { + "title": "" + }, + "apps": { + "subtitle": "", + "title": "" + }, + "authentication": { + "title": "" + }, + "bookmarks": { + "title": "" + }, + "bookmarks-empty": { + "title": "" + }, + "collector": { + "title": "" + }, + "config": { + "title": "" + }, + "config-access": { + "subtitle": "", + "title": "" + }, + "config-general": { + "subtitle": "", + "title": "" + }, + "config-plugins": { + "subtitle": "", + "title": "" + }, + "connect-data": { + "title": "" + }, + "connections": { + "subtitle": "", + "title": "" + }, + "correlations": { + "subtitle": "", + "title": "" + }, + "create": { + "title": "" + }, + "create-alert": { + "title": "" + }, + "create-dashboard": { + "title": "" + }, + "create-folder": { + "title": "" + }, + "create-import": { + "title": "" + }, + "dashboards": { + "subtitle": "", + "title": "" + }, + "data-sources": { + "subtitle": "", + "title": "" + }, + "databases": { + "title": "" + }, + "datasources": { + "subtitle": "", + "title": "" + }, + "detect": { + "title": "" + }, + "drilldown": { + "title": "" + }, + "explore": { + "title": "" + }, + "frontend": { + "subtitle": "", + "title": "" + }, + "frontend-app": { + "title": "" + }, + "global-orgs": { + "subtitle": "", + "title": "" + }, + "global-users": { + "subtitle": "", + "title": "" + }, + "grafana-quaderno": { + "title": "" + }, + "groupsync": { + "subtitle": "" + }, + "help": { + "title": "" + }, + "help/community": "", + "help/documentation": "", + "help/keyboard-shortcuts": "", + "help/support": "", + "history-container": { + "drawer-tittle": "" + }, + "history-wrapper": { + "collapse": "", + "expand": "", + "icon-selected": "", + "icon-unselected": "", + "show-more": "", + "today": "", + "yesterday": "" + }, + "home": { + "title": "" + }, + "incidents": { + "title": "" + }, + "infrastructure": { + "subtitle": "", + "title": "" + }, + "integrations": { + "title": "" + }, + "k6": { + "title": "" + }, + "kubernetes": { + "title": "" + }, + "library-panels": { + "subtitle": "", + "title": "" + }, + "machine-learning": { + "title": "" + }, + "manage-folder": { + "subtitle": "" + }, + "migrate-to-cloud": { + "subtitle": "", + "title": "" + }, + "monitoring": { + "subtitle": "", + "title": "" + }, + "new": { + "title": "" + }, + "new-dashboard": { + "title": "" + }, + "new-folder": { + "title": "" + }, + "oncall": { + "title": "" + }, + "org-settings": { + "subtitle": "", + "title": "" + }, + "playlists": { + "subtitle": "", + "title": "" + }, + "plugins": { + "subtitle": "", + "title": "" + }, + "private-data-source-connections": { + "subtitle": "", + "title": "" + }, + "profile/notifications": { + "title": "" + }, + "profile/password": { + "title": "" + }, + "profile/settings": { + "title": "" + }, + "profiles": { + "title": "" + }, + "public": { + "title": "" + }, + "recently-deleted": { + "subtitle": "", + "title": "" + }, + "recorded-queries": { + "title": "" + }, + "reporting": { + "title": "" + }, + "scenes": { + "title": "" + }, + "search": { + "placeholderCommandPalette": "" + }, + "search-dashboards": { + "title": "" + }, + "server-settings": { + "subtitle": "", + "title": "" + }, + "service-accounts": { + "subtitle": "", + "title": "" + }, + "setup-guide": { + "title": "" + }, + "shared-dashboard": { + "subtitle": "", + "title": "" + }, + "sign-out": { + "title": "" + }, + "slo": { + "title": "" + }, + "snapshots": { + "subtitle": "", + "title": "" + }, + "starred": { + "title": "" + }, + "starred-empty": { + "title": "" + }, + "statistics-and-licensing": { + "title": "" + }, + "storage": { + "subtitle": "", + "title": "" + }, + "support-bundles": { + "subtitle": "", + "title": "" + }, + "synthetics": { + "title": "" + }, + "teams": { + "subtitle": "", + "title": "" + }, + "testing-and-synthetics": { + "subtitle": "", + "title": "" + }, + "upgrading": { + "title": "" + }, + "users": { + "subtitle": "", + "title": "" + } + }, + "navigation": { + "invite-user": { + "invite-button": "", + "invite-tooltip": "" + }, + "item": { + "add-bookmark": "", + "remove-bookmark": "" + }, + "kiosk": { + "tv-alert": "" + }, + "megamenu": { + "close": "", + "dock": "", + "list-label": "", + "open": "", + "undock": "" + }, + "rss-button": "" + }, + "news": { + "drawer": { + "close": "" + }, + "title": "" + }, + "notifications": { + "empty-state": { + "description": "", + "title": "" + }, + "starred-dashboard": "", + "unstarred-dashboard": "" + }, + "oauth": { + "form": { + "server-discovery-action-button": "", + "server-discovery-modal-close": "", + "server-discovery-modal-loading": "", + "server-discovery-modal-submit": "" + }, + "login": { + "error": "" + } + }, + "panel": { + "header-menu": { + "copy": "", + "create-library-panel": "", + "duplicate": "", + "edit": "", + "explore": "", + "get-help": "", + "hide-legend": "", + "inspect": "", + "inspect-data": "", + "inspect-json": "", + "more": "", + "new-alert-rule": "", + "query": "", + "remove": "", + "replace-library-panel": "", + "share": "", + "show-legend": "", + "unlink-library-panel": "", + "view": "" + } + }, + "panel-search": { + "no-matches": "", + "unsupported-layout": "" + }, + "panel-type-filter": { + "clear-button": "" + }, + "playlist-edit": { + "error-prefix": "", + "form": { + "add-tag-label": "", + "add-tag-placeholder": "", + "add-title-label": "", + "cancel": "", + "heading": "", + "interval-label": "", + "interval-placeholder": "", + "interval-required": "", + "name-label": "", + "name-placeholder": "", + "name-required": "", + "save": "", + "table-delete": "", + "table-drag": "", + "table-empty": "", + "table-heading": "" + }, + "sub-title": "", + "title": "" + }, + "playlist-page": { + "card": { + "delete": "", + "edit": "", + "start": "", + "tooltip": "" + }, + "create-button": { + "title": "" + }, + "delete-modal": { + "body": "", + "confirm-text": "" + }, + "empty": { + "button": "", + "pro-tip": "", + "title": "" + } + }, + "playlists": { + "empty-state": { + "message": "" + } + }, + "plugins": { + "catalog": { + "no-updates-available": "", + "update-all": { + "all-plugins-updated": "", + "available-header": "", + "button": "", + "cloud-update-message": "", + "error": "", + "error-status-text": "", + "header": "", + "installed-header": "", + "modal-confirmation": "", + "modal-dismiss": "", + "modal-in-progress": "", + "modal-title": "", + "name-header": "", + "update-header": "", + "update-status-text": "" + }, + "versions": { + "confirmation-text-1": "", + "confirmation-text-2": "", + "downgrade-confirm": "", + "downgrade-title": "" + } + }, + "details": { + "connections-tab": { + "description": "" + }, + "labels": { + "contactGrafanaLabs": "", + "customLinks": "", + "customLinksTooltip": "", + "dependencies": "", + "documentation": "", + "downloads": "", + "from": "", + "installedVersion": "", + "lastCommitDate": "", + "latestVersion": "", + "license": "", + "raiseAnIssue": "", + "reportAbuse": "", + "reportAbuseTooltip": "", + "repository": "", + "signature": "", + "status": "", + "updatedAt": "" + }, + "modal": { + "cancel": "", + "copyEmail": "", + "description": "", + "node": "", + "title": "" + } + }, + "empty-state": { + "message": "" + }, + "filter": { + "disabled": "", + "sort": "", + "sort-list": "", + "state": "" + }, + "plugin-help": { + "error": "", + "not-found": "" + } + }, + "profile": { + "change-password": { + "cancel-button": "", + "cannot-change-password-message": "", + "change-password-button": "", + "confirm-password-label": "", + "confirm-password-required": "", + "ldap-auth-proxy-message": "", + "new-password-label": "", + "new-password-required": "", + "new-password-same-as-old": "", + "old-password-label": "", + "old-password-required": "", + "passwords-must-match": "", + "strong-password-validation-register": "" + } + }, + "public-dashboard": { + "acknowledgment-checkboxes": { + "ack-title": "", + "data-src-ack-desc": "", + "data-src-ack-tooltip": "", + "public-ack-desc": "", + "public-ack-tooltip": "", + "usage-ack-desc": "", + "usage-ack-desc-tooltip": "" + }, + "config": { + "can-view-dashboard-radio-button-label": "", + "copy-button": "", + "dashboard-url-field-label": "", + "email-share-type-option-label": "", + "pause-sharing-dashboard-label": "", + "public-share-type-option-label": "", + "revoke-public-URL-button": "", + "revoke-public-URL-button-title": "", + "settings-title": "" + }, + "configuration": { + "display-annotations-description": "", + "display-annotations-label": "", + "enable-time-range-description": "", + "enable-time-range-label": "", + "settings-label": "", + "success-pause": "", + "success-resume": "", + "success-update": "", + "success-update-old": "", + "time-range-label": "", + "time-range-tooltip": "" + }, + "create-page": { + "generate-public-url-button": "", + "unsupported-features-desc": "", + "welcome-title": "" + }, + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "email-sharing": { + "accept-button": "", + "alert-text": "", + "bill-ack": "", + "cancel-button": "", + "input-invalid-email-text": "", + "input-required-email-text": "", + "invite-button": "", + "invite-field-desc": "", + "invite-field-label": "", + "learn-more-button": "", + "recipient-email-placeholder": "", + "recipient-invalid-email-text": "", + "recipient-invitation-button": "", + "recipient-invitation-description": "", + "recipient-invitation-tooltip": "", + "recipient-list-description": "", + "recipient-list-title": "", + "recipient-required-email-text": "", + "resend-button": "", + "resend-button-title": "", + "resend-invite-label": "", + "revoke-access-label": "", + "revoke-button": "", + "revoke-button-title": "", + "success-creation": "", + "success-share-type-change": "" + }, + "modal-alerts": { + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "save-dashboard-changes-alert-title": "", + "unsupport-data-source-alert-readmore-link": "", + "unsupported-data-source-alert-desc": "", + "unsupported-data-source-alert-title": "", + "unsupported-template-variable-alert-desc": "", + "unsupported-template-variable-alert-title": "" + }, + "public-sharing": { + "accept-button": "", + "alert-text": "", + "cancel-button": "", + "learn-more-button": "", + "public-ack": "", + "success-creation": "", + "success-share-type-change": "" + }, + "settings-bar-header": { + "collapse-settings-tooltip": "", + "expand-settings-tooltip": "" + }, + "settings-configuration": { + "default-time-range-label": "", + "default-time-range-label-desc": "", + "show-annotations-label": "", + "show-annotations-label-desc": "", + "time-range-picker-label": "", + "time-range-picker-label-desc": "" + }, + "settings-summary": { + "annotations-hide-text": "", + "annotations-show-text": "", + "time-range-picker-disabled-text": "", + "time-range-picker-enabled-text": "", + "time-range-text": "" + }, + "share": { + "success-delete": "", + "success-delete-old": "" + }, + "share-configuration": { + "share-type-label": "" + }, + "share-externally": { + "copy-link-button": "", + "email-share-type-option-description": "", + "email-share-type-option-label": "", + "no-upsert-perm-alert-desc": "", + "no-upsert-perm-alert-title": "", + "pause-access-button": "", + "pause-access-tooltip": "", + "public-share-type-option-description": "", + "public-share-type-option-label": "", + "resume-access-button": "", + "revoke-access-button": "", + "revoke-access-description": "", + "unsupported-data-source-alert-desc": "" + }, + "sharing": { + "success-creation": "" + } + }, + "public-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "public-dashboard-users-access-list": { + "dashboard-modal": { + "external-link": "", + "loading-text": "", + "open-dashboard-list-text": "", + "public-dashboard-link": "", + "public-dashboard-setting": "", + "sharing-setting": "" + }, + "delete-user-modal": { + "delete-user-button-text": "", + "delete-user-cancel-button": "", + "delete-user-revoke-access-button": "", + "revoke-access-title": "", + "revoke-user-access-modal-desc-line1": "", + "revoke-user-access-modal-desc-line2": "" + }, + "delete-user-shared-dashboards-modal": { + "revoke-user-access-modal-desc-line2": "" + }, + "modal": { + "dashboard-modal-title": "", + "shared-dashboard-modal-title": "" + }, + "table-body": { + "dashboard-count_other": "" + }, + "table-header": { + "activated-label": "", + "activated-tooltip": "", + "email-label": "", + "last-active-label": "", + "origin-label": "", + "role-label": "" + } + }, + "query-operation": { + "header": { + "collapse-row": "", + "datasource-help": "", + "drag-and-drop": "", + "duplicate-query": "", + "expand-row": "", + "hide-response": "", + "remove-query": "", + "show-response": "", + "toggle-edit-mode": "" + }, + "query-editor-not-exported": "" + }, + "recently-deleted": { + "buttons": { + "delete": "", + "restore": "" + }, + "page": { + "no-deleted-dashboards": "", + "no-deleted-dashboards-text": "", + "no-search-result": "" + }, + "permanently-delete-modal": { + "confirm-text": "", + "delete-button": "", + "delete-loading": "", + "title": "", + "text_other": "" + }, + "restore-modal": { + "restore-button": "", + "restore-loading": "", + "title": "", + "folder-picker-text_other": "", + "text_other": "" + } + }, + "recentlyDeleted": { + "filter": { + "placeholder": "" + } + }, + "reduce": { + "strictMode": { + "description": "", + "title": "" + } + }, + "refresh-picker": { + "aria-label": { + "choose-interval": "", + "duration-selected": "" + }, + "auto-option": { + "aria-label": "", + "label": "" + }, + "live-option": { + "aria-label": "", + "label": "" + }, + "off-option": { + "aria-label": "", + "label": "" + }, + "tooltip": { + "interval-selected": "", + "turned-off": "" + } + }, + "return-to-previous": { + "button": { + "label": "" + }, + "dismissable-button": "" + }, + "role-picker": { + "built-in": { + "basic-roles": "" + }, + "input": { + "no-roles": "" + }, + "menu": { + "clear-button": "", + "tooltip": "" + }, + "sub-menu": { + "clear-button": "" + }, + "title": { + "description": "" + } + }, + "role-picker-drawer": { + "basic-roles": { + "label": "" + } + }, + "route-error": { + "description": "", + "reload-button": "", + "title": "" + }, + "save-dashboards": { + "message-length": { + "info": "", + "title": "" + }, + "name-exists": { + "message-info": "", + "message-suggestion": "", + "title": "" + } + }, + "scopes": { + "dashboards": { + "collapse": "", + "expand": "", + "loading": "", + "noResultsForFilter": "", + "noResultsForFilterClear": "", + "noResultsForScopes": "", + "noResultsNoScopes": "", + "search": "", + "toggle": { + "collapse": "", + "disabled": "", + "expand": "" + } + }, + "selector": { + "apply": "", + "cancel": "", + "input": { + "placeholder": "", + "removeAll": "" + }, + "title": "" + }, + "tree": { + "collapse": "", + "expand": "", + "headline": { + "noResults": "", + "recommended": "", + "results": "" + }, + "search": "" + } + }, + "search": { + "actions": { + "include-panels": "", + "remove-datasource-filter": "", + "sort-placeholder": "", + "starred": "", + "view-as-folders": "", + "view-as-list": "" + }, + "dashboard-actions": { + "import": "", + "new": "", + "new-dashboard": "", + "new-folder": "" + }, + "results-table": { + "datasource-header": "", + "deleted-less-than-1-min": "", + "deleted-remaining-header": "", + "location-header": "", + "name-header": "", + "tags-header": "", + "type-dashboard": "", + "type-folder": "", + "type-header": "" + }, + "search-input": { + "include-panels-placeholder": "", + "placeholder": "" + } + }, + "select": { + "select-menu": { + "selected-count": "" + } + }, + "service-account-create-page": { + "create": { + "button": "" + }, + "name": { + "label": "", + "required-error": "" + }, + "page-nav": { + "label": "" + }, + "role": { + "label": "" + } + }, + "service-accounts": { + "empty-state": { + "button-title": "", + "message": "", + "more-info": "", + "title": "" + } + }, + "share-dashboard": { + "menu": { + "export-json-title": "", + "share-externally-title": "", + "share-internally-title": "", + "share-snapshot-title": "" + }, + "share-button": "", + "share-button-tooltip": "" + }, + "share-drawer": { + "confirm-action": { + "back-arrow-button": "", + "cancel-button": "" + } + }, + "share-modal": { + "dashboard": { + "title": "" + }, + "embed": { + "copy": "", + "html": "", + "html-description": "", + "info": "", + "time-range": "" + }, + "export": { + "back-button": "", + "cancel-button": "", + "info-text": "", + "loading": "", + "save-button": "", + "share-externally-label": "", + "view-button": "" + }, + "library": { + "info": "" + }, + "link": { + "copy-link-button": "", + "info-text": "", + "link-url": "", + "render-alert": "", + "render-instructions": "", + "rendered-image": "", + "save-alert": "", + "save-dashboard": "", + "shorten-url": "", + "time-range-description": "", + "time-range-label": "" + }, + "panel": { + "title": "" + }, + "snapshot": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "deleted-message": "", + "expire": "", + "expire-day": "", + "expire-hour": "", + "expire-never": "", + "expire-week": "", + "info-text-1": "", + "info-text-2": "", + "local-button": "", + "mistake-message": "", + "name": "", + "timeout": "", + "timeout-description": "", + "url-label": "" + }, + "tab-title": { + "embed": "", + "export": "", + "library-panel": "", + "link": "", + "panel-embed": "", + "public-dashboard": "", + "public-dashboard-title": "", + "snapshot": "" + }, + "theme-picker": { + "current": "", + "dark": "", + "field-name": "", + "light": "" + }, + "view-json": { + "copy-button": "" + } + }, + "share-panel": { + "drawer": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "" + }, + "menu": { + "new-library-panel-title": "", + "share-embed-title": "", + "share-link-title": "", + "share-snapshot-title": "" + }, + "new-library-panel": { + "cancel-button": "", + "create-button": "" + } + }, + "share-panel-image": { + "preview": { + "title": "" + }, + "settings": { + "height-label": "", + "height-min": "", + "height-placeholder": "", + "height-required": "", + "max-warning": "", + "scale-factor-label": "", + "scale-factor-min": "", + "scale-factor-placeholder": "", + "scale-factor-required": "", + "title": "", + "width-label": "", + "width-min": "", + "width-placeholder": "", + "width-required": "" + } + }, + "share-playlist": { + "checkbox-description": "", + "checkbox-label": "", + "copy-link-button": "", + "link-url-label": "", + "mode": "", + "mode-kiosk": "", + "mode-normal": "", + "title": "" + }, + "shared": { + "preferences": { + "theme": { + "dark-label": "", + "light-label": "", + "system-label": "" + } + } + }, + "shared-dashboard": { + "delete-modal": { + "revoke-body-text": "", + "revoke-title": "" + }, + "fields": { + "timezone-label": "" + } + }, + "shared-dashboard-list": { + "button": { + "config-button-tooltip": "", + "revoke-button-text": "", + "revoke-button-tooltip": "", + "view-button-tooltip": "" + }, + "empty-state": { + "message": "", + "more-info": "" + }, + "toggle": { + "pause-sharing-toggle-text": "" + } + }, + "shared-preferences": { + "fields": { + "home-dashboard-label": "", + "home-dashboard-placeholder": "", + "locale-label": "", + "locale-placeholder": "", + "theme-description": "", + "theme-label": "", + "week-start-label": "" + }, + "theme": { + "default-label": "" + }, + "title": "" + }, + "sign-up": { + "back-button": "", + "submit-button": "", + "verify": { + "back-button": "", + "complete-button": "", + "header": "", + "info": "", + "send-button": "" + } + }, + "silences": { + "empty-state": { + "button-title": "", + "title": "" + }, + "table": { + "add-silence-button": "", + "edit-button": "", + "expired-silences": "", + "no-matching-silences": "", + "noConfig": "", + "recreate-button": "", + "unsilence-button": "" + } + }, + "silences-table": { + "header": { + "alert-name": "", + "state": "" + } + }, + "snapshot": { + "empty-state": { + "message": "", + "more-info": "" + }, + "external-badge": "", + "name-column-header": "", + "share": { + "cancel-button": "", + "copy-link-button": "", + "delete-button": "", + "delete-description": "", + "delete-permission-tooltip": "", + "delete-title": "", + "deleted-alert": "", + "expiration-label": "", + "info-alert": "", + "learn-more-button": "", + "local-button": "", + "name-label": "", + "new-snapshot-button": "", + "success-creation": "", + "success-delete": "", + "view-all-button": "" + }, + "share-panel": { + "info-alert": "" + }, + "url-column-header": "", + "view-button": "" + }, + "table": { + "container": { + "content": "", + "show-all-series": "", + "show-only-series": "" + } + }, + "tag-filter": { + "clear-button": "", + "loading": "", + "no-tags": "", + "placeholder": "" + }, + "teams": { + "empty-state": { + "button-title": "", + "message": "", + "pro-tip": "", + "title": "" + } + }, + "theme-preview": { + "breadcrumbs": { + "dashboards": "", + "home": "" + }, + "panel": { + "form-label": "", + "title": "" + } + }, + "time-picker": { + "absolute": { + "recent-title": "", + "title": "" + }, + "calendar": { + "apply-button": "", + "cancel-button": "", + "close": "", + "next-month": "", + "previous-month": "", + "select-time": "" + }, + "content": { + "empty-recent-list-docs": "", + "empty-recent-list-info": "", + "filter-placeholder": "" + }, + "copy-paste": { + "copy-success-message": "", + "default-error-message": "", + "default-error-title": "", + "tooltip-copy": "", + "tooltip-paste": "" + }, + "footer": { + "change-settings-button": "", + "fiscal-year-option": "", + "fiscal-year-start": "", + "time-zone-option": "", + "time-zone-selection": "" + }, + "range-content": { + "apply-button": "", + "default-error": "", + "fiscal-year": "", + "from-input": "", + "open-input-calendar": "", + "range-error": "", + "to-input": "" + }, + "range-picker": { + "backwards-time-aria-label": "", + "current-time-selected": "", + "forwards-time-aria-label": "", + "to": "", + "zoom-out-button": "", + "zoom-out-tooltip": "" + }, + "time-range": { + "apply": "", + "aria-role": "", + "default-title": "", + "example": "", + "example-details": "", + "example-title": "", + "from-label": "", + "from-to": "", + "more-info": "", + "specify": "", + "submit-button-label": "", + "supported-formats": "", + "to-label": "" + }, + "zone": { + "select-aria-label": "", + "select-search-input": "" + } + }, + "trails": { + "bookmarks": { + "or-view-bookmarks": "" + }, + "card": { + "date-created": "" + }, + "home": { + "learn-more": "", + "lets-start": "", + "start-your-metrics-exploration": "", + "subtitle": "" + }, + "metric-select": { + "filter-by": "", + "native-histogram": "", + "new-badge": "", + "otel-switch": "" + }, + "native-histogram-banner": { + "ch-heatmap": "", + "ch-histogram": "", + "click-histogram": "", + "hide-examples": "", + "learn-more": "", + "metric-examples": "", + "nh-heatmap": "", + "nh-histogram": "", + "now": "", + "previously": "", + "see-examples": "", + "sentence": "" + }, + "recent-metrics": { + "or-view-a-recent-exploration": "" + }, + "settings": { + "always-keep-selected-metric-graph-in-view": "", + "show-previews-of-metric-graphs": "" + } + }, + "transformations": { + "empty": { + "add-transformation-body": "", + "add-transformation-header": "" + } + }, + "upgrade-box": { + "discovery-text": "", + "discovery-text-continued": "", + "get-started": "", + "learn-more": "", + "upgrade-button": "" + }, + "user-orgs": { + "current-org-button": "", + "name-column": "", + "role-column": "", + "select-org-button": "", + "title": "" + }, + "user-profile": { + "fields": { + "email-error": "", + "email-label": "", + "name-error": "", + "name-label": "", + "username-label": "" + }, + "tabs": { + "general": "" + } + }, + "user-session": { + "auth-module-column": "", + "browser-column": "", + "created-at-column": "", + "identity-provider-column": "", + "ip-column": "", + "revoke": "", + "seen-at-column": "" + }, + "user-sessions": { + "loading": "" + }, + "users": { + "empty-state": { + "message": "" + } + }, + "users-access-list": { + "tabs": { + "public-dashboard-users-tab-title": "", + "shared-dashboard-users-tab-title": "" + } + }, + "variable": { + "adhoc": { + "placeholder": "" + }, + "dropdown": { + "placeholder": "" + }, + "picker": { + "link-all": "", + "option-all": "", + "option-selected-values": "", + "option-tooltip": "" + }, + "textbox": { + "placeholder": "" + } + }, + "variables": { + "empty-state": { + "button-title": "", + "info-box-content": "", + "info-box-content-2": "", + "title": "" + }, + "unknown-table": { + "loading": "", + "no-unknowns": "", + "renamed-or-missing-variables": "", + "variable": "" + } + } +} \ No newline at end of file From e191a3523459c6a3a325ce9771c23465d15cfa80 Mon Sep 17 00:00:00 2001 From: Jacob Valdez Date: Mon, 10 Mar 2025 14:55:14 -0500 Subject: [PATCH 20/63] Adding note about upgrading plugins prior to migration (#100235) * Adding note about upgradfing plugins prior to migration * adding admonition vis-a-vis enterprise plugin add-on * Update cloud-migration-assistant.md --- .../migration-guide/cloud-migration-assistant.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/sources/administration/migration-guide/cloud-migration-assistant.md b/docs/sources/administration/migration-guide/cloud-migration-assistant.md index 87a5a47cb5a..5e1e1b0b423 100644 --- a/docs/sources/administration/migration-guide/cloud-migration-assistant.md +++ b/docs/sources/administration/migration-guide/cloud-migration-assistant.md @@ -147,6 +147,12 @@ Your data sources, including credentials, are migrated securely and seamlessly t The migration assistant supports any plugins found in the plugins catalog. As long as the plugin is signed or is a core plugin built into Grafana, it is eligible for migration. Due to security reasons, unsigned plugins are not supported in Grafana Cloud. If you are using any unsigned private plugins, Grafana recommends you seek an alternative plugin for the catalog or work on a strategy to deprecate certain functionality from your self-managed instance. +Upgrade any plugins you intend to migrate before using the migration assistant as any migrated plugins will be configured on the Grafana Cloud instance as the latest version of that plugin. + +{{< admonition type="caution">}} +If you want to migrate Enterprise plugins, check what type of plan your Grafana Cloud instance is on and whether or not this plan requires an Enterprise plugin add-on. +{{< /admonition >}} + ### Grafana Alerting resources The migration assistant can migrate the majority of Grafana Alerting resources to your Grafana Cloud instance. These include: From 1e6aa27313ccd8ba6e8a18bb7a4b5e6727dba81e Mon Sep 17 00:00:00 2001 From: Isabel Matwawana <76437239+imatwawana@users.noreply.github.com> Date: Mon, 10 Mar 2025 16:06:59 -0400 Subject: [PATCH 21/63] Docs: Add enterprise availability notes (#101909) * Added enterprise only note * Fixed wording * Added availability to share panel internally and removed invite new member * Fixed wording for consistency * Removed link to invite new members section * Discarded change --- .../share-dashboards-panels/_index.md | 28 ++++--------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/docs/sources/dashboards/share-dashboards-panels/_index.md b/docs/sources/dashboards/share-dashboards-panels/_index.md index 5885b9b8e86..d424a4b75fb 100644 --- a/docs/sources/dashboards/share-dashboards-panels/_index.md +++ b/docs/sources/dashboards/share-dashboards-panels/_index.md @@ -81,8 +81,6 @@ Grafana enables you to share dashboards and panels with other users within your - Reports - Library panels -You can also invite new members to your organization from the **Share** menu. For more information, refer to [Invite new members](#invite-new-members). - You must have an authorized viewer permission to see an image rendered by a direct link. The same permission is also required to view embedded links unless you have anonymous access permission enabled for your Grafana instance. {{< admonition type="note" >}} @@ -140,7 +138,7 @@ Learn how to configure and manage externally shared dashboards in [Externally sh ### Schedule a report {{< admonition type="note" >}} -This feature is only available in Grafana Enterprise. +This feature is only available on Grafana Enterprise. {{< /admonition >}} To share your dashboard as a report, follow these steps: @@ -204,6 +202,10 @@ In addition to sharing dashboards as links, reports, and snapshots, you can expo ### Export a dashboard as PDF +{{< admonition type="note" >}} +This feature is only available on Grafana Enterprise. +{{< /admonition >}} + To export a dashboard in its current state as a PDF, follow these steps: 1. Click **Dashboards** in the main menu. @@ -365,23 +367,3 @@ To delete existing snapshots, follow these steps: 1. Click the red **x** next to the snapshot URL that you want to delete. The snapshot is immediately deleted. You may need to clear your browser cache or use a private or incognito browser to confirm this. - -## Invite new members - -{{< admonition type="note" >}} -This feature is only available on Grafana Cloud. -{{< /admonition >}} - -You can invite new members to your organization using the **Share** drop-down menu. You must have the `OrgUsersAdd` permission to use this feature. - -To invite a new member to your organization, follow these steps: - -1. Click **Dashboards** in the main menu and open any dashboard. -1. Click the **Share** drop-down list in the top-right corner and select **Invite new member**. - - The **Members** page of your Grafana Cloud Portal opens. - -1. Enter the email address of the new member in the provided field. -1. Make a selection in the **Role** drop-down list. -1. (Optional) Select the **Receive billing emails** checkbox, if applicable. -1. Click **Invite**. From 229b549c238c862fc66be48c1dbe0f4ec12b7e7d Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Tue, 11 Mar 2025 08:34:25 +0300 Subject: [PATCH 22/63] Provisioning: Move folder management into its own helper (#101864) * folder * update folder links * Fix test * update * cleanup --------- Co-authored-by: Clarity-89 --- .betterer.results | 11 +- pkg/apis/folder/v0alpha1/register.go | 3 +- pkg/registry/apis/provisioning/files.go | 66 ++++++--- .../apis/provisioning/jobs/sync/worker.go | 130 +---------------- .../apis/provisioning/resources/folders.go | 135 ++++++++++++++++++ .../BrowseDashboardsPage.tsx | 16 +-- .../NewProvisionedFolderForm.test.tsx | 27 +++- .../components/NewProvisionedFolderForm.tsx | 57 ++++---- 8 files changed, 250 insertions(+), 195 deletions(-) create mode 100644 pkg/registry/apis/provisioning/resources/folders.go diff --git a/.betterer.results b/.betterer.results index c8692914cbd..026cbcdb441 100644 --- a/.betterer.results +++ b/.betterer.results @@ -2959,10 +2959,6 @@ exports[`better eslint`] = { "public/app/features/auth-config/utils/data.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/features/browse-dashboards/BrowseDashboardsPage.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] - ], "public/app/features/browse-dashboards/api/browseDashboardsAPI.ts:5381": [ [0, 0, 0, "Do not re-export imported variable (\`@reduxjs/toolkit/query/react\`)", "0"] ], @@ -2977,7 +2973,7 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] ], "public/app/features/browse-dashboards/components/NewProvisionedFolderForm.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], + [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], @@ -2987,14 +2983,15 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "7"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "8"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "9"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "10"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "10"], [0, 0, 0, "No untranslated strings. Wrap text with ", "11"], [0, 0, 0, "No untranslated strings. Wrap text with ", "12"], [0, 0, 0, "No untranslated strings. Wrap text with ", "13"], [0, 0, 0, "No untranslated strings. Wrap text with ", "14"], [0, 0, 0, "No untranslated strings. Wrap text with ", "15"], [0, 0, 0, "No untranslated strings. Wrap text with ", "16"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "17"] + [0, 0, 0, "No untranslated strings. Wrap text with ", "17"], + [0, 0, 0, "No untranslated strings. Wrap text with ", "18"] ], "public/app/features/browse-dashboards/state/index.ts:5381": [ [0, 0, 0, "Do not use export all (\`export * from ...\`)", "0"], diff --git a/pkg/apis/folder/v0alpha1/register.go b/pkg/apis/folder/v0alpha1/register.go index 4f317ac272b..27f1e0ed670 100644 --- a/pkg/apis/folder/v0alpha1/register.go +++ b/pkg/apis/folder/v0alpha1/register.go @@ -3,10 +3,11 @@ package v0alpha1 import ( "fmt" - "github.com/grafana/grafana/pkg/apimachinery/utils" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/grafana/grafana/pkg/apimachinery/utils" ) const ( diff --git a/pkg/registry/apis/provisioning/files.go b/pkg/registry/apis/provisioning/files.go index d36dafe8017..71096f98678 100644 --- a/pkg/registry/apis/provisioning/files.go +++ b/pkg/registry/apis/provisioning/files.go @@ -8,7 +8,6 @@ import ( "net/http" "path" "strings" - "time" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -16,6 +15,8 @@ import ( "k8s.io/apiserver/pkg/registry/rest" "github.com/grafana/grafana-app-sdk/logging" + "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" + folder "github.com/grafana/grafana/pkg/apis/folder/v0alpha1" provisioning "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1" "github.com/grafana/grafana/pkg/registry/apis/provisioning/repository" "github.com/grafana/grafana/pkg/registry/apis/provisioning/resources" @@ -200,19 +201,14 @@ func (s *filesConnector) doWrite(ctx context.Context, update bool, repo reposito return nil, apierrors.NewBadRequest("repository does not support read-writing") } + parser, err := s.parsers.GetParser(ctx, writer) + if err != nil { + return nil, err + } + defer func() { _ = req.Body.Close() }() if strings.HasSuffix(path, "/") { - if err := writer.Create(ctx, path, ref, nil, message); err != nil { - return nil, fmt.Errorf("failed to create folder: %w", err) - } - return &provisioning.ResourceWrapper{ - Path: path, - Ref: ref, - Timestamp: &metav1.Time{Time: time.Now()}, - // TODO: should we return something here? - // TypeMeta: metav1.TypeMeta{}, - // Resource: provisioning.ResourceObjects{}, - }, nil + return s.doCreateFolder(ctx, writer, path, ref, message, parser) } data, err := io.ReadAll(req.Body) @@ -226,11 +222,6 @@ func (s *filesConnector) doWrite(ctx context.Context, update bool, repo reposito Ref: ref, } - parser, err := s.parsers.GetParser(ctx, writer) - if err != nil { - return nil, err - } - parsed, err := parser.Parse(ctx, info, true) if err != nil { if errors.Is(err, resources.ErrUnableToReadResourceBytes) { @@ -282,6 +273,47 @@ func (s *filesConnector) doWrite(ctx context.Context, update bool, repo reposito return parsed.AsResourceWrapper(), err } +func (s *filesConnector) doCreateFolder(ctx context.Context, repo repository.Writer, path string, ref string, message string, parser *resources.Parser) (*provisioning.ResourceWrapper, error) { + manager := resources.NewFolderManager(repo, parser.Client().Resource(folder.SchemeGroupVersion.WithResource(folder.RESOURCE))) + + // Now actually create the folder + if err := repo.Create(ctx, path, ref, nil, message); err != nil { + return nil, fmt.Errorf("failed to create folder: %w", err) + } + + cfg := repo.Config() + wrap := &provisioning.ResourceWrapper{ + Path: path, + Ref: ref, + Repository: provisioning.ResourceRepositoryInfo{ + Type: cfg.Spec.Type, + Namespace: cfg.Namespace, + Name: cfg.Name, + Title: cfg.Spec.Title, + }, + Resource: provisioning.ResourceObjects{ + Action: provisioning.ResourceActionCreate, + }, + } + + if ref == "" { + folderName, err := manager.EnsureFolderPathExist(ctx, path) + if err != nil { + return nil, err + } + + current, err := manager.GetFolder(ctx, folderName) + if err != nil && !apierrors.IsNotFound(err) { + return nil, err // unable to check if the folder exists + } + wrap.Resource.Upsert = v0alpha1.Unstructured{ + Object: current.Object, + } + } + + return wrap, nil +} + func (s *filesConnector) doDelete(ctx context.Context, repo repository.Repository, path string, ref string, message string) (*provisioning.ResourceWrapper, error) { if err := repository.IsWriteAllowed(repo.Config(), ref); err != nil { return nil, err diff --git a/pkg/registry/apis/provisioning/jobs/sync/worker.go b/pkg/registry/apis/provisioning/jobs/sync/worker.go index ff2a7b5df81..170fe9cd833 100644 --- a/pkg/registry/apis/provisioning/jobs/sync/worker.go +++ b/pkg/registry/apis/provisioning/jobs/sync/worker.go @@ -6,19 +6,14 @@ import ( "encoding/json" "errors" "fmt" - "path" "sort" - "strings" - apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/dynamic" "github.com/grafana/grafana-app-sdk/logging" - "github.com/grafana/grafana/pkg/apimachinery/utils" dashboard "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1" folders "github.com/grafana/grafana/pkg/apis/folder/v0alpha1" provisioning "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1" @@ -26,7 +21,6 @@ import ( "github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs" "github.com/grafana/grafana/pkg/registry/apis/provisioning/repository" "github.com/grafana/grafana/pkg/registry/apis/provisioning/resources" - "github.com/grafana/grafana/pkg/registry/apis/provisioning/safepath" "github.com/grafana/grafana/pkg/storage/legacysql/dualwrite" ) @@ -165,11 +159,11 @@ func (r *SyncWorker) createJob(ctx context.Context, repo repository.ReaderWriter progress: progress, parser: parser, lister: r.lister, - folders: dynamicClient.Resource(schema.GroupVersionResource{ + folders: resources.NewFolderManager(repo, dynamicClient.Resource(schema.GroupVersionResource{ Group: folders.GROUP, Version: folders.VERSION, Resource: folders.RESOURCE, - }), + })), dashboards: dynamicClient.Resource(schema.GroupVersionResource{ Group: dashboard.GROUP, Version: "v1alpha1", @@ -208,7 +202,7 @@ type syncJob struct { progress jobs.JobProgressRecorder parser *resources.Parser lister resources.ResourceLister - folders dynamic.ResourceInterface + folders *resources.FolderManager dashboards dynamic.ResourceInterface folderLookup *resources.FolderTree resourcesLookup map[resourceID]string // the path with this k8s name @@ -219,7 +213,7 @@ func (r *syncJob) run(ctx context.Context, options provisioning.SyncJobOptions) cfg := r.repository.Config() rootFolder := resources.RootFolder(cfg) if rootFolder != "" { - if err := r.ensureFolderExists(ctx, resources.Folder{ + if err := r.folders.EnsureFolderExists(ctx, resources.Folder{ ID: rootFolder, // will not change if exists Title: cfg.Spec.Title, }, ""); err != nil { @@ -458,7 +452,7 @@ func (r *syncJob) writeResourceFromFile(ctx context.Context, path string, ref st r.resourcesLookup[id] = path // Make sure the parent folders exist - folder, err := r.ensureFolderPathExists(ctx, path) + folder, err := r.folders.EnsureFolderPathExist(ctx, path) if err != nil { result.Error = fmt.Errorf("failed to ensure folder path exists: %w", err) return result @@ -485,124 +479,10 @@ func (r *syncJob) writeResourceFromFile(ctx context.Context, path string, ref st return result } -// ensureFolderPathExists creates the folder structure in the cluster. -func (r *syncJob) ensureFolderPathExists(ctx context.Context, filePath string) (parent string, err error) { - cfg := r.repository.Config() - parent = resources.RootFolder(cfg) - - dir := path.Dir(filePath) - if dir == "." { - return parent, nil - } - - if r.folderLookup == nil { - r.folderLookup = resources.NewEmptyFolderTree() - } - - f := resources.ParseFolder(dir, cfg.Name) - if r.folderLookup.In(f.ID) { - return f.ID, nil - } - - var traverse string - for i, part := range strings.Split(f.Path, "/") { - if i == 0 { - traverse = part - } else { - traverse, err = safepath.Join(traverse, part) - if err != nil { - return "", fmt.Errorf("unable to make path: %w", err) - } - } - - f := resources.ParseFolder(traverse, cfg.GetName()) - if r.folderLookup.In(f.ID) { - parent = f.ID - continue - } - - if err := r.ensureFolderExists(ctx, f, parent); err != nil { - return "", fmt.Errorf("ensure folder exists: %w", err) - } - r.folderLookup.Add(f, parent) - parent = f.ID - } - - return f.ID, err -} - -// ensureFolderExists creates the folder if it doesn't exist. -// If the folder already exists: -// - it will error if the folder is not owned by this repository -func (r *syncJob) ensureFolderExists(ctx context.Context, folder resources.Folder, parent string) error { - cfg := r.repository.Config() - obj, err := r.folders.Get(ctx, folder.ID, metav1.GetOptions{}) - if err == nil { - current, ok := obj.GetAnnotations()[utils.AnnoKeyManagerIdentity] - if !ok { - return fmt.Errorf("target folder is not managed by a repository") - } - if current != cfg.Name { - return fmt.Errorf("target folder is managed by a different repository (%s)", current) - } - return nil - } else if !apierrors.IsNotFound(err) { - return fmt.Errorf("failed to check if folder exists: %w", err) - } - - obj = &unstructured.Unstructured{ - Object: map[string]interface{}{ - "spec": map[string]any{ - "title": folder.Title, - }, - }, - } - - meta, err := utils.MetaAccessor(obj) - if err != nil { - return fmt.Errorf("create meta accessor for the object: %w", err) - } - - obj.SetNamespace(cfg.GetNamespace()) - obj.SetName(folder.ID) - if parent != "" { - meta.SetFolder(parent) - } - meta.SetManagerProperties(utils.ManagerProperties{ - Kind: utils.ManagerKindRepo, - Identity: cfg.GetName(), - }) - meta.SetSourceProperties(utils.SourceProperties{ - Path: folder.Path, - Checksum: "", // FIXME: which hash? - }) - - result := jobs.JobResourceResult{ - Name: folder.ID, - Resource: folders.RESOURCE, - Group: folders.GROUP, - Path: folder.Path, - Action: repository.FileActionCreated, - Error: err, - } - - if _, err := r.folders.Create(ctx, obj, metav1.CreateOptions{}); err != nil { - result.Error = fmt.Errorf("failed to create folder: %w", err) - r.progress.Record(ctx, result) - return fmt.Errorf("failed to create folder: %w", err) - } - - r.progress.Record(ctx, result) - - return nil -} - func (r *syncJob) client(kind string) (dynamic.ResourceInterface, error) { switch kind { case dashboard.GROUP, dashboard.DASHBOARD_RESOURCE, "Dashboard": return r.dashboards, nil - case folders.GROUP, folders.RESOURCE, "Folder": - return r.folders, nil } return nil, fmt.Errorf("unsupported resource: %s", kind) } diff --git a/pkg/registry/apis/provisioning/resources/folders.go b/pkg/registry/apis/provisioning/resources/folders.go new file mode 100644 index 00000000000..d519e30273c --- /dev/null +++ b/pkg/registry/apis/provisioning/resources/folders.go @@ -0,0 +1,135 @@ +package resources + +import ( + "context" + "fmt" + "path" + "strings" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/client-go/dynamic" + + "github.com/grafana/grafana/pkg/apimachinery/utils" + "github.com/grafana/grafana/pkg/registry/apis/provisioning/repository" + "github.com/grafana/grafana/pkg/registry/apis/provisioning/safepath" +) + +type FolderManager struct { + repo repository.Repository + lookup *FolderTree + client dynamic.ResourceInterface +} + +func NewFolderManager(repo repository.Repository, client dynamic.ResourceInterface) *FolderManager { + return &FolderManager{ + repo: repo, + lookup: NewEmptyFolderTree(), + client: client, + } +} + +// EnsureFoldersExist creates the folder structure in the cluster. +func (fm *FolderManager) EnsureFolderPathExist(ctx context.Context, filePath string) (parent string, err error) { + if filePath == "" || filePath == "/" || filePath == "." || filePath == "./" { + return "", fmt.Errorf("invald initial path") + } + + cfg := fm.repo.Config() + parent = RootFolder(cfg) + + dir := filePath + if !strings.HasSuffix(filePath, "/") { + dir = path.Dir(filePath) + } + if dir == "." { + return parent, nil + } + + f := ParseFolder(dir, cfg.Name) + if fm.lookup.In(f.ID) { + return f.ID, nil + } + + var traverse string + for i, part := range strings.Split(f.Path, "/") { + if i == 0 { + traverse = part + } else { + traverse, err = safepath.Join(traverse, part) + if err != nil { + return "", fmt.Errorf("unable to make path: %w", err) + } + } + + f := ParseFolder(traverse, cfg.GetName()) + if fm.lookup.In(f.ID) { + parent = f.ID + continue + } + + if err := fm.EnsureFolderExists(ctx, f, parent); err != nil { + return "", fmt.Errorf("ensure folder exists: %w", err) + } + fm.lookup.Add(f, parent) + parent = f.ID + } + + return f.ID, err +} + +// EnsureFolderExists creates the folder if it doesn't exist. +// If the folder already exists: +// - it will error if the folder is not owned by this repository +func (fm *FolderManager) EnsureFolderExists(ctx context.Context, folder Folder, parent string) error { + cfg := fm.repo.Config() + obj, err := fm.client.Get(ctx, folder.ID, metav1.GetOptions{}) + if err == nil { + current, ok := obj.GetAnnotations()[utils.AnnoKeyManagerIdentity] + if !ok { + return fmt.Errorf("target folder is not managed by a repository") + } + if current != cfg.Name { + return fmt.Errorf("target folder is managed by a different repository (%s)", current) + } + return nil + } else if !apierrors.IsNotFound(err) { + return fmt.Errorf("failed to check if folder exists: %w", err) + } + + obj = &unstructured.Unstructured{ + Object: map[string]interface{}{ + "spec": map[string]any{ + "title": folder.Title, + }, + }, + } + + meta, err := utils.MetaAccessor(obj) + if err != nil { + return fmt.Errorf("create meta accessor for the object: %w", err) + } + + obj.SetNamespace(cfg.GetNamespace()) + obj.SetName(folder.ID) + if parent != "" { + meta.SetFolder(parent) + } + meta.SetManagerProperties(utils.ManagerProperties{ + Kind: utils.ManagerKindRepo, + Identity: cfg.GetName(), + }) + meta.SetSourceProperties(utils.SourceProperties{ + Path: folder.Path, + }) + + if _, err := fm.client.Create(ctx, obj, metav1.CreateOptions{}); err != nil { + return fmt.Errorf("failed to create folder: %w", err) + } + return nil +} + +func (fm *FolderManager) GetFolder(ctx context.Context, name string) (*unstructured.Unstructured, error) { + return fm.client.Get(ctx, name, metav1.GetOptions{}) +} diff --git a/public/app/features/browse-dashboards/BrowseDashboardsPage.tsx b/public/app/features/browse-dashboards/BrowseDashboardsPage.tsx index 6b2daa2e25e..cb222a73867 100644 --- a/public/app/features/browse-dashboards/BrowseDashboardsPage.tsx +++ b/public/app/features/browse-dashboards/BrowseDashboardsPage.tsx @@ -5,7 +5,7 @@ import AutoSizer from 'react-virtualized-auto-sizer'; import { GrafanaTheme2 } from '@grafana/data'; import { config, reportInteraction } from '@grafana/runtime'; -import { LinkButton, FilterInput, useStyles2, Text, Stack, Alert, Icon } from '@grafana/ui'; +import { LinkButton, FilterInput, useStyles2, Text, Stack } from '@grafana/ui'; import { Page } from 'app/core/components/Page/Page'; import { getConfig } from 'app/core/config'; import { Trans } from 'app/core/internationalization'; @@ -127,7 +127,6 @@ const BrowseDashboardsPage = memo(() => { ); }; - const prLink = search.get('prLink'); return ( { } > - {prLink && ( - - Open pull request in GitHub - - - } - onRemove={() => window.open(prLink)} - /> - )}
{ }; }); +jest.mock('react-router-dom-v5-compat', () => { + const actual = jest.requireActual('react-router-dom-v5-compat'); + return { + ...actual, + useNavigate: () => jest.fn(), + }; +}); + // Mock the defaults jest.mock('../../dashboard-scene/saving/provisioned/defaults', () => { return { @@ -101,6 +109,14 @@ function setup(props: Partial = {}) { }; } +const mockRequest = { + isSuccess: false, + isError: false, + isLoading: false, + error: null, + data: { resource: { upsert: { metadata: { name: 'new-folder' } } } }, +}; + describe('NewProvisionedFolderForm', () => { beforeEach(() => { jest.clearAllMocks(); @@ -145,12 +161,7 @@ describe('NewProvisionedFolderForm', () => { // Mock useCreateRepositoryFilesWithPathMutation const mockCreate = jest.fn(); - const mockRequest = { - isSuccess: false, - isError: false, - isLoading: false, - error: null, - }; + (useCreateRepositoryFilesWithPathMutation as jest.Mock).mockReturnValue([mockCreate, mockRequest]); (validationSrv.validateNewFolderName as jest.Mock).mockResolvedValue(true); @@ -248,6 +259,7 @@ describe('NewProvisionedFolderForm', () => { (useCreateRepositoryFilesWithPathMutation as jest.Mock).mockReturnValue([ mockCreate, { + ...mockRequest, isSuccess: true, isError: false, isLoading: false, @@ -294,6 +306,7 @@ describe('NewProvisionedFolderForm', () => { (useCreateRepositoryFilesWithPathMutation as jest.Mock).mockReturnValue([ mockCreate, { + ...mockRequest, isSuccess: true, isError: false, isLoading: false, @@ -342,6 +355,7 @@ describe('NewProvisionedFolderForm', () => { (useCreateRepositoryFilesWithPathMutation as jest.Mock).mockReturnValue([ mockCreate, { + ...mockRequest, isSuccess: false, isError: true, isLoading: false, @@ -374,6 +388,7 @@ describe('NewProvisionedFolderForm', () => { (useCreateRepositoryFilesWithPathMutation as jest.Mock).mockReturnValue([ jest.fn(), { + ...mockRequest, isSuccess: false, isError: false, isLoading: true, diff --git a/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.tsx b/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.tsx index 509c0ac5a87..bc1c23043b6 100644 --- a/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.tsx +++ b/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.tsx @@ -1,22 +1,20 @@ import { skipToken } from '@reduxjs/toolkit/query'; 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, locationService } from '@grafana/runtime'; +import { getAppEvents } from '@grafana/runtime'; import { Alert, Button, Field, Input, RadioButtonGroup, Spinner, Stack, TextArea } from '@grafana/ui'; import { validationSrv } from 'app/features/manage-dashboards/services/ValidationSrv'; -import { - RepositorySpec, - useCreateRepositoryFilesWithPathMutation, - useGetRepositoryQuery, -} from 'app/features/provisioning/api'; +import { useCreateRepositoryFilesWithPathMutation, useGetRepositoryQuery } from 'app/features/provisioning/api'; +import { PROVISIONING_URL } from 'app/features/provisioning/constants'; import { usePullRequestParam } from 'app/features/provisioning/hooks'; import { WorkflowOption } from 'app/features/provisioning/types'; import { validateBranchName } from 'app/features/provisioning/utils/git'; import { FolderDTO } from '../../../types'; -import { AnnoKeySourcePath } from '../../apiserver/types'; +import { AnnoKeySourcePath, Resource } from '../../apiserver/types'; import { getDefaultWorkflow, getWorkflowOptions } from '../../dashboard-scene/saving/provisioned/defaults'; import { useGetFolderQuery } from '../../folders/api'; @@ -45,6 +43,7 @@ export function NewProvisionedFolderForm({ onSubmit, onCancel, parentFolder }: P const repositoryName = parentFolder.repository?.name; const query = useGetRepositoryQuery(repositoryName ? { name: repositoryName } : skipToken); const prURL = usePullRequestParam(); + const navigate = useNavigate(); const [create, request] = useCreateRepositoryFilesWithPathMutation(); // Get k8s folder data, necessary to get parent folder path @@ -67,7 +66,6 @@ export function NewProvisionedFolderForm({ onSubmit, onCancel, parentFolder }: P } = useForm({ defaultValues: { ...initialFormValues, workflow: getDefaultWorkflow(repositoryConfig) } }); const [workflow, ref] = watch(['workflow', 'ref']); - const prLink = getPRLink(repositoryConfig, ref); useEffect(() => { setValue('workflow', getDefaultWorkflow(repositoryConfig)); @@ -77,21 +75,40 @@ export function NewProvisionedFolderForm({ onSubmit, onCancel, parentFolder }: P const appEvents = getAppEvents(); if (request.isSuccess) { onSubmit(); - if (workflow === 'branch' && prLink) { - locationService.partial({ prLink }); - } else { - appEvents.publish({ - type: AppEvents.alertSuccess.name, - payload: ['Folder created successfully'], - }); + + appEvents.publish({ + type: AppEvents.alertSuccess.name, + payload: ['Folder created successfully'], + }); + + const folder = request.data.resource?.upsert as Resource; + if (folder?.metadata?.name) { + navigate(`/dashboards/f/${folder?.metadata?.name}/`); + return; } + + let url = `${PROVISIONING_URL}/${repositoryName}/file/${request.data.path}`; + if (request.data.ref?.length) { + url += '?ref=' + request.data.ref; + } + navigate(url); } else if (request.isError) { appEvents.publish({ type: AppEvents.alertError.name, payload: ['Error creating folder', request.error], }); } - }, [request.isSuccess, request.isError, request.error, onSubmit, ref, prLink, workflow]); + }, [ + request.isSuccess, + request.isError, + request.error, + onSubmit, + ref, + request.data, + workflow, + navigate, + repositoryName, + ]); if (query.isLoading || folderQuery.isLoading) { return ; @@ -229,11 +246,3 @@ const BranchValidationError = () => { ); }; - -function getPRLink(spec?: RepositorySpec, ref?: string) { - const githubSpec = spec?.type === 'github' ? spec.github : undefined; - if (!githubSpec || !spec?.workflows.includes('branch')) { - return ''; - } - return `${githubSpec.url}/compare/${githubSpec.branch}...${ref}?quick_pull=1&labels=grafana`; -} From 11a95a0b80bac0229404d0096c4c4782a763c42a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 11 Mar 2025 09:07:58 +0300 Subject: [PATCH 23/63] Update dependency prismjs to v1.30.0 [SECURITY] (#101915) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- packages/grafana-prometheus/package.json | 2 +- packages/grafana-ui/package.json | 2 +- .../datasource/azuremonitor/package.json | 2 +- .../datasource/cloud-monitoring/package.json | 2 +- .../grafana-pyroscope-datasource/package.json | 2 +- .../app/plugins/datasource/tempo/package.json | 2 +- yarn.lock | 23 ++++++++++++------- 8 files changed, 22 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 52da476b137..591bdddd3ea 100644 --- a/package.json +++ b/package.json @@ -365,7 +365,7 @@ "ol": "7.4.0", "ol-ext": "4.0.26", "pluralize": "^8.0.0", - "prismjs": "1.29.0", + "prismjs": "1.30.0", "rc-slider": "11.1.8", "rc-tree": "5.13.0", "re-resizable": "6.10.3", diff --git a/packages/grafana-prometheus/package.json b/packages/grafana-prometheus/package.json index 59690be5c05..bd1378e8870 100644 --- a/packages/grafana-prometheus/package.json +++ b/packages/grafana-prometheus/package.json @@ -64,7 +64,7 @@ "moment-timezone": "0.5.47", "monaco-promql": "1.7.4", "pluralize": "8.0.0", - "prismjs": "1.29.0", + "prismjs": "1.30.0", "react-highlight-words": "0.21.0", "react-use": "17.6.0", "react-window": "1.8.11", diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index 4b51ff9386a..3beb518521f 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -82,7 +82,7 @@ "moment": "2.30.1", "monaco-editor": "0.34.1", "ol": "7.4.0", - "prismjs": "1.29.0", + "prismjs": "1.30.0", "rc-cascader": "3.33.0", "rc-drawer": "7.2.0", "rc-picker": "4.9.2", diff --git a/public/app/plugins/datasource/azuremonitor/package.json b/public/app/plugins/datasource/azuremonitor/package.json index 854abbb71e0..c28ed69b662 100644 --- a/public/app/plugins/datasource/azuremonitor/package.json +++ b/public/app/plugins/datasource/azuremonitor/package.json @@ -16,7 +16,7 @@ "immer": "10.1.1", "lodash": "4.17.21", "monaco-editor": "0.34.1", - "prismjs": "1.29.0", + "prismjs": "1.30.0", "react": "18.3.1", "react-dom": "18.3.1", "react-select": "5.10.0", diff --git a/public/app/plugins/datasource/cloud-monitoring/package.json b/public/app/plugins/datasource/cloud-monitoring/package.json index 4b12136a513..d22e00bcc4d 100644 --- a/public/app/plugins/datasource/cloud-monitoring/package.json +++ b/public/app/plugins/datasource/cloud-monitoring/package.json @@ -17,7 +17,7 @@ "immer": "10.1.1", "lodash": "4.17.21", "monaco-editor": "0.34.1", - "prismjs": "1.29.0", + "prismjs": "1.30.0", "react": "18.3.1", "react-dom": "18.3.1", "react-select": "5.10.0", diff --git a/public/app/plugins/datasource/grafana-pyroscope-datasource/package.json b/public/app/plugins/datasource/grafana-pyroscope-datasource/package.json index d75bed9c7ca..1b9d1b831b4 100644 --- a/public/app/plugins/datasource/grafana-pyroscope-datasource/package.json +++ b/public/app/plugins/datasource/grafana-pyroscope-datasource/package.json @@ -12,7 +12,7 @@ "fast-deep-equal": "^3.1.3", "lodash": "4.17.21", "monaco-editor": "0.34.1", - "prismjs": "1.29.0", + "prismjs": "1.30.0", "react": "18.3.1", "react-dom": "18.3.1", "react-use": "17.6.0", diff --git a/public/app/plugins/datasource/tempo/package.json b/public/app/plugins/datasource/tempo/package.json index 1cf120ff959..619a81e8f81 100644 --- a/public/app/plugins/datasource/tempo/package.json +++ b/public/app/plugins/datasource/tempo/package.json @@ -26,7 +26,7 @@ "lodash": "4.17.21", "lru-cache": "11.0.2", "monaco-editor": "0.34.1", - "prismjs": "1.29.0", + "prismjs": "1.30.0", "react": "18.3.1", "react-dom": "18.3.1", "react-select": "5.10.0", diff --git a/yarn.lock b/yarn.lock index a9474b2c206..3171da05a1d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2566,7 +2566,7 @@ __metadata: immer: "npm:10.1.1" lodash: "npm:4.17.21" monaco-editor: "npm:0.34.1" - prismjs: "npm:1.29.0" + prismjs: "npm:1.30.0" react: "npm:18.3.1" react-dom: "npm:18.3.1" react-select: "npm:5.10.0" @@ -2638,7 +2638,7 @@ __metadata: jest: "npm:29.7.0" lodash: "npm:4.17.21" monaco-editor: "npm:0.34.1" - prismjs: "npm:1.29.0" + prismjs: "npm:1.30.0" react: "npm:18.3.1" react-dom: "npm:18.3.1" react-use: "npm:17.6.0" @@ -2858,7 +2858,7 @@ __metadata: immer: "npm:10.1.1" lodash: "npm:4.17.21" monaco-editor: "npm:0.34.1" - prismjs: "npm:1.29.0" + prismjs: "npm:1.30.0" react: "npm:18.3.1" react-dom: "npm:18.3.1" react-select: "npm:5.10.0" @@ -2914,7 +2914,7 @@ __metadata: lodash: "npm:4.17.21" lru-cache: "npm:11.0.2" monaco-editor: "npm:0.34.1" - prismjs: "npm:1.29.0" + prismjs: "npm:1.30.0" react: "npm:18.3.1" react-dom: "npm:18.3.1" react-select: "npm:5.10.0" @@ -3476,7 +3476,7 @@ __metadata: moment-timezone: "npm:0.5.47" monaco-promql: "npm:1.7.4" pluralize: "npm:8.0.0" - prismjs: "npm:1.29.0" + prismjs: "npm:1.30.0" react: "npm:18.3.1" react-dom: "npm:18.3.1" react-highlight-words: "npm:0.21.0" @@ -3889,7 +3889,7 @@ __metadata: moment: "npm:2.30.1" monaco-editor: "npm:0.34.1" ol: "npm:7.4.0" - prismjs: "npm:1.29.0" + prismjs: "npm:1.30.0" process: "npm:^0.11.10" rc-cascader: "npm:3.33.0" rc-drawer: "npm:7.2.0" @@ -18301,7 +18301,7 @@ __metadata: postcss-reporter: "npm:7.1.0" postcss-scss: "npm:4.0.9" prettier: "npm:3.4.2" - prismjs: "npm:1.29.0" + prismjs: "npm:1.30.0" rc-slider: "npm:11.1.8" rc-tree: "npm:5.13.0" re-resizable: "npm:6.10.3" @@ -25194,13 +25194,20 @@ __metadata: languageName: node linkType: hard -"prismjs@npm:1.29.0, prismjs@npm:^1.27.0, prismjs@npm:^1.29.0": +"prismjs@npm:1.29.0": version: 1.29.0 resolution: "prismjs@npm:1.29.0" checksum: 10/2080db382c2dde0cfc7693769e89b501ef1bfc8ff4f8d25c07fd4c37ca31bc443f6133d5b7c145a73309dc396e829ddb7cc18560026d862a887ae08864ef6b07 languageName: node linkType: hard +"prismjs@npm:1.30.0, prismjs@npm:^1.27.0, prismjs@npm:^1.29.0": + version: 1.30.0 + resolution: "prismjs@npm:1.30.0" + checksum: 10/6b48a2439a82e5c6882f48ebc1564c3890e16463ba17ac10c3ad4f62d98dea5b5c915b172b63b83023a70ad4f5d7be3e8a60304420db34a161fae69dd4e3e2da + languageName: node + linkType: hard + "prismjs@npm:~1.27.0": version: 1.27.0 resolution: "prismjs@npm:1.27.0" From fa809ac417b23ee1854721d332c1ec571ce68ccf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Peter=20=C5=A0tibran=C3=BD?= Date: Tue, 11 Mar 2025 09:03:03 +0100 Subject: [PATCH 24/63] Fix more LastInsertId calls (#101892) * Fix more places where LastInsertId is used without proper directive for Spanner. * Fix tests. --- pkg/infra/serverlock/serverlock.go | 4 ++++ pkg/infra/serverlock/serverlock_test.go | 7 ++++--- pkg/services/sqlstore/session/session.go | 9 +++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/pkg/infra/serverlock/serverlock.go b/pkg/infra/serverlock/serverlock.go index 768854f9b06..ea66851c34a 100644 --- a/pkg/infra/serverlock/serverlock.go +++ b/pkg/infra/serverlock/serverlock.go @@ -374,6 +374,10 @@ func (sl *ServerLockService) createLock(ctx context.Context, } lockRow.Id = id } else { + if sl.SQLStore.GetDBType() == migrator.Spanner { + rawSQL += " THEN RETURN id" // Required for successful LastInsertId call. + } + res, err := dbSession.Exec( rawSQL, lockRow.OperationUID, lockRow.LastExecution, 0) diff --git a/pkg/infra/serverlock/serverlock_test.go b/pkg/infra/serverlock/serverlock_test.go index 3c060c0f22e..0205bce3908 100644 --- a/pkg/infra/serverlock/serverlock_test.go +++ b/pkg/infra/serverlock/serverlock_test.go @@ -36,6 +36,7 @@ func TestServerLock(t *testing.T) { first, err := sl.getOrCreate(context.Background(), operationUID) require.NoError(t, err) + require.NotZero(t, first.Id) t.Run("trying to create three new row locks", func(t *testing.T) { expectedLastExecution := first.LastExecution @@ -44,8 +45,8 @@ func TestServerLock(t *testing.T) { for i := 0; i < 3; i++ { latest, err = sl.getOrCreate(context.Background(), operationUID) require.NoError(t, err) - assert.Equal(t, operationUID, first.OperationUID) - assert.Equal(t, int64(1), first.Id) + assert.Equal(t, first.OperationUID, operationUID) + assert.Equal(t, first.Id, latest.Id) } assert.Equal(t, @@ -114,7 +115,7 @@ func TestLockAndRelease(t *testing.T) { affectedRows, err := sess.Insert(&lock) require.NoError(t, err) require.Equal(t, int64(1), affectedRows) - require.Equal(t, int64(1), lock.Id) + require.NotZero(t, lock.Id) return nil }) require.NoError(t, err) diff --git a/pkg/services/sqlstore/session/session.go b/pkg/services/sqlstore/session/session.go index b585925c753..d1f79d6f294 100644 --- a/pkg/services/sqlstore/session/session.go +++ b/pkg/services/sqlstore/session/session.go @@ -101,19 +101,20 @@ func (gtx *SessionTx) ExecWithReturningId(ctx context.Context, query string, arg } func execWithReturningId(ctx context.Context, driverName string, query string, sess Session, args ...any) (int64, error) { - supported := false var id int64 if driverName == "postgres" { query = fmt.Sprintf("%s RETURNING id", query) - supported = true - } - if supported { err := sess.Get(ctx, &id, query, args...) if err != nil { return id, err } return id, nil } else { + if driverName == "spanner" { + // LastInsertId requires THEN RETURN directive. + query = fmt.Sprintf("%s THEN RETURN id", query) + } + res, err := sess.Exec(ctx, query, args...) if err != nil { return id, err From 7ecad55bffbc8aad9ed6cbedb4ac3bec666ef8c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 11 Mar 2025 09:16:29 +0100 Subject: [PATCH 25/63] Tabs: Reduce active border from 4 px to 2px (#101888) * Tabs: Reduce active border from 4 to 2px * css fixes --- .../src/themes/createComponents.ts | 4 +- .../TabbedContainer/TabbedContainer.tsx | 26 ++--- .../grafana-ui/src/components/Tabs/Tab.tsx | 6 +- .../src/components/Tabs/TabsBar.tsx | 3 +- .../scene/layout-tabs/TabItemRenderer.tsx | 100 +++--------------- .../layout-tabs/TabsLayoutManagerRenderer.tsx | 3 +- 6 files changed, 33 insertions(+), 109 deletions(-) diff --git a/packages/grafana-data/src/themes/createComponents.ts b/packages/grafana-data/src/themes/createComponents.ts index e810a94b86e..6421229640b 100644 --- a/packages/grafana-data/src/themes/createComponents.ts +++ b/packages/grafana-data/src/themes/createComponents.ts @@ -43,9 +43,6 @@ export interface ThemeComponents { sidemenu: { width: number; }; - menuTabs: { - height: number; - }; horizontalDrawer: { defaultHeight: number; }; @@ -96,6 +93,7 @@ export function createComponents(colors: ThemeColors, shadows: ThemeShadows): Th sidemenu: { width: 57, }, + // @ts-expect-error (added here to not crash plugins that might use it) menuTabs: { height: 5, }, diff --git a/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx b/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx index 4bc11a81e5c..5e1cb77957d 100644 --- a/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx +++ b/packages/grafana-ui/src/components/TabbedContainer/TabbedContainer.tsx @@ -6,8 +6,9 @@ import { SelectableValue, GrafanaTheme2 } from '@grafana/data'; import { IconButton } from '../../components/IconButton/IconButton'; import { TabsBar, Tab, TabContent } from '../../components/Tabs'; -import { useStyles2, useTheme2 } from '../../themes'; +import { useStyles2 } from '../../themes'; import { IconName } from '../../types/icon'; +import { Box } from '../Layout/Box/Box'; import { ScrollContainer } from '../ScrollContainer/ScrollContainer'; export interface TabConfig { @@ -28,14 +29,11 @@ export interface TabbedContainerProps { export function TabbedContainer({ tabs, defaultTab, closeIconTooltip, onClose, testId }: TabbedContainerProps) { const [activeTab, setActiveTab] = useState(tabs.some((tab) => tab.value === defaultTab) ? defaultTab : tabs[0].value); const styles = useStyles2(getStyles); - const theme = useTheme2(); const onSelectTab = (item: SelectableValue) => { setActiveTab(item.value!); }; - const autoHeight = `calc(100% - (${theme.spacing(theme.components.menuTabs.height)} + ${theme.spacing(1)}))`; - return (
@@ -48,9 +46,11 @@ export function TabbedContainer({ tabs, defaultTab, closeIconTooltip, onClose, t icon={t.icon} /> ))} - + + + - + {tabs.find((t) => t.value === activeTab)?.content}
@@ -60,21 +60,17 @@ export function TabbedContainer({ tabs, defaultTab, closeIconTooltip, onClose, t const getStyles = (theme: GrafanaTheme2) => ({ container: css({ height: '100%', + display: 'flex', + flexDirection: 'column', + flex: '1 1 0', + minHeight: 0, }), tabContent: css({ padding: theme.spacing(2), backgroundColor: theme.colors.background.primary, - height: `100%`, - }), - close: css({ - position: 'absolute', - right: '16px', - top: '5px', - cursor: 'pointer', - fontSize: theme.typography.size.lg, }), tabs: css({ - paddingTop: theme.spacing(1), + paddingTop: theme.spacing(0.5), borderColor: theme.colors.border.weak, ul: { marginLeft: theme.spacing(2), diff --git a/packages/grafana-ui/src/components/Tabs/Tab.tsx b/packages/grafana-ui/src/components/Tabs/Tab.tsx index e866fb4d242..edbe71c965c 100644 --- a/packages/grafana-ui/src/components/Tabs/Tab.tsx +++ b/packages/grafana-ui/src/components/Tabs/Tab.tsx @@ -92,11 +92,11 @@ const getStyles = (theme: GrafanaTheme2) => { position: 'relative', display: 'flex', whiteSpace: 'nowrap', - padding: theme.spacing(0.5), + padding: theme.spacing(0, 0.5), }), link: css({ color: theme.colors.text.secondary, - padding: theme.spacing(1, 1.5, 0.5), + padding: theme.spacing(1, 1.5, 1), borderRadius: theme.shape.radius.default, display: 'block', @@ -114,7 +114,7 @@ const getStyles = (theme: GrafanaTheme2) => { position: 'absolute', left: 0, right: 0, - height: '4px', + height: '2px', borderRadius: theme.shape.radius.default, bottom: 0, }, diff --git a/packages/grafana-ui/src/components/Tabs/TabsBar.tsx b/packages/grafana-ui/src/components/Tabs/TabsBar.tsx index d5d43c51cbd..7ebfaf20c03 100644 --- a/packages/grafana-ui/src/components/Tabs/TabsBar.tsx +++ b/packages/grafana-ui/src/components/Tabs/TabsBar.tsx @@ -36,8 +36,7 @@ const getStyles = (theme: GrafanaTheme2) => ({ tabs: css({ position: 'relative', display: 'flex', - height: theme.spacing(theme.components.menuTabs.height), - alignItems: 'stretch', + alignItems: 'center', }), }); diff --git a/public/app/features/dashboard-scene/scene/layout-tabs/TabItemRenderer.tsx b/public/app/features/dashboard-scene/scene/layout-tabs/TabItemRenderer.tsx index 52f12ffdc7f..69dca7748f1 100644 --- a/public/app/features/dashboard-scene/scene/layout-tabs/TabItemRenderer.tsx +++ b/public/app/features/dashboard-scene/scene/layout-tabs/TabItemRenderer.tsx @@ -1,11 +1,9 @@ -import { css, cx } from '@emotion/css'; +import { cx } from '@emotion/css'; import { useLocation } from 'react-router'; -import { GrafanaTheme2, locationUtil, textUtil } from '@grafana/data'; +import { locationUtil, textUtil } from '@grafana/data'; import { SceneComponentProps, sceneGraph } from '@grafana/scenes'; -import { clearButtonStyles, useElementSelection, useStyles2 } from '@grafana/ui'; -// eslint-disable-next-line no-restricted-imports -import { getFocusStyles } from '@grafana/ui/src/themes/mixins'; +import { Tab, useElementSelection } from '@grafana/ui'; import { TabItem } from './TabItem'; @@ -19,87 +17,19 @@ export function TabItemRenderer({ model }: SceneComponentProps) { const isActive = myIndex === currentTabIndex; const location = useLocation(); const href = textUtil.sanitize(locationUtil.getUrlForPartial(location, { tab: myIndex })); - const styles = useStyles2(getStyles); - const clearStyles = useStyles2(clearButtonStyles); return ( - <> -
- + ); } - -function getStyles(theme: GrafanaTheme2) { - return { - container: css({ - listStyle: 'none', - position: 'relative', - display: 'flex', - whiteSpace: 'nowrap', - alignItems: 'center', - }), - checkboxWrapper: css({ - paddingLeft: theme.spacing(1), - }), - label: css({ - color: theme.colors.text.secondary, - padding: theme.spacing(1, 2, 0.5), - borderRadius: theme.shape.radius.default, - userSelect: 'none', - - display: 'block', - height: '100%', - - svg: { - marginRight: theme.spacing(1), - }, - - '&:focus-visible': getFocusStyles(theme), - - '&::before': { - display: 'block', - content: '" "', - position: 'absolute', - left: 0, - right: 0, - height: '4px', - borderRadius: theme.shape.radius.default, - bottom: 0, - }, - }), - labelNotActive: css({ - '&:hover, &:focus': { - color: theme.colors.text.primary, - - '&::before': { - backgroundColor: theme.colors.action.hover, - }, - }, - }), - labelActive: css({ - color: theme.colors.text.primary, - overflow: 'hidden', - - '&::before': { - backgroundImage: theme.colors.gradients.brandHorizontal, - }, - }), - }; -} diff --git a/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManagerRenderer.tsx b/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManagerRenderer.tsx index 8a9e5a6a8f6..624b772db37 100644 --- a/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManagerRenderer.tsx +++ b/public/app/features/dashboard-scene/scene/layout-tabs/TabsLayoutManagerRenderer.tsx @@ -60,12 +60,13 @@ const getStyles = (theme: GrafanaTheme2) => ({ overflowX: 'auto', overflowY: 'hidden', paddingInline: theme.spacing(0.125), + paddingTop: '1px', }), tabContentContainer: css({ backgroundColor: 'transparent', display: 'flex', flex: 1, minHeight: 0, - padding: '2px 2px 0 2px', + paddingTop: theme.spacing(1), }), }); From f535d89efb6f9be877fbbbb24085c92fa01ada83 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Tue, 11 Mar 2025 11:23:49 +0300 Subject: [PATCH 26/63] fixed folder issue --- pkg/registry/apis/provisioning/jobs/sync/worker.go | 2 ++ pkg/registry/apis/provisioning/resources/folders.go | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/pkg/registry/apis/provisioning/jobs/sync/worker.go b/pkg/registry/apis/provisioning/jobs/sync/worker.go index 170fe9cd833..5d51f1f1e67 100644 --- a/pkg/registry/apis/provisioning/jobs/sync/worker.go +++ b/pkg/registry/apis/provisioning/jobs/sync/worker.go @@ -483,6 +483,8 @@ func (r *syncJob) client(kind string) (dynamic.ResourceInterface, error) { switch kind { case dashboard.GROUP, dashboard.DASHBOARD_RESOURCE, "Dashboard": return r.dashboards, nil + case folders.GROUP, folders.RESOURCE, "Folder": + return r.folders.Client(), nil } return nil, fmt.Errorf("unsupported resource: %s", kind) } diff --git a/pkg/registry/apis/provisioning/resources/folders.go b/pkg/registry/apis/provisioning/resources/folders.go index d519e30273c..9574f097956 100644 --- a/pkg/registry/apis/provisioning/resources/folders.go +++ b/pkg/registry/apis/provisioning/resources/folders.go @@ -30,6 +30,10 @@ func NewFolderManager(repo repository.Repository, client dynamic.ResourceInterfa } } +func (fm *FolderManager) Client() dynamic.ResourceInterface { + return fm.client +} + // EnsureFoldersExist creates the folder structure in the cluster. func (fm *FolderManager) EnsureFolderPathExist(ctx context.Context, filePath string) (parent string, err error) { if filePath == "" || filePath == "/" || filePath == "." || filePath == "./" { From 14ad1dec3828e9b446fedbaf88d16061daecacea Mon Sep 17 00:00:00 2001 From: Carl Bergquist Date: Tue, 11 Mar 2025 10:12:58 +0100 Subject: [PATCH 27/63] conf: hides scope feature toggles from docs (#101913) Signed-off-by: bergquist --- .../feature-toggles/index.md | 1 - pkg/services/featuremgmt/registry.go | 24 +++++++++++-------- pkg/services/featuremgmt/toggles_gen.json | 15 ++++++++---- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index fbc2e986f46..66ca24087ad 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -60,7 +60,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general- | `logRowsPopoverMenu` | Enable filtering menu displayed when text of a log line is selected | Yes | | `lokiQueryHints` | Enables query hints for Loki | Yes | | `alertingQueryOptimization` | Optimizes eligible queries in order to reduce load on datasources | | -| `promQLScope` | In-development feature that will allow injection of labels into prometheus queries. | Yes | | `groupToNestedTableTransformation` | Enables the group to nested table transformation | Yes | | `newPDFRendering` | New implementation for the dashboard-to-PDF rendering | Yes | | `tlsMemcached` | Use TLS-enabled memcached in the enterprise caching feature | Yes | diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index dfb8405c2ea..45080db02f1 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -983,18 +983,22 @@ var ( Expression: "false", }, { - Name: "promQLScope", - Description: "In-development feature that will allow injection of labels into prometheus queries.", - Stage: FeatureStageGeneralAvailability, - Owner: grafanaOSSBigTent, - Expression: "true", + Name: "promQLScope", + Description: "In-development feature that will allow injection of labels into prometheus queries.", + Stage: FeatureStageGeneralAvailability, + Owner: grafanaOSSBigTent, + Expression: "true", + HideFromDocs: true, + HideFromAdminPage: true, }, { - Name: "logQLScope", - Description: "In-development feature that will allow injection of labels into loki queries.", - Stage: FeatureStagePrivatePreview, - Owner: grafanaObservabilityLogsSquad, - Expression: "false", + Name: "logQLScope", + Description: "In-development feature that will allow injection of labels into loki queries.", + Stage: FeatureStagePrivatePreview, + Owner: grafanaObservabilityLogsSquad, + Expression: "false", + HideFromDocs: true, + HideFromAdminPage: true, }, { Name: "sqlExpressions", diff --git a/pkg/services/featuremgmt/toggles_gen.json b/pkg/services/featuremgmt/toggles_gen.json index b42c54bc438..ac910ee0efd 100644 --- a/pkg/services/featuremgmt/toggles_gen.json +++ b/pkg/services/featuremgmt/toggles_gen.json @@ -2417,13 +2417,18 @@ { "metadata": { "name": "logQLScope", - "resourceVersion": "1730842404843", - "creationTimestamp": "2024-11-11T11:53:24Z" + "resourceVersion": "1741643492217", + "creationTimestamp": "2024-11-11T11:53:24Z", + "annotations": { + "grafana.app/updatedTimestamp": "2025-03-10 21:51:32.217697 +0000 UTC" + } }, "spec": { "description": "In-development feature that will allow injection of labels into loki queries.", "stage": "privatePreview", "codeowner": "@grafana/observability-logs", + "hideFromAdminPage": true, + "hideFromDocs": true, "expression": "false" } }, @@ -3262,16 +3267,18 @@ { "metadata": { "name": "promQLScope", - "resourceVersion": "1735845919509", + "resourceVersion": "1741643492217", "creationTimestamp": "2024-01-29T20:22:17Z", "annotations": { - "grafana.app/updatedTimestamp": "2025-01-02 19:25:19.509884 +0000 UTC" + "grafana.app/updatedTimestamp": "2025-03-10 21:51:32.217697 +0000 UTC" } }, "spec": { "description": "In-development feature that will allow injection of labels into prometheus queries.", "stage": "GA", "codeowner": "@grafana/oss-big-tent", + "hideFromAdminPage": true, + "hideFromDocs": true, "expression": "true" } }, From dd5db2312364e9d13cbc070dcccd732e58b97d30 Mon Sep 17 00:00:00 2001 From: Sam Jewell <2903904+samjewell@users.noreply.github.com> Date: Tue, 11 Mar 2025 09:59:23 +0000 Subject: [PATCH 28/63] SQL Expressions: Update comment for flag definition (#101919) Update comment for SQL Expressions flag definition --- .../setup-grafana/configure-grafana/feature-toggles/index.md | 2 +- pkg/services/featuremgmt/registry.go | 2 +- pkg/services/featuremgmt/toggles_gen.go | 2 +- pkg/services/featuremgmt/toggles_gen.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index 66ca24087ad..48d57b65263 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -183,7 +183,7 @@ Experimental features might be changed or removed without prior notice. | `kubernetesFeatureToggles` | Use the kubernetes API for feature toggle management in the frontend | | `newFolderPicker` | Enables the nested folder picker without having nested folders enabled | | `scopeApi` | In-development feature flag for the scope api using the app platform. | -| `sqlExpressions` | Enables using SQL and DuckDB functions as Expressions. | +| `sqlExpressions` | Enables SQL Expressions, which can execute SQL queries against data source results. | | `nodeGraphDotLayout` | Changed the layout algorithm for the node graph | | `kubernetesAggregator` | Enable grafana's embedded kube-aggregator | | `expressionParser` | Enable new expression parser | diff --git a/pkg/services/featuremgmt/registry.go b/pkg/services/featuremgmt/registry.go index 45080db02f1..c42f344f4a3 100644 --- a/pkg/services/featuremgmt/registry.go +++ b/pkg/services/featuremgmt/registry.go @@ -1002,7 +1002,7 @@ var ( }, { Name: "sqlExpressions", - Description: "Enables using SQL and DuckDB functions as Expressions.", + Description: "Enables SQL Expressions, which can execute SQL queries against data source results.", Stage: FeatureStageExperimental, FrontendOnly: false, Owner: grafanaDatasourcesCoreServicesSquad, diff --git a/pkg/services/featuremgmt/toggles_gen.go b/pkg/services/featuremgmt/toggles_gen.go index d9dcfd8603a..739f826d187 100644 --- a/pkg/services/featuremgmt/toggles_gen.go +++ b/pkg/services/featuremgmt/toggles_gen.go @@ -536,7 +536,7 @@ const ( FlagLogQLScope = "logQLScope" // FlagSqlExpressions - // Enables using SQL and DuckDB functions as Expressions. + // Enables SQL Expressions, which can execute SQL queries against data source results. FlagSqlExpressions = "sqlExpressions" // FlagNodeGraphDotLayout diff --git a/pkg/services/featuremgmt/toggles_gen.json b/pkg/services/featuremgmt/toggles_gen.json index ac910ee0efd..d4685e9017b 100644 --- a/pkg/services/featuremgmt/toggles_gen.json +++ b/pkg/services/featuremgmt/toggles_gen.json @@ -3816,7 +3816,7 @@ } }, "spec": { - "description": "Enables using SQL and DuckDB functions as Expressions.", + "description": "Enables SQL Expressions, which can execute SQL queries against data source results.", "stage": "experimental", "codeowner": "@grafana/grafana-datasources-core-services" } From da25d97ffde0d9af934b10cdc3e5ac4e1e3e8101 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Fern=C3=A1ndez?= Date: Tue, 11 Mar 2025 10:59:55 +0100 Subject: [PATCH 29/63] AutoSaveField: Change the story to use `Combobox` instead of `Select` (#101922) --- .../AutoSaveField/AutoSaveField.story.tsx | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/packages/grafana-ui/src/components/AutoSaveField/AutoSaveField.story.tsx b/packages/grafana-ui/src/components/AutoSaveField/AutoSaveField.story.tsx index 7e5d0f911d8..1f033fcf69c 100644 --- a/packages/grafana-ui/src/components/AutoSaveField/AutoSaveField.story.tsx +++ b/packages/grafana-ui/src/components/AutoSaveField/AutoSaveField.story.tsx @@ -1,10 +1,10 @@ import { StoryFn, Meta } from '@storybook/react'; import { useState } from 'react'; +import { Combobox } from '../Combobox/Combobox'; import { Checkbox } from '../Forms/Checkbox'; import { RadioButtonGroup } from '../Forms/RadioButtonGroup/RadioButtonGroup'; import { Input } from '../Input/Input'; -import { Select } from '../Select/Select'; import { Switch } from '../Switch/Switch'; import { TextArea } from '../TextArea/TextArea'; @@ -97,11 +97,12 @@ Basic.args = { }; export const AllComponents: StoryFn = (args) => { - const [selected, setSelected] = useState(''); - const [checkBoxTest, setCheckBoxTest] = useState(false); - const [textAreaValue, setTextAreaValue] = useState(''); const [inputTextValue, setInputTextValue] = useState(''); - const [switchTest, setSwitchTest] = useState(false); + const [comoboboxValue, setComboboxValue] = useState(''); + const [radioButtonValue, setRadioButtonValue] = useState(''); + const [checkBoxValue, setCheckBoxValue] = useState(false); + const [textAreaValue, setTextAreaValue] = useState(''); + const [switchValue, setSwitchValue] = useState(false); return (
@@ -117,13 +118,14 @@ export const AllComponents: StoryFn = (args) => { /> )} - + {(onChange) => ( - 0 && !isDisabled ? ( + scopes.length > 0 && !disabled ? ( ) : undefined } - onMouseOver={() => setIsTooltipVisible(true)} - onMouseOut={() => setIsTooltipVisible(false)} + onMouseOver={() => setTooltipVisible(true)} + onMouseOut={() => setTooltipVisible(false)} onClick={() => { - if (!isDisabled) { + if (!disabled) { onInputClick(); } }} /> ), - [isDisabled, isLoading, onInputClick, onRemoveAllClick, scopes, scopesTitles] + [disabled, loading, onInputClick, onRemoveAllClick, scopes, scopesTitles] ); return ( - + {input} ); diff --git a/public/app/features/scopes/selector/ScopesSelector.tsx b/public/app/features/scopes/selector/ScopesSelector.tsx new file mode 100644 index 00000000000..002a9ed73fd --- /dev/null +++ b/public/app/features/scopes/selector/ScopesSelector.tsx @@ -0,0 +1,129 @@ +import { css } from '@emotion/css'; +import { useObservable } from 'react-use'; +import { Observable } from 'rxjs'; + +import { GrafanaTheme2 } from '@grafana/data'; +import { useScopes } from '@grafana/runtime'; +import { Button, Drawer, IconButton, Spinner, useStyles2 } from '@grafana/ui'; +import { useGrafana } from 'app/core/context/GrafanaContext'; +import { t, Trans } from 'app/core/internationalization'; + +import { ScopesInput } from './ScopesInput'; +import { ScopesSelectorService } from './ScopesSelectorService'; +import { ScopesTree } from './ScopesTree'; + +export const ScopesSelector = () => { + const { chrome } = useGrafana(); + const chromeState = chrome.useState(); + const menuDockedAndOpen = !chromeState.chromeless && chromeState.megaMenuDocked && chromeState.megaMenuOpen; + const styles = useStyles2(getStyles, menuDockedAndOpen); + const scopes = useScopes(); + + const scopesSelectorService = ScopesSelectorService.instance; + + useObservable(scopesSelectorService?.stateObservable ?? new Observable(), scopesSelectorService?.state); + + if (!scopes || !scopesSelectorService || !scopes.state.enabled) { + return null; + } + + const { readOnly, drawerOpened, loading } = scopes.state; + const { nodes, selectedScopes, opened, loadingNodeName, treeScopes } = scopesSelectorService.state; + const { toggleDrawer, open, removeAllScopes, closeAndApply, closeAndReset, updateNode, toggleNodeSelect } = + scopesSelectorService; + + const dashboardsIconLabel = readOnly + ? t('scopes.dashboards.toggle.disabled', 'Suggested dashboards list is disabled due to read only mode') + : drawerOpened + ? t('scopes.dashboards.toggle.collapse', 'Collapse suggested dashboards list') + : t('scopes.dashboards.toggle..expand', 'Expand suggested dashboards list'); + + return ( +
+ + + + + {opened && ( + +
+
+ {loading ? ( + + ) : ( + + )} +
+ +
+ + +
+
+
+ )} +
+ ); +}; + +const getStyles = (theme: GrafanaTheme2, menuDockedAndOpen: boolean) => { + return { + container: css({ + display: 'flex', + flexDirection: 'row', + paddingLeft: menuDockedAndOpen ? theme.spacing(2) : 'unset', + }), + dashboards: css({ + color: theme.colors.text.secondary, + marginRight: theme.spacing(2), + + '&:hover': css({ + color: theme.colors.text.primary, + }), + }), + drawerContainer: css({ + display: 'flex', + flexDirection: 'column', + height: '100%', + }), + treeContainer: css({ + display: 'flex', + flexDirection: 'column', + maxHeight: '100%', + overflowY: 'hidden', + // Fix for top level search outline overflow due to scrollbars + paddingLeft: theme.spacing(0.5), + }), + buttonsContainer: css({ + display: 'flex', + gap: theme.spacing(1), + marginTop: theme.spacing(8), + }), + }; +}; diff --git a/public/app/features/scopes/selector/ScopesSelectorService.ts b/public/app/features/scopes/selector/ScopesSelectorService.ts new file mode 100644 index 00000000000..705145829d3 --- /dev/null +++ b/public/app/features/scopes/selector/ScopesSelectorService.ts @@ -0,0 +1,392 @@ +import { isEqual } from 'lodash'; +import { finalize, from } from 'rxjs'; + +import { Scope, ScopeNode } from '@grafana/data'; +import { config, getBackendSrv } from '@grafana/runtime'; + +import { ScopesService } from '../ScopesService'; +import { ScopesServiceBase } from '../ScopesServiceBase'; +import { ScopesDashboardsService } from '../dashboards/ScopesDashboardsService'; + +import { NodeReason, NodesMap, SelectedScope, TreeScope } from './types'; + +interface ScopesSelectorServiceState { + opened: boolean; + loadingNodeName: string | undefined; + nodes: NodesMap; + selectedScopes: SelectedScope[]; + treeScopes: TreeScope[]; +} + +export class ScopesSelectorService extends ScopesServiceBase { + static #instance: ScopesSelectorService | undefined = undefined; + + private _scopesCache = new Map>(); + + private constructor() { + super({ + opened: false, + loadingNodeName: undefined, + nodes: { + '': { + name: '', + reason: NodeReason.Result, + nodeType: 'container', + title: '', + expandable: true, + selectable: false, + expanded: true, + query: '', + nodes: {}, + }, + }, + selectedScopes: [], + treeScopes: [], + }); + } + + public static get instance(): ScopesSelectorService | undefined { + if (!ScopesSelectorService.#instance && config.featureToggles.scopeFilters) { + ScopesSelectorService.#instance = new ScopesSelectorService(); + } + + return ScopesSelectorService.#instance; + } + + public updateNode = async (path: string[], expanded: boolean, query: string) => { + this._fetchSub?.unsubscribe(); + + let nodes = { ...this.state.nodes }; + let currentLevel: NodesMap = nodes; + + for (let idx = 0; idx < path.length - 1; idx++) { + currentLevel = currentLevel[path[idx]].nodes; + } + + const loadingNodeName = path[path.length - 1]; + const currentNode = currentLevel[loadingNodeName]; + + const differentQuery = currentNode.query !== query; + + currentNode.expanded = expanded; + currentNode.query = query; + + if (expanded || differentQuery) { + this.updateState({ nodes, loadingNodeName }); + + this._fetchSub = from(this.fetchNodeApi(loadingNodeName, query)) + .pipe( + finalize(() => { + this.updateState({ loadingNodeName: undefined }); + }) + ) + .subscribe((childNodes) => { + const [selectedScopes, treeScopes] = this.getScopesAndTreeScopesWithPaths( + this.state.selectedScopes, + this.state.treeScopes, + path, + childNodes + ); + + const persistedNodes = treeScopes + .map(({ path }) => path[path.length - 1]) + .filter((nodeName) => nodeName in currentNode.nodes && !(nodeName in childNodes)) + .reduce((acc, nodeName) => { + acc[nodeName] = { + ...currentNode.nodes[nodeName], + reason: NodeReason.Persisted, + }; + + return acc; + }, {}); + + currentNode.nodes = { ...persistedNodes, ...childNodes }; + + this.updateState({ nodes, selectedScopes, treeScopes }); + + this._fetchSub?.unsubscribe(); + }); + } else { + this.updateState({ nodes, loadingNodeName: undefined }); + } + }; + + public toggleNodeSelect = (path: string[]) => { + let treeScopes = [...this.state.treeScopes]; + + let parentNode = this.state.nodes['']; + + for (let idx = 1; idx < path.length - 1; idx++) { + parentNode = parentNode.nodes[path[idx]]; + } + + const nodeName = path[path.length - 1]; + const { linkId } = parentNode.nodes[nodeName]; + + const selectedIdx = treeScopes.findIndex(({ scopeName }) => scopeName === linkId); + + if (selectedIdx === -1) { + this.fetchScopeApi(linkId!); + + const selectedFromSameNode = + treeScopes.length === 0 || + Object.values(parentNode.nodes).some(({ linkId }) => linkId === treeScopes[0].scopeName); + + const treeScope = { + scopeName: linkId!, + path, + }; + + this.updateState({ + treeScopes: parentNode?.disableMultiSelect || !selectedFromSameNode ? [treeScope] : [...treeScopes, treeScope], + }); + } else { + treeScopes.splice(selectedIdx, 1); + + this.updateState({ treeScopes }); + } + }; + + public changeScopes = (scopeNames: string[]) => + this.setNewScopes(scopeNames.map((scopeName) => ({ scopeName, path: [] }))); + + public setNewScopes = async (treeScopes = this.state.treeScopes) => { + if (isEqual(treeScopes, this.getTreeScopesFromSelectedScopes(this.state.selectedScopes))) { + return; + } + + let selectedScopes = treeScopes.map(({ scopeName, path }) => ({ + scope: this.getBasicScope(scopeName), + path, + })); + this.updateState({ selectedScopes, treeScopes }); + ScopesService.instance?.setLoading(true); + ScopesDashboardsService.instance?.fetchDashboards(selectedScopes.map(({ scope }) => scope.metadata.name)); + + selectedScopes = await this.fetchScopesApi(treeScopes); + this.updateState({ selectedScopes }); + ScopesService.instance?.setScopes(selectedScopes.map(({ scope }) => scope)); + ScopesService.instance?.setLoading(false); + }; + + public removeAllScopes = () => this.setNewScopes([]); + + public open = async () => { + if (!ScopesService.instance?.state.readOnly) { + if (Object.keys(this.state.nodes[''].nodes).length === 0) { + await this.updateNode([''], true, ''); + } + + let nodes = { ...this.state.nodes }; + + // First close all nodes + nodes = this.closeNodes(nodes); + + // Extract the path of a scope + let path = [...(this.state.selectedScopes[0]?.path ?? ['', ''])]; + path.splice(path.length - 1, 1); + + // Expand the nodes to the selected scope + nodes = this.expandNodes(nodes, path); + + this.updateState({ nodes, opened: true }); + } + }; + + public closeAndReset = () => { + this.updateState({ opened: false, treeScopes: this.getTreeScopesFromSelectedScopes(this.state.selectedScopes) }); + }; + + public closeAndApply = () => { + this.updateState({ opened: false }); + this.setNewScopes(); + }; + + public toggleDrawer = () => ScopesService.instance?.setDrawerOpened(!ScopesService.instance?.state.drawerOpened); + + private closeNodes = (nodes: NodesMap): NodesMap => { + return Object.entries(nodes).reduce((acc, [id, node]) => { + acc[id] = { + ...node, + expanded: false, + nodes: this.closeNodes(node.nodes), + }; + + return acc; + }, {}); + }; + + private expandNodes = (nodes: NodesMap, path: string[]): NodesMap => { + nodes = { ...nodes }; + let currentNodes = nodes; + + for (let i = 0; i < path.length; i++) { + const nodeId = path[i]; + + currentNodes[nodeId] = { + ...currentNodes[nodeId], + expanded: true, + }; + currentNodes = currentNodes[nodeId].nodes; + } + + return nodes; + }; + + private getBasicScope = (name: string): Scope => { + return { + metadata: { name }, + spec: { + filters: [], + title: name, + type: '', + category: '', + description: '', + }, + }; + }; + + private getTreeScopesFromSelectedScopes = (scopes: SelectedScope[]): TreeScope[] => { + return scopes.map(({ scope, path }) => ({ + scopeName: scope.metadata.name, + path, + })); + }; + + // helper func to get the selected/tree scopes together with their paths + // needed to maintain selected scopes in tree for example when navigating + // between categories or when loading scopes from URL to find the scope's path + private getScopesAndTreeScopesWithPaths = ( + selectedScopes: SelectedScope[], + treeScopes: TreeScope[], + path: string[], + childNodes: NodesMap + ): [SelectedScope[], TreeScope[]] => { + const childNodesArr = Object.values(childNodes); + + // Get all scopes without paths + // We use tree scopes as the list is always up to date as opposed to selected scopes which can be outdated + const scopeNamesWithoutPaths = treeScopes.filter(({ path }) => path.length === 0).map(({ scopeName }) => scopeName); + + // We search for the path of each scope name without a path + const scopeNamesWithPaths = scopeNamesWithoutPaths.reduce>((acc, scopeName) => { + const possibleParent = childNodesArr.find((childNode) => childNode.selectable && childNode.linkId === scopeName); + + if (possibleParent) { + acc[scopeName] = [...path, possibleParent.name]; + } + + return acc; + }, {}); + + // Update the paths of the selected scopes based on what we found + const newSelectedScopes = selectedScopes.map((selectedScope) => { + if (selectedScope.path.length > 0) { + return selectedScope; + } + + return { + ...selectedScope, + path: scopeNamesWithPaths[selectedScope.scope.metadata.name] ?? [], + }; + }); + + // Update the paths of the tree scopes based on what we found + const newTreeScopes = treeScopes.map((treeScope) => { + if (treeScope.path.length > 0) { + return treeScope; + } + + return { + ...treeScope, + path: scopeNamesWithPaths[treeScope.scopeName] ?? [], + }; + }); + + return [newSelectedScopes, newTreeScopes]; + }; + + public fetchNodeApi = async (parent: string, query: string): Promise => { + try { + const nodes = + ( + await getBackendSrv().get<{ items: ScopeNode[] }>( + `/apis/${this._apiGroup}/${this._apiVersion}/namespaces/${this._apiNamespace}/find/scope_node_children`, + { parent, query } + ) + )?.items ?? []; + + return nodes.reduce((acc, { metadata: { name }, spec }) => { + acc[name] = { + name, + ...spec, + expandable: spec.nodeType === 'container', + selectable: spec.linkType === 'scope', + expanded: false, + query: '', + reason: NodeReason.Result, + nodes: {}, + }; + return acc; + }, {}); + } catch (err) { + return {}; + } + }; + + public fetchScopeApi = async (name: string): Promise => { + if (this._scopesCache.has(name)) { + return this._scopesCache.get(name)!; + } + + const response = new Promise(async (resolve) => { + const basicScope = this.getBasicScope(name); + + try { + const serverScope = await getBackendSrv().get( + `/apis/${this._apiGroup}/${this._apiVersion}/namespaces/${this._apiNamespace}/scopes/${name}` + ); + + const scope = { + ...basicScope, + ...serverScope, + metadata: { + ...basicScope.metadata, + ...serverScope.metadata, + }, + spec: { + ...basicScope.spec, + ...serverScope.spec, + }, + }; + + resolve(scope); + } catch (err) { + this._scopesCache.delete(name); + + resolve(basicScope); + } + }); + + this._scopesCache.set(name, response); + + return response; + }; + + public fetchScopesApi = async (treeScopes: TreeScope[]): Promise => { + const scopes = await Promise.all(treeScopes.map(({ scopeName }) => this.fetchScopeApi(scopeName))); + + return scopes.reduce((acc, scope, idx) => { + acc.push({ + scope, + path: treeScopes[idx].path, + }); + + return acc; + }, []); + }; + + public reset = () => { + ScopesSelectorService.#instance = undefined; + }; +} diff --git a/public/app/features/scopes/internal/ScopesTree.tsx b/public/app/features/scopes/selector/ScopesTree.tsx similarity index 86% rename from public/app/features/scopes/internal/ScopesTree.tsx rename to public/app/features/scopes/selector/ScopesTree.tsx index d4116f6ba1e..ed37df63729 100644 --- a/public/app/features/scopes/internal/ScopesTree.tsx +++ b/public/app/features/scopes/selector/ScopesTree.tsx @@ -27,11 +27,11 @@ export function ScopesTree({ const nodeId = nodePath[nodePath.length - 1]; const node = nodes[nodeId]; const childNodes = Object.values(node.nodes); - const isNodeLoading = loadingNodeName === nodeId; + const nodeLoading = loadingNodeName === nodeId; const scopeNames = scopes.map(({ scopeName }) => scopeName); - const anyChildExpanded = childNodes.some(({ isExpanded }) => isExpanded); + const anyChildExpanded = childNodes.some(({ expanded }) => expanded); const groupedNodes: Dictionary = useMemo(() => groupBy(childNodes, 'reason'), [childNodes]); - const isLastExpandedNode = !anyChildExpanded && node.isExpanded; + const lastExpandedNode = !anyChildExpanded && node.expanded; return ( <> @@ -42,11 +42,11 @@ export function ScopesTree({ onNodeUpdate={onNodeUpdate} /> - + ; - isLastExpandedNode: boolean; + lastExpandedNode: boolean; loadingNodeName: string | undefined; node: Node; nodePath: string[]; @@ -26,7 +26,7 @@ export interface ScopesTreeItemProps { export function ScopesTreeItem({ anyChildExpanded, groupedNodes, - isLastExpandedNode, + lastExpandedNode, loadingNodeName, node, nodePath, @@ -48,9 +48,9 @@ export function ScopesTreeItem({ const children = (
{nodes.map((childNode) => { - const isSelected = childNode.isSelectable && scopeNames.includes(childNode.linkId!); + const selected = childNode.selectable && scopeNames.includes(childNode.linkId!); - if (anyChildExpanded && !childNode.isExpanded) { + if (anyChildExpanded && !childNode.expanded) { return null; } @@ -62,16 +62,16 @@ export function ScopesTreeItem({
-
- {childNode.isSelectable && !childNode.isExpanded ? ( +
+ {childNode.selectable && !childNode.expanded ? ( node.disableMultiSelect ? ( { @@ -80,7 +80,7 @@ export function ScopesTreeItem({ /> ) : ( { onNodeSelectToggle(childNodePath); @@ -89,18 +89,18 @@ export function ScopesTreeItem({ ) ) : null} - {childNode.isExpandable ? ( + {childNode.expandable ? ( @@ -110,7 +110,7 @@ export function ScopesTreeItem({
- {childNode.isExpanded && ( + {childNode.expanded && ( ); - if (isLastExpandedNode) { + if (lastExpandedNode) { return ( ; } diff --git a/public/app/features/scopes/internal/ScopesTreeSearch.tsx b/public/app/features/scopes/selector/ScopesTreeSearch.tsx similarity index 82% rename from public/app/features/scopes/internal/ScopesTreeSearch.tsx rename to public/app/features/scopes/selector/ScopesTreeSearch.tsx index 273d2fa24b0..f8bc5c071ec 100644 --- a/public/app/features/scopes/internal/ScopesTreeSearch.tsx +++ b/public/app/features/scopes/selector/ScopesTreeSearch.tsx @@ -18,22 +18,22 @@ export interface ScopesTreeSearchProps { export function ScopesTreeSearch({ anyChildExpanded, nodePath, query, onNodeUpdate }: ScopesTreeSearchProps) { const styles = useStyles2(getStyles); - const [inputState, setInputState] = useState<{ value: string; isDirty: boolean }>({ value: query, isDirty: false }); + const [inputState, setInputState] = useState<{ value: string; dirty: boolean }>({ value: query, dirty: false }); useEffect(() => { - if (!inputState.isDirty && inputState.value !== query) { - setInputState({ value: query, isDirty: false }); + if (!inputState.dirty && inputState.value !== query) { + setInputState({ value: query, dirty: false }); } }, [inputState, query]); useDebounce( () => { - if (inputState.isDirty) { + if (inputState.dirty) { onNodeUpdate(nodePath, true, inputState.value); } }, 500, - [inputState.isDirty, inputState.value] + [inputState.dirty, inputState.value] ); if (anyChildExpanded) { @@ -48,7 +48,7 @@ export function ScopesTreeSearch({ anyChildExpanded, nodePath, query, onNodeUpda data-testid="scopes-tree-search" escapeRegex={false} onChange={(value) => { - setInputState({ value, isDirty: true }); + setInputState({ value, dirty: true }); }} /> ); diff --git a/public/app/features/scopes/selector/types.ts b/public/app/features/scopes/selector/types.ts new file mode 100644 index 00000000000..672a6f158b4 --- /dev/null +++ b/public/app/features/scopes/selector/types.ts @@ -0,0 +1,31 @@ +import { Scope, ScopeNodeSpec } from '@grafana/data'; + +export enum NodeReason { + Persisted, + Result, +} + +export interface Node extends ScopeNodeSpec { + name: string; + reason: NodeReason; + expandable: boolean; + selectable: boolean; + expanded: boolean; + query: string; + nodes: NodesMap; +} + +export type NodesMap = Record; + +export interface SelectedScope { + scope: Scope; + path: string[]; +} + +export interface TreeScope { + scopeName: string; + path: string[]; +} + +export type OnNodeUpdate = (path: string[], expanded: boolean, query: string) => void; +export type OnNodeSelectToggle = (path: string[]) => void; diff --git a/public/app/features/scopes/tests/dashboardReload.test.ts b/public/app/features/scopes/tests/dashboardReload.test.ts index 24b07bca51a..7973842c33e 100644 --- a/public/app/features/scopes/tests/dashboardReload.test.ts +++ b/public/app/features/scopes/tests/dashboardReload.test.ts @@ -2,8 +2,7 @@ import { config } from '@grafana/runtime'; import { setDashboardAPI } from 'app/features/dashboard/api/dashboard_api'; import { getDashboardScenePageStateManager } from 'app/features/dashboard-scene/pages/DashboardScenePageStateManager'; -import { clearMocks, enterEditMode, updateMyVar, updateScopes, updateTimeRange } from './utils/actions'; -import { expectDashboardReload, expectNotDashboardReload } from './utils/assertions'; +import { enterEditMode, updateMyVar, updateScopes, updateTimeRange } from './utils/actions'; import { getDatasource, getInstanceSettings, getMock } from './utils/mocks'; import { renderDashboard, resetScenes } from './utils/render'; @@ -17,6 +16,8 @@ jest.mock('@grafana/runtime', () => ({ })); describe('Dashboard reload', () => { + let dashboardReloadSpy: jest.SpyInstance; + beforeAll(() => { config.featureToggles.scopeFilters = true; config.featureToggles.groupByVariable = true; @@ -39,43 +40,45 @@ describe('Dashboard reload', () => { config.featureToggles.reloadDashboardsOnParamsChange = reloadDashboardsOnParamsChange; setDashboardAPI(undefined); - const dashboardScene = renderDashboard({ uid: withUid ? 'dash-1' : undefined }, { reloadOnParamsChange }); + const dashboardScene = await renderDashboard({ uid: withUid ? 'dash-1' : undefined }, { reloadOnParamsChange }); + + dashboardReloadSpy = jest.spyOn(getDashboardScenePageStateManager(), 'reloadDashboard'); if (editMode) { await enterEditMode(dashboardScene); } const shouldReload = reloadDashboardsOnParamsChange && reloadOnParamsChange && withUid && !editMode; + dashboardReloadSpy.mockClear(); await updateTimeRange(dashboardScene); await jest.advanceTimersToNextTimerAsync(); if (!shouldReload) { - expectNotDashboardReload(); + expect(dashboardReloadSpy).not.toHaveBeenCalled(); } else { - expectDashboardReload(); + expect(dashboardReloadSpy).toHaveBeenCalled(); } await updateMyVar(dashboardScene, '2'); await jest.advanceTimersToNextTimerAsync(); if (!shouldReload) { - expectNotDashboardReload(); + expect(dashboardReloadSpy).not.toHaveBeenCalled(); } else { - expectDashboardReload(); + expect(dashboardReloadSpy).toHaveBeenCalled(); } await updateScopes(['grafana']); await jest.advanceTimersToNextTimerAsync(); if (!shouldReload) { - expectNotDashboardReload(); + expect(dashboardReloadSpy).not.toHaveBeenCalled(); } else { - expectDashboardReload(); + expect(dashboardReloadSpy).toHaveBeenCalled(); } getDashboardScenePageStateManager().clearDashboardCache(); getDashboardScenePageStateManager().clearSceneCache(); setDashboardAPI(undefined); - await resetScenes(); - clearMocks(); + await resetScenes([dashboardReloadSpy]); } ); }); diff --git a/public/app/features/scopes/tests/dashboardsList.test.ts b/public/app/features/scopes/tests/dashboardsList.test.ts index 3b5f2fe1885..895337f69d2 100644 --- a/public/app/features/scopes/tests/dashboardsList.test.ts +++ b/public/app/features/scopes/tests/dashboardsList.test.ts @@ -1,5 +1,7 @@ import { config } from '@grafana/runtime'; +import { ScopesDashboardsService } from '../dashboards/ScopesDashboardsService'; + import { clearNotFound, expandDashboardFolder, @@ -21,7 +23,18 @@ import { expectNoDashboardsNoScopes, expectNoDashboardsSearch, } from './utils/assertions'; -import { fetchDashboardsSpy, getDatasource, getInstanceSettings, getMock } from './utils/mocks'; +import { + alternativeDashboardWithRootFolder, + alternativeDashboardWithTwoFolders, + dashboardWithOneFolder, + dashboardWithoutFolder, + dashboardWithRootFolder, + dashboardWithRootFolderAndOtherFolder, + dashboardWithTwoFolders, + getDatasource, + getInstanceSettings, + getMock, +} from './utils/mocks'; import { renderDashboard, resetScenes } from './utils/render'; jest.mock('@grafana/runtime', () => ({ @@ -34,17 +47,20 @@ jest.mock('@grafana/runtime', () => ({ })); describe('Dashboards list', () => { + let fetchDashboardsSpy: jest.SpyInstance; + beforeAll(() => { config.featureToggles.scopeFilters = true; config.featureToggles.groupByVariable = true; }); - beforeEach(() => { - renderDashboard(); + beforeEach(async () => { + await renderDashboard(); + fetchDashboardsSpy = jest.spyOn(ScopesDashboardsService.instance!, 'fetchDashboardsApi'); }); afterEach(async () => { - await resetScenes(); + await resetScenes([fetchDashboardsSpy]); }); it('Opens container and fetches dashboards list when a scope is selected', async () => { @@ -244,14 +260,13 @@ describe('Dashboards list', () => { }); it('Does not show the input when there are no dashboards found for scope', async () => { - await toggleDashboards(); await updateScopes(['cloud']); + await toggleDashboards(); expectNoDashboardsForScope(); expectNoDashboardsSearch(); }); it('Shows the input and a message when there are no dashboards found for filter', async () => { - await toggleDashboards(); await updateScopes(['mimir']); await searchDashboards('unknown'); expectDashboardsSearch(); @@ -260,4 +275,359 @@ describe('Dashboards list', () => { await clearNotFound(); expectDashboardSearchValue(''); }); + + describe('groupDashboards', () => { + it('Assigns dashboards without groups to root folder', () => { + expect(ScopesDashboardsService.instance?.groupDashboards([dashboardWithoutFolder])).toEqual({ + '': { + title: '', + expanded: true, + folders: {}, + dashboards: { + [dashboardWithoutFolder.spec.dashboard]: { + dashboard: dashboardWithoutFolder.spec.dashboard, + dashboardTitle: dashboardWithoutFolder.status.dashboardTitle, + items: [dashboardWithoutFolder], + }, + }, + }, + }); + }); + + it('Assigns dashboards with root group to root folder', () => { + expect(ScopesDashboardsService.instance?.groupDashboards([dashboardWithRootFolder])).toEqual({ + '': { + title: '', + expanded: true, + folders: {}, + dashboards: { + [dashboardWithRootFolder.spec.dashboard]: { + dashboard: dashboardWithRootFolder.spec.dashboard, + dashboardTitle: dashboardWithRootFolder.status.dashboardTitle, + items: [dashboardWithRootFolder], + }, + }, + }, + }); + }); + + it('Merges folders from multiple dashboards', () => { + expect( + ScopesDashboardsService.instance?.groupDashboards([dashboardWithOneFolder, dashboardWithTwoFolders]) + ).toEqual({ + '': { + title: '', + expanded: true, + folders: { + 'Folder 1': { + title: 'Folder 1', + expanded: false, + folders: {}, + dashboards: { + [dashboardWithOneFolder.spec.dashboard]: { + dashboard: dashboardWithOneFolder.spec.dashboard, + dashboardTitle: dashboardWithOneFolder.status.dashboardTitle, + items: [dashboardWithOneFolder], + }, + [dashboardWithTwoFolders.spec.dashboard]: { + dashboard: dashboardWithTwoFolders.spec.dashboard, + dashboardTitle: dashboardWithTwoFolders.status.dashboardTitle, + items: [dashboardWithTwoFolders], + }, + }, + }, + 'Folder 2': { + title: 'Folder 2', + expanded: false, + folders: {}, + dashboards: { + [dashboardWithTwoFolders.spec.dashboard]: { + dashboard: dashboardWithTwoFolders.spec.dashboard, + dashboardTitle: dashboardWithTwoFolders.status.dashboardTitle, + items: [dashboardWithTwoFolders], + }, + }, + }, + }, + dashboards: {}, + }, + }); + }); + + it('Merges scopes from multiple dashboards', () => { + expect( + ScopesDashboardsService.instance?.groupDashboards([dashboardWithTwoFolders, alternativeDashboardWithTwoFolders]) + ).toEqual({ + '': { + title: '', + expanded: true, + folders: { + 'Folder 1': { + title: 'Folder 1', + expanded: false, + folders: {}, + dashboards: { + [dashboardWithTwoFolders.spec.dashboard]: { + dashboard: dashboardWithTwoFolders.spec.dashboard, + dashboardTitle: dashboardWithTwoFolders.status.dashboardTitle, + items: [dashboardWithTwoFolders, alternativeDashboardWithTwoFolders], + }, + }, + }, + 'Folder 2': { + title: 'Folder 2', + expanded: false, + folders: {}, + dashboards: { + [dashboardWithTwoFolders.spec.dashboard]: { + dashboard: dashboardWithTwoFolders.spec.dashboard, + dashboardTitle: dashboardWithTwoFolders.status.dashboardTitle, + items: [dashboardWithTwoFolders, alternativeDashboardWithTwoFolders], + }, + }, + }, + }, + dashboards: {}, + }, + }); + }); + + it('Matches snapshot', () => { + expect( + ScopesDashboardsService.instance?.groupDashboards([ + dashboardWithoutFolder, + dashboardWithOneFolder, + dashboardWithTwoFolders, + alternativeDashboardWithTwoFolders, + dashboardWithRootFolder, + alternativeDashboardWithRootFolder, + dashboardWithRootFolderAndOtherFolder, + ]) + ).toEqual({ + '': { + dashboards: { + [dashboardWithRootFolderAndOtherFolder.spec.dashboard]: { + dashboard: dashboardWithRootFolderAndOtherFolder.spec.dashboard, + dashboardTitle: dashboardWithRootFolderAndOtherFolder.status.dashboardTitle, + items: [dashboardWithRootFolderAndOtherFolder], + }, + [dashboardWithRootFolder.spec.dashboard]: { + dashboard: dashboardWithRootFolder.spec.dashboard, + dashboardTitle: dashboardWithRootFolder.status.dashboardTitle, + items: [dashboardWithRootFolder, alternativeDashboardWithRootFolder], + }, + [dashboardWithoutFolder.spec.dashboard]: { + dashboard: dashboardWithoutFolder.spec.dashboard, + dashboardTitle: dashboardWithoutFolder.status.dashboardTitle, + items: [dashboardWithoutFolder], + }, + }, + folders: { + 'Folder 1': { + dashboards: { + [dashboardWithOneFolder.spec.dashboard]: { + dashboard: dashboardWithOneFolder.spec.dashboard, + dashboardTitle: dashboardWithOneFolder.status.dashboardTitle, + items: [dashboardWithOneFolder], + }, + [dashboardWithTwoFolders.spec.dashboard]: { + dashboard: dashboardWithTwoFolders.spec.dashboard, + dashboardTitle: dashboardWithTwoFolders.status.dashboardTitle, + items: [dashboardWithTwoFolders, alternativeDashboardWithTwoFolders], + }, + }, + folders: {}, + expanded: false, + title: 'Folder 1', + }, + 'Folder 2': { + dashboards: { + [dashboardWithTwoFolders.spec.dashboard]: { + dashboard: dashboardWithTwoFolders.spec.dashboard, + dashboardTitle: dashboardWithTwoFolders.status.dashboardTitle, + items: [dashboardWithTwoFolders, alternativeDashboardWithTwoFolders], + }, + }, + folders: {}, + expanded: false, + title: 'Folder 2', + }, + 'Folder 3': { + dashboards: { + [dashboardWithRootFolderAndOtherFolder.spec.dashboard]: { + dashboard: dashboardWithRootFolderAndOtherFolder.spec.dashboard, + dashboardTitle: dashboardWithRootFolderAndOtherFolder.status.dashboardTitle, + items: [dashboardWithRootFolderAndOtherFolder], + }, + }, + folders: {}, + expanded: false, + title: 'Folder 3', + }, + }, + expanded: true, + title: '', + }, + }); + }); + }); + + describe('filterFolders', () => { + it('Shows folders matching criteria', () => { + expect( + ScopesDashboardsService.instance?.filterFolders( + { + '': { + title: '', + expanded: true, + folders: { + 'Folder 1': { + title: 'Folder 1', + expanded: false, + folders: {}, + dashboards: { + 'Dashboard ID': { + dashboard: 'Dashboard ID', + dashboardTitle: 'Dashboard Title', + items: [], + }, + }, + }, + 'Folder 2': { + title: 'Folder 2', + expanded: true, + folders: {}, + dashboards: { + 'Dashboard ID': { + dashboard: 'Dashboard ID', + dashboardTitle: 'Dashboard Title', + items: [], + }, + }, + }, + }, + dashboards: { + 'Dashboard ID': { + dashboard: 'Dashboard ID', + dashboardTitle: 'Dashboard Title', + items: [], + }, + }, + }, + }, + 'Folder' + ) + ).toEqual({ + '': { + title: '', + expanded: true, + folders: { + 'Folder 1': { + title: 'Folder 1', + expanded: true, + folders: {}, + dashboards: { + 'Dashboard ID': { + dashboard: 'Dashboard ID', + dashboardTitle: 'Dashboard Title', + items: [], + }, + }, + }, + 'Folder 2': { + title: 'Folder 2', + expanded: true, + folders: {}, + dashboards: { + 'Dashboard ID': { + dashboard: 'Dashboard ID', + dashboardTitle: 'Dashboard Title', + items: [], + }, + }, + }, + }, + dashboards: {}, + }, + }); + }); + + it('Shows dashboards matching criteria', () => { + expect( + ScopesDashboardsService.instance?.filterFolders( + { + '': { + title: '', + expanded: true, + folders: { + 'Folder 1': { + title: 'Folder 1', + expanded: false, + folders: {}, + dashboards: { + 'Dashboard ID': { + dashboard: 'Dashboard ID', + dashboardTitle: 'Dashboard Title', + items: [], + }, + }, + }, + 'Folder 2': { + title: 'Folder 2', + expanded: true, + folders: {}, + dashboards: { + 'Random ID': { + dashboard: 'Random ID', + dashboardTitle: 'Random Title', + items: [], + }, + }, + }, + }, + dashboards: { + 'Dashboard ID': { + dashboard: 'Dashboard ID', + dashboardTitle: 'Dashboard Title', + items: [], + }, + 'Random ID': { + dashboard: 'Random ID', + dashboardTitle: 'Random Title', + items: [], + }, + }, + }, + }, + 'dash' + ) + ).toEqual({ + '': { + title: '', + expanded: true, + folders: { + 'Folder 1': { + title: 'Folder 1', + expanded: true, + folders: {}, + dashboards: { + 'Dashboard ID': { + dashboard: 'Dashboard ID', + dashboardTitle: 'Dashboard Title', + items: [], + }, + }, + }, + }, + dashboards: { + 'Dashboard ID': { + dashboard: 'Dashboard ID', + dashboardTitle: 'Dashboard Title', + items: [], + }, + }, + }, + }); + }); + }); }); diff --git a/public/app/features/scopes/tests/featureFlag.test.ts b/public/app/features/scopes/tests/featureFlag.test.ts deleted file mode 100644 index efe209a6f5b..00000000000 --- a/public/app/features/scopes/tests/featureFlag.test.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { config } from '@grafana/runtime'; - -import { scopesSelectorScene } from '../instance'; - -import { getDatasource, getInstanceSettings, getMock } from './utils/mocks'; -import { renderDashboard } from './utils/render'; - -jest.mock('@grafana/runtime', () => ({ - __esModule: true, - ...jest.requireActual('@grafana/runtime'), - useChromeHeaderHeight: jest.fn(), - getBackendSrv: () => ({ get: getMock }), - getDataSourceSrv: () => ({ get: getDatasource, getInstanceSettings }), - usePluginLinks: jest.fn().mockReturnValue({ links: [] }), -})); - -describe('Feature flag off', () => { - beforeAll(() => { - config.featureToggles.scopeFilters = false; - config.featureToggles.groupByVariable = true; - }); - - it('Does not initialize', () => { - renderDashboard(); - expect(scopesSelectorScene).toBeNull(); - }); -}); diff --git a/public/app/features/scopes/tests/selector.test.ts b/public/app/features/scopes/tests/selector.test.ts index 6435de62803..951c6f54b2e 100644 --- a/public/app/features/scopes/tests/selector.test.ts +++ b/public/app/features/scopes/tests/selector.test.ts @@ -1,13 +1,13 @@ import { config } from '@grafana/runtime'; -import { sceneGraph } from '@grafana/scenes'; -import { DashboardScene } from 'app/features/dashboard-scene/scene/DashboardScene'; -import { getClosestScopesFacade } from '../utils'; +import { getDashboardScenePageStateManager } from '../../dashboard-scene/pages/DashboardScenePageStateManager'; +import { ScopesSelectorService } from '../selector/ScopesSelectorService'; import { applyScopes, cancelScopes, openSelector, selectResultCloud, updateScopes } from './utils/actions'; -import { expectNotDashboardReload, expectScopesSelectorValue } from './utils/assertions'; -import { fetchSelectedScopesSpy, getDatasource, getInstanceSettings, getMock, mocksScopes } from './utils/mocks'; +import { expectScopesSelectorValue } from './utils/assertions'; +import { getDatasource, getInstanceSettings, getMock, mocksScopes } from './utils/mocks'; import { renderDashboard, resetScenes } from './utils/render'; +import { getListOfScopes } from './utils/selectors'; jest.mock('@grafana/runtime', () => ({ __esModule: true, @@ -19,19 +19,22 @@ jest.mock('@grafana/runtime', () => ({ })); describe('Selector', () => { - let dashboardScene: DashboardScene; + let fetchSelectedScopesSpy: jest.SpyInstance; + let dashboardReloadSpy: jest.SpyInstance; beforeAll(() => { config.featureToggles.scopeFilters = true; config.featureToggles.groupByVariable = true; }); - beforeEach(() => { - dashboardScene = renderDashboard(); + beforeEach(async () => { + await renderDashboard(); + fetchSelectedScopesSpy = jest.spyOn(ScopesSelectorService.instance!, 'fetchScopesApi'); + dashboardReloadSpy = jest.spyOn(getDashboardScenePageStateManager(), 'reloadDashboard'); }); afterEach(async () => { - await resetScenes(); + await resetScenes([fetchSelectedScopesSpy, dashboardReloadSpy]); }); it('Fetches scope details on save', async () => { @@ -39,9 +42,7 @@ describe('Selector', () => { await selectResultCloud(); await applyScopes(); expect(fetchSelectedScopesSpy).toHaveBeenCalled(); - expect(getClosestScopesFacade(dashboardScene)?.value).toEqual( - mocksScopes.filter(({ metadata: { name } }) => name === 'cloud') - ); + expect(getListOfScopes()).toEqual(mocksScopes.filter(({ metadata: { name } }) => name === 'cloud')); }); it('Does not save the scopes on close', async () => { @@ -49,7 +50,7 @@ describe('Selector', () => { await selectResultCloud(); await cancelScopes(); expect(fetchSelectedScopesSpy).not.toHaveBeenCalled(); - expect(getClosestScopesFacade(dashboardScene)?.value).toEqual([]); + expect(getListOfScopes()).toEqual([]); }); it('Shows selected scopes', async () => { @@ -59,25 +60,6 @@ describe('Selector', () => { it('Does not reload the dashboard on scope change', async () => { await updateScopes(['grafana']); - expectNotDashboardReload(); - }); - - it('Adds scopes to enrichers', async () => { - const queryRunner = sceneGraph.getQueryController(dashboardScene)!; - - await updateScopes(['grafana']); - let scopes = mocksScopes.filter(({ metadata: { name } }) => name === 'grafana'); - expect(dashboardScene.enrichDataRequest(queryRunner).scopes).toEqual(scopes); - expect(dashboardScene.enrichFiltersRequest().scopes).toEqual(scopes); - - await updateScopes(['grafana', 'mimir']); - scopes = mocksScopes.filter(({ metadata: { name } }) => name === 'grafana' || name === 'mimir'); - expect(dashboardScene.enrichDataRequest(queryRunner).scopes).toEqual(scopes); - expect(dashboardScene.enrichFiltersRequest().scopes).toEqual(scopes); - - await updateScopes(['mimir']); - scopes = mocksScopes.filter(({ metadata: { name } }) => name === 'mimir'); - expect(dashboardScene.enrichDataRequest(queryRunner).scopes).toEqual(scopes); - expect(dashboardScene.enrichFiltersRequest().scopes).toEqual(scopes); + expect(dashboardReloadSpy).not.toHaveBeenCalled(); }); }); diff --git a/public/app/features/scopes/tests/tree.test.ts b/public/app/features/scopes/tests/tree.test.ts index 983393ca204..186e6fe06f0 100644 --- a/public/app/features/scopes/tests/tree.test.ts +++ b/public/app/features/scopes/tests/tree.test.ts @@ -1,5 +1,7 @@ import { config } from '@grafana/runtime'; +import { ScopesSelectorService } from '../selector/ScopesSelectorService'; + import { applyScopes, clearScopesSearch, @@ -39,7 +41,7 @@ import { expectSelectedScopePath, expectTreeScopePath, } from './utils/assertions'; -import { fetchNodesSpy, fetchScopeSpy, getDatasource, getInstanceSettings, getMock } from './utils/mocks'; +import { getDatasource, getInstanceSettings, getMock } from './utils/mocks'; import { renderDashboard, resetScenes } from './utils/render'; jest.mock('@grafana/runtime', () => ({ @@ -52,17 +54,22 @@ jest.mock('@grafana/runtime', () => ({ })); describe('Tree', () => { + let fetchNodesSpy: jest.SpyInstance; + let fetchScopeSpy: jest.SpyInstance; + beforeAll(() => { config.featureToggles.scopeFilters = true; config.featureToggles.groupByVariable = true; }); - beforeEach(() => { - renderDashboard(); + beforeEach(async () => { + await renderDashboard(); + fetchNodesSpy = jest.spyOn(ScopesSelectorService.instance!, 'fetchNodeApi'); + fetchScopeSpy = jest.spyOn(ScopesSelectorService.instance!, 'fetchScopeApi'); }); afterEach(async () => { - await resetScenes(); + await resetScenes([fetchNodesSpy, fetchScopeSpy]); }); it('Fetches scope details on select', async () => { @@ -126,16 +133,16 @@ describe('Tree', () => { await openSelector(); await expandResultApplications(); await searchScopes('Cloud'); - expect(fetchNodesSpy).toHaveBeenCalledTimes(2); + expect(fetchNodesSpy).toHaveBeenCalledTimes(3); expectResultApplicationsGrafanaNotPresent(); expectResultApplicationsMimirNotPresent(); expectResultApplicationsCloudPresent(); await clearScopesSearch(); - expect(fetchNodesSpy).toHaveBeenCalledTimes(3); + expect(fetchNodesSpy).toHaveBeenCalledTimes(4); await searchScopes('Grafana'); - expect(fetchNodesSpy).toHaveBeenCalledTimes(4); + expect(fetchNodesSpy).toHaveBeenCalledTimes(5); expectResultApplicationsGrafanaPresent(); expectResultApplicationsCloudNotPresent(); }); @@ -156,7 +163,7 @@ describe('Tree', () => { await expandResultApplications(); await selectResultApplicationsMimir(); await searchScopes('grafana'); - expect(fetchNodesSpy).toHaveBeenCalledTimes(2); + expect(fetchNodesSpy).toHaveBeenCalledTimes(3); expectPersistedApplicationsMimirPresent(); expectPersistedApplicationsGrafanaNotPresent(); expectResultApplicationsMimirNotPresent(); @@ -168,7 +175,7 @@ describe('Tree', () => { await expandResultApplications(); await selectResultApplicationsMimir(); await searchScopes('mimir'); - expect(fetchNodesSpy).toHaveBeenCalledTimes(2); + expect(fetchNodesSpy).toHaveBeenCalledTimes(3); expectPersistedApplicationsMimirNotPresent(); expectResultApplicationsMimirPresent(); }); @@ -178,10 +185,10 @@ describe('Tree', () => { await expandResultApplications(); await selectResultApplicationsMimir(); await searchScopes('grafana'); - expect(fetchNodesSpy).toHaveBeenCalledTimes(2); + expect(fetchNodesSpy).toHaveBeenCalledTimes(3); await clearScopesSearch(); - expect(fetchNodesSpy).toHaveBeenCalledTimes(3); + expect(fetchNodesSpy).toHaveBeenCalledTimes(4); expectPersistedApplicationsMimirNotPresent(); expectPersistedApplicationsGrafanaNotPresent(); expectResultApplicationsMimirPresent(); @@ -192,15 +199,15 @@ describe('Tree', () => { await openSelector(); await expandResultApplications(); await searchScopes('mimir'); - expect(fetchNodesSpy).toHaveBeenCalledTimes(2); + expect(fetchNodesSpy).toHaveBeenCalledTimes(3); await selectResultApplicationsMimir(); await searchScopes('unknown'); - expect(fetchNodesSpy).toHaveBeenCalledTimes(3); + expect(fetchNodesSpy).toHaveBeenCalledTimes(4); expectPersistedApplicationsMimirPresent(); await clearScopesSearch(); - expect(fetchNodesSpy).toHaveBeenCalledTimes(4); + expect(fetchNodesSpy).toHaveBeenCalledTimes(5); expectResultApplicationsMimirPresent(); expectResultApplicationsGrafanaPresent(); }); @@ -210,7 +217,7 @@ describe('Tree', () => { await expandResultApplications(); await selectResultApplicationsMimir(); await searchScopes('grafana'); - expect(fetchNodesSpy).toHaveBeenCalledTimes(2); + expect(fetchNodesSpy).toHaveBeenCalledTimes(3); await selectResultApplicationsGrafana(); await applyScopes(); @@ -222,7 +229,7 @@ describe('Tree', () => { await expandResultApplications(); await selectResultApplicationsMimir(); await searchScopes('grafana'); - expect(fetchNodesSpy).toHaveBeenCalledTimes(2); + expect(fetchNodesSpy).toHaveBeenCalledTimes(3); await selectResultApplicationsGrafana(); await applyScopes(); @@ -239,11 +246,11 @@ describe('Tree', () => { expectScopesHeadline('Recommended'); await searchScopes('Applications'); - expect(fetchNodesSpy).toHaveBeenCalledTimes(1); + expect(fetchNodesSpy).toHaveBeenCalledTimes(2); expectScopesHeadline('Results'); await searchScopes('unknown'); - expect(fetchNodesSpy).toHaveBeenCalledTimes(2); + expect(fetchNodesSpy).toHaveBeenCalledTimes(3); expectScopesHeadline('No results found for your query'); }); diff --git a/public/app/features/scopes/tests/utils.test.ts b/public/app/features/scopes/tests/utils.test.ts deleted file mode 100644 index 7b37541fb05..00000000000 --- a/public/app/features/scopes/tests/utils.test.ts +++ /dev/null @@ -1,364 +0,0 @@ -import { filterFolders, groupDashboards } from '../internal/utils'; - -import { - alternativeDashboardWithRootFolder, - alternativeDashboardWithTwoFolders, - dashboardWithOneFolder, - dashboardWithoutFolder, - dashboardWithRootFolder, - dashboardWithRootFolderAndOtherFolder, - dashboardWithTwoFolders, -} from './utils/mocks'; - -describe('Utils', () => { - describe('groupDashboards', () => { - it('Assigns dashboards without groups to root folder', () => { - expect(groupDashboards([dashboardWithoutFolder])).toEqual({ - '': { - title: '', - isExpanded: true, - folders: {}, - dashboards: { - [dashboardWithoutFolder.spec.dashboard]: { - dashboard: dashboardWithoutFolder.spec.dashboard, - dashboardTitle: dashboardWithoutFolder.status.dashboardTitle, - items: [dashboardWithoutFolder], - }, - }, - }, - }); - }); - - it('Assigns dashboards with root group to root folder', () => { - expect(groupDashboards([dashboardWithRootFolder])).toEqual({ - '': { - title: '', - isExpanded: true, - folders: {}, - dashboards: { - [dashboardWithRootFolder.spec.dashboard]: { - dashboard: dashboardWithRootFolder.spec.dashboard, - dashboardTitle: dashboardWithRootFolder.status.dashboardTitle, - items: [dashboardWithRootFolder], - }, - }, - }, - }); - }); - - it('Merges folders from multiple dashboards', () => { - expect(groupDashboards([dashboardWithOneFolder, dashboardWithTwoFolders])).toEqual({ - '': { - title: '', - isExpanded: true, - folders: { - 'Folder 1': { - title: 'Folder 1', - isExpanded: false, - folders: {}, - dashboards: { - [dashboardWithOneFolder.spec.dashboard]: { - dashboard: dashboardWithOneFolder.spec.dashboard, - dashboardTitle: dashboardWithOneFolder.status.dashboardTitle, - items: [dashboardWithOneFolder], - }, - [dashboardWithTwoFolders.spec.dashboard]: { - dashboard: dashboardWithTwoFolders.spec.dashboard, - dashboardTitle: dashboardWithTwoFolders.status.dashboardTitle, - items: [dashboardWithTwoFolders], - }, - }, - }, - 'Folder 2': { - title: 'Folder 2', - isExpanded: false, - folders: {}, - dashboards: { - [dashboardWithTwoFolders.spec.dashboard]: { - dashboard: dashboardWithTwoFolders.spec.dashboard, - dashboardTitle: dashboardWithTwoFolders.status.dashboardTitle, - items: [dashboardWithTwoFolders], - }, - }, - }, - }, - dashboards: {}, - }, - }); - }); - - it('Merges scopes from multiple dashboards', () => { - expect(groupDashboards([dashboardWithTwoFolders, alternativeDashboardWithTwoFolders])).toEqual({ - '': { - title: '', - isExpanded: true, - folders: { - 'Folder 1': { - title: 'Folder 1', - isExpanded: false, - folders: {}, - dashboards: { - [dashboardWithTwoFolders.spec.dashboard]: { - dashboard: dashboardWithTwoFolders.spec.dashboard, - dashboardTitle: dashboardWithTwoFolders.status.dashboardTitle, - items: [dashboardWithTwoFolders, alternativeDashboardWithTwoFolders], - }, - }, - }, - 'Folder 2': { - title: 'Folder 2', - isExpanded: false, - folders: {}, - dashboards: { - [dashboardWithTwoFolders.spec.dashboard]: { - dashboard: dashboardWithTwoFolders.spec.dashboard, - dashboardTitle: dashboardWithTwoFolders.status.dashboardTitle, - items: [dashboardWithTwoFolders, alternativeDashboardWithTwoFolders], - }, - }, - }, - }, - dashboards: {}, - }, - }); - }); - - it('Matches snapshot', () => { - expect( - groupDashboards([ - dashboardWithoutFolder, - dashboardWithOneFolder, - dashboardWithTwoFolders, - alternativeDashboardWithTwoFolders, - dashboardWithRootFolder, - alternativeDashboardWithRootFolder, - dashboardWithRootFolderAndOtherFolder, - ]) - ).toEqual({ - '': { - dashboards: { - [dashboardWithRootFolderAndOtherFolder.spec.dashboard]: { - dashboard: dashboardWithRootFolderAndOtherFolder.spec.dashboard, - dashboardTitle: dashboardWithRootFolderAndOtherFolder.status.dashboardTitle, - items: [dashboardWithRootFolderAndOtherFolder], - }, - [dashboardWithRootFolder.spec.dashboard]: { - dashboard: dashboardWithRootFolder.spec.dashboard, - dashboardTitle: dashboardWithRootFolder.status.dashboardTitle, - items: [dashboardWithRootFolder, alternativeDashboardWithRootFolder], - }, - [dashboardWithoutFolder.spec.dashboard]: { - dashboard: dashboardWithoutFolder.spec.dashboard, - dashboardTitle: dashboardWithoutFolder.status.dashboardTitle, - items: [dashboardWithoutFolder], - }, - }, - folders: { - 'Folder 1': { - dashboards: { - [dashboardWithOneFolder.spec.dashboard]: { - dashboard: dashboardWithOneFolder.spec.dashboard, - dashboardTitle: dashboardWithOneFolder.status.dashboardTitle, - items: [dashboardWithOneFolder], - }, - [dashboardWithTwoFolders.spec.dashboard]: { - dashboard: dashboardWithTwoFolders.spec.dashboard, - dashboardTitle: dashboardWithTwoFolders.status.dashboardTitle, - items: [dashboardWithTwoFolders, alternativeDashboardWithTwoFolders], - }, - }, - folders: {}, - isExpanded: false, - title: 'Folder 1', - }, - 'Folder 2': { - dashboards: { - [dashboardWithTwoFolders.spec.dashboard]: { - dashboard: dashboardWithTwoFolders.spec.dashboard, - dashboardTitle: dashboardWithTwoFolders.status.dashboardTitle, - items: [dashboardWithTwoFolders, alternativeDashboardWithTwoFolders], - }, - }, - folders: {}, - isExpanded: false, - title: 'Folder 2', - }, - 'Folder 3': { - dashboards: { - [dashboardWithRootFolderAndOtherFolder.spec.dashboard]: { - dashboard: dashboardWithRootFolderAndOtherFolder.spec.dashboard, - dashboardTitle: dashboardWithRootFolderAndOtherFolder.status.dashboardTitle, - items: [dashboardWithRootFolderAndOtherFolder], - }, - }, - folders: {}, - isExpanded: false, - title: 'Folder 3', - }, - }, - isExpanded: true, - title: '', - }, - }); - }); - }); - - describe('filterFolders', () => { - it('Shows folders matching criteria', () => { - expect( - filterFolders( - { - '': { - title: '', - isExpanded: true, - folders: { - 'Folder 1': { - title: 'Folder 1', - isExpanded: false, - folders: {}, - dashboards: { - 'Dashboard ID': { - dashboard: 'Dashboard ID', - dashboardTitle: 'Dashboard Title', - items: [], - }, - }, - }, - 'Folder 2': { - title: 'Folder 2', - isExpanded: true, - folders: {}, - dashboards: { - 'Dashboard ID': { - dashboard: 'Dashboard ID', - dashboardTitle: 'Dashboard Title', - items: [], - }, - }, - }, - }, - dashboards: { - 'Dashboard ID': { - dashboard: 'Dashboard ID', - dashboardTitle: 'Dashboard Title', - items: [], - }, - }, - }, - }, - 'Folder' - ) - ).toEqual({ - '': { - title: '', - isExpanded: true, - folders: { - 'Folder 1': { - title: 'Folder 1', - isExpanded: true, - folders: {}, - dashboards: { - 'Dashboard ID': { - dashboard: 'Dashboard ID', - dashboardTitle: 'Dashboard Title', - items: [], - }, - }, - }, - 'Folder 2': { - title: 'Folder 2', - isExpanded: true, - folders: {}, - dashboards: { - 'Dashboard ID': { - dashboard: 'Dashboard ID', - dashboardTitle: 'Dashboard Title', - items: [], - }, - }, - }, - }, - dashboards: {}, - }, - }); - }); - - it('Shows dashboards matching criteria', () => { - expect( - filterFolders( - { - '': { - title: '', - isExpanded: true, - folders: { - 'Folder 1': { - title: 'Folder 1', - isExpanded: false, - folders: {}, - dashboards: { - 'Dashboard ID': { - dashboard: 'Dashboard ID', - dashboardTitle: 'Dashboard Title', - items: [], - }, - }, - }, - 'Folder 2': { - title: 'Folder 2', - isExpanded: true, - folders: {}, - dashboards: { - 'Random ID': { - dashboard: 'Random ID', - dashboardTitle: 'Random Title', - items: [], - }, - }, - }, - }, - dashboards: { - 'Dashboard ID': { - dashboard: 'Dashboard ID', - dashboardTitle: 'Dashboard Title', - items: [], - }, - 'Random ID': { - dashboard: 'Random ID', - dashboardTitle: 'Random Title', - items: [], - }, - }, - }, - }, - 'dash' - ) - ).toEqual({ - '': { - title: '', - isExpanded: true, - folders: { - 'Folder 1': { - title: 'Folder 1', - isExpanded: true, - folders: {}, - dashboards: { - 'Dashboard ID': { - dashboard: 'Dashboard ID', - dashboardTitle: 'Dashboard Title', - items: [], - }, - }, - }, - }, - dashboards: { - 'Dashboard ID': { - dashboard: 'Dashboard ID', - dashboardTitle: 'Dashboard Title', - items: [], - }, - }, - }, - }); - }); - }); -}); diff --git a/public/app/features/scopes/tests/utils/actions.ts b/public/app/features/scopes/tests/utils/actions.ts index 9781fee2b6d..5972a430fc5 100644 --- a/public/app/features/scopes/tests/utils/actions.ts +++ b/public/app/features/scopes/tests/utils/actions.ts @@ -5,16 +5,8 @@ import { MultiValueVariable, sceneGraph, VariableValue } from '@grafana/scenes'; import { defaultTimeZone, TimeZone } from '@grafana/schema'; import { DashboardScene } from 'app/features/dashboard-scene/scene/DashboardScene'; -import { scopesSelectorScene } from '../../instance'; +import { ScopesService } from '../../ScopesService'; -import { - dashboardReloadSpy, - fetchDashboardsSpy, - fetchNodesSpy, - fetchScopeSpy, - fetchSelectedScopesSpy, - getMock, -} from './mocks'; import { getDashboardFolderExpand, getDashboardsExpand, @@ -37,30 +29,13 @@ import { getTreeSearch, } from './selectors'; -export const clearMocks = () => { - fetchNodesSpy.mockClear(); - fetchScopeSpy.mockClear(); - fetchSelectedScopesSpy.mockClear(); - fetchDashboardsSpy.mockClear(); - dashboardReloadSpy.mockClear(); - getMock.mockClear(); -}; - const click = async (selector: () => HTMLElement) => act(() => fireEvent.click(selector())); const type = async (selector: () => HTMLInputElement, value: string) => { await act(() => fireEvent.input(selector(), { target: { value } })); await jest.runOnlyPendingTimersAsync(); }; -export const updateScopes = async (scopes: string[]) => - act(async () => - scopesSelectorScene?.updateScopes( - scopes.map((scopeName) => ({ - scopeName, - path: [], - })) - ) - ); +export const updateScopes = async (scopes: string[]) => act(async () => ScopesService.instance?.changeScopes(scopes)); export const openSelector = async () => click(getSelectorInput); export const applyScopes = async () => { await click(getSelectorApply); diff --git a/public/app/features/scopes/tests/utils/assertions.ts b/public/app/features/scopes/tests/utils/assertions.ts index f58d73de50f..c842e81b3fa 100644 --- a/public/app/features/scopes/tests/utils/assertions.ts +++ b/public/app/features/scopes/tests/utils/assertions.ts @@ -1,4 +1,3 @@ -import { dashboardReloadSpy } from './mocks'; import { getDashboard, getDashboardsContainer, @@ -21,7 +20,6 @@ import { queryDashboard, queryDashboardFolderExpand, queryDashboardsContainer, - queryDashboardsExpand, queryDashboardsSearch, queryPersistedApplicationsGrafanaSelect, queryPersistedApplicationsMimirSelect, @@ -29,7 +27,6 @@ import { queryResultApplicationsGrafanaSelect, queryResultApplicationsMimirSelect, querySelectorApply, - querySelectorInput, } from './selectors'; const expectInDocument = (selector: () => HTMLElement) => expect(selector()).toBeInTheDocument(); @@ -42,7 +39,7 @@ const expectTextContent = (selector: () => HTMLElement, text: string) => expect( const expectDisabled = (selector: () => HTMLElement) => expect(selector()).toBeDisabled(); export const expectScopesSelectorClosed = () => expectNotInDocument(querySelectorApply); -export const expectScopesSelectorNotInDocument = () => expectNotInDocument(querySelectorInput); +export const expectScopesSelectorDisabled = () => expectDisabled(getSelectorInput); export const expectScopesSelectorValue = (value: string) => expectValue(getSelectorInput, value); export const expectScopesHeadline = (value: string) => expectTextContent(getTreeHeadline, value); export const expectPersistedApplicationsGrafanaNotPresent = () => @@ -65,7 +62,6 @@ export const expectResultCloudOpsSelected = () => expectRadioChecked(getResultCl export const expectResultCloudOpsNotSelected = () => expectRadioNotChecked(getResultCloudOpsRadio); export const expectDashboardsDisabled = () => expectDisabled(getDashboardsExpand); -export const expectDashboardsNotInDocument = () => expectNotInDocument(queryDashboardsExpand); export const expectDashboardsClosed = () => expectNotInDocument(queryDashboardsContainer); export const expectDashboardsOpen = () => expectInDocument(getDashboardsContainer); export const expectNoDashboardsSearch = () => expectNotInDocument(queryDashboardsSearch); @@ -81,9 +77,6 @@ export const expectDashboardNotInDocument = (uid: string) => expectNotInDocument export const expectDashboardLength = (uid: string, length: number) => expect(queryAllDashboard(uid)).toHaveLength(length); -export const expectNotDashboardReload = () => expect(dashboardReloadSpy).not.toHaveBeenCalled(); -export const expectDashboardReload = () => expect(dashboardReloadSpy).toHaveBeenCalled(); - export const expectSelectedScopePath = (name: string, path: string[] | undefined) => expect(getSelectedScope(name)?.path).toEqual(path); export const expectTreeScopePath = (name: string, path: string[] | undefined) => diff --git a/public/app/features/scopes/tests/utils/mocks.ts b/public/app/features/scopes/tests/utils/mocks.ts index 0ac0a785237..f61e251a8bb 100644 --- a/public/app/features/scopes/tests/utils/mocks.ts +++ b/public/app/features/scopes/tests/utils/mocks.ts @@ -2,8 +2,6 @@ import { Scope, ScopeDashboardBinding, ScopeNode } from '@grafana/data'; import { DataSourceRef } from '@grafana/schema/dist/esm/common/common.gen'; import { getDashboardScenePageStateManager } from 'app/features/dashboard-scene/pages/DashboardScenePageStateManager'; -import * as api from '../../internal/api'; - export const mocksScopes: Scope[] = [ { metadata: { name: 'cloud' }, @@ -369,10 +367,6 @@ export const mocksNodes: Array = [ }, ] as const; -export const fetchNodesSpy = jest.spyOn(api, 'fetchNodes'); -export const fetchScopeSpy = jest.spyOn(api, 'fetchScope'); -export const fetchSelectedScopesSpy = jest.spyOn(api, 'fetchSelectedScopes'); -export const fetchDashboardsSpy = jest.spyOn(api, 'fetchDashboards'); export const dashboardReloadSpy = jest.spyOn(getDashboardScenePageStateManager(), 'reloadDashboard'); export const getMock = jest diff --git a/public/app/features/scopes/tests/utils/render.tsx b/public/app/features/scopes/tests/utils/render.tsx index 32ff0010d48..66072bd43b2 100644 --- a/public/app/features/scopes/tests/utils/render.tsx +++ b/public/app/features/scopes/tests/utils/render.tsx @@ -1,19 +1,21 @@ -import { cleanup } from '@testing-library/react'; +import { cleanup, waitFor } from '@testing-library/react'; import { KBarProvider } from 'kbar'; import { render } from 'test/test-utils'; import { getPanelPlugin } from '@grafana/data/test/__mocks__/pluginMocks'; import { config, setPluginImportUtils } from '@grafana/runtime'; +import { sceneGraph } from '@grafana/scenes'; import { defaultDashboard } from '@grafana/schema'; import { AppChrome } from 'app/core/components/AppChrome/AppChrome'; import { transformSaveModelToScene } from 'app/features/dashboard-scene/serialization/transformSaveModelToScene'; import { DashboardDataDTO, DashboardDTO, DashboardMeta } from 'app/types'; -import { initializeScopes, scopesDashboardsScene, scopesSelectorScene } from '../../instance'; -import { getInitialDashboardsState } from '../../internal/ScopesDashboardsScene'; -import { initialSelectorState } from '../../internal/ScopesSelectorScene'; +import { ScopesContextProvider } from '../../ScopesContextProvider'; +import { ScopesService } from '../../ScopesService'; +import { ScopesDashboardsService } from '../../dashboards/ScopesDashboardsService'; +import { ScopesSelectorService } from '../../selector/ScopesSelectorService'; -import { clearMocks } from './actions'; +import { getMock } from './mocks'; const getDashboardDTO: ( overrideDashboard: Partial, @@ -176,33 +178,38 @@ setPluginImportUtils({ getPanelPluginFromCache: () => undefined, }); -export function renderDashboard( +export async function renderDashboard( overrideDashboard: Partial = {}, overrideMeta: Partial = {} ) { jest.useFakeTimers({ advanceTimers: true }); jest.spyOn(console, 'error').mockImplementation(jest.fn()); - clearMocks(); - initializeScopes(); const dto: DashboardDTO = getDashboardDTO(overrideDashboard, overrideMeta); const scene = transformSaveModelToScene(dto); render( - - - + + + + + ); + await waitFor(() => expect(sceneGraph.getScopesBridge(scene)).toBeDefined()); + return scene; } -export async function resetScenes() { +export async function resetScenes(spies: jest.SpyInstance[] = []) { await jest.runOnlyPendingTimersAsync(); jest.useRealTimers(); - scopesSelectorScene?.setState(initialSelectorState); - scopesDashboardsScene?.setState(getInitialDashboardsState()); + getMock.mockClear(); + spies.forEach((spy) => spy.mockClear()); + ScopesService.instance?.reset(); + ScopesSelectorService.instance?.reset(); + ScopesDashboardsService.instance?.reset(); cleanup(); } diff --git a/public/app/features/scopes/tests/utils/selectors.ts b/public/app/features/scopes/tests/utils/selectors.ts index 689e82ca87f..e5ef25e26bb 100644 --- a/public/app/features/scopes/tests/utils/selectors.ts +++ b/public/app/features/scopes/tests/utils/selectors.ts @@ -1,6 +1,7 @@ import { screen } from '@testing-library/react'; -import { scopesSelectorScene } from '../../instance'; +import { ScopesService } from '../../ScopesService'; +import { ScopesSelectorService } from '../../selector/ScopesSelectorService'; const selectors = { tree: { @@ -33,14 +34,12 @@ const selectors = { }; export const getSelectorInput = () => screen.getByTestId(selectors.selector.input); -export const querySelectorInput = () => screen.queryByTestId(selectors.selector.input); export const querySelectorApply = () => screen.queryByTestId(selectors.selector.apply); export const getSelectorApply = () => screen.getByTestId(selectors.selector.apply); export const getSelectorCancel = () => screen.getByTestId(selectors.selector.cancel); export const getDashboardsExpand = () => screen.getByTestId(selectors.dashboards.expand); export const getDashboardsContainer = () => screen.getByTestId(selectors.dashboards.container); -export const queryDashboardsExpand = () => screen.queryByTestId(selectors.dashboards.expand); export const queryDashboardsContainer = () => screen.queryByTestId(selectors.dashboards.container); export const queryDashboardsSearch = () => screen.queryByTestId(selectors.dashboards.search); export const getDashboardsSearch = () => screen.getByTestId(selectors.dashboards.search); @@ -88,8 +87,9 @@ export const getResultCloudDevRadio = () => export const getResultCloudOpsRadio = () => screen.getByTestId(selectors.tree.radio('cloud-ops', 'result')); -export const getListOfSelectedScopes = () => scopesSelectorScene?.state.scopes; -export const getListOfTreeScopes = () => scopesSelectorScene?.state.treeScopes; +export const getListOfScopes = () => ScopesService.instance?.state.value; +export const getListOfSelectedScopes = () => ScopesSelectorService.instance?.state.selectedScopes; +export const getListOfTreeScopes = () => ScopesSelectorService.instance?.state.treeScopes; export const getSelectedScope = (name: string) => getListOfSelectedScopes()?.find((selectedScope) => selectedScope.scope.metadata.name === name); export const getTreeScope = (name: string) => getListOfTreeScopes()?.find((treeScope) => treeScope.scopeName === name); diff --git a/public/app/features/scopes/tests/viewMode.test.ts b/public/app/features/scopes/tests/viewMode.test.ts index 89d698b9b0f..ba115534f98 100644 --- a/public/app/features/scopes/tests/viewMode.test.ts +++ b/public/app/features/scopes/tests/viewMode.test.ts @@ -1,14 +1,14 @@ import { config } from '@grafana/runtime'; import { DashboardScene } from 'app/features/dashboard-scene/scene/DashboardScene'; -import { scopesDashboardsScene, scopesSelectorScene } from '../instance'; +import { ScopesService } from '../ScopesService'; import { enterEditMode, openSelector, toggleDashboards } from './utils/actions'; import { expectDashboardsClosed, - expectDashboardsNotInDocument, + expectDashboardsDisabled, expectScopesSelectorClosed, - expectScopesSelectorNotInDocument, + expectScopesSelectorDisabled, } from './utils/assertions'; import { getDatasource, getInstanceSettings, getMock } from './utils/mocks'; import { renderDashboard, resetScenes } from './utils/render'; @@ -30,8 +30,8 @@ describe('View mode', () => { config.featureToggles.groupByVariable = true; }); - beforeEach(() => { - dashboardScene = renderDashboard(); + beforeEach(async () => { + dashboardScene = await renderDashboard(); }); afterEach(async () => { @@ -40,8 +40,8 @@ describe('View mode', () => { it('Enters view mode', async () => { await enterEditMode(dashboardScene); - expect(scopesSelectorScene?.state?.isReadOnly).toEqual(true); - expect(scopesDashboardsScene?.state?.isPanelOpened).toEqual(false); + expect(ScopesService.instance?.state.readOnly).toEqual(true); + expect(ScopesService.instance?.state.drawerOpened).toEqual(false); }); it('Closes selector on enter', async () => { @@ -58,11 +58,11 @@ describe('View mode', () => { it('Does not show selector when view mode is active', async () => { await enterEditMode(dashboardScene); - expectScopesSelectorNotInDocument(); + expectScopesSelectorDisabled(); }); it('Does not show the expand button when view mode is active', async () => { await enterEditMode(dashboardScene); - expectDashboardsNotInDocument(); + expectDashboardsDisabled(); }); }); diff --git a/public/app/features/scopes/useScopesDashboardsState.ts b/public/app/features/scopes/useScopesDashboardsState.ts deleted file mode 100644 index 7fc2e7d385a..00000000000 --- a/public/app/features/scopes/useScopesDashboardsState.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { scopesDashboardsScene } from './instance'; - -export const useScopesDashboardsState = () => { - return scopesDashboardsScene?.useState(); -}; diff --git a/public/app/features/scopes/utils.ts b/public/app/features/scopes/utils.ts deleted file mode 100644 index 29ddd616382..00000000000 --- a/public/app/features/scopes/utils.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Scope } from '@grafana/data'; -import { sceneGraph, SceneObject } from '@grafana/scenes'; - -import { ScopesFacade } from './ScopesFacadeScene'; -import { scopesDashboardsScene, scopesSelectorScene } from './instance'; -import { getScopesFromSelectedScopes } from './internal/utils'; - -export function getSelectedScopes(): Scope[] { - return getScopesFromSelectedScopes(scopesSelectorScene?.state.scopes ?? []); -} - -export function getSelectedScopesNames(): string[] { - return getSelectedScopes().map((scope) => scope.metadata.name); -} - -export function enableScopes() { - scopesSelectorScene?.enable(); - scopesDashboardsScene?.enable(); -} - -export function disableScopes() { - scopesSelectorScene?.disable(); - scopesDashboardsScene?.disable(); -} - -export function exitScopesReadOnly() { - scopesSelectorScene?.exitReadOnly(); - scopesDashboardsScene?.exitReadOnly(); -} - -export function enterScopesReadOnly() { - scopesSelectorScene?.enterReadOnly(); - scopesDashboardsScene?.enterReadOnly(); -} - -export function getClosestScopesFacade(scene: SceneObject): ScopesFacade | null { - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions - return sceneGraph.findObject(scene, (obj) => obj instanceof ScopesFacade) as ScopesFacade | null; -} diff --git a/public/app/features/trails/DataTrail.tsx b/public/app/features/trails/DataTrail.tsx index aef53bad053..3a6502f894f 100644 --- a/public/app/features/trails/DataTrail.tsx +++ b/public/app/features/trails/DataTrail.tsx @@ -31,7 +31,6 @@ import { VariableValueSelectors, } from '@grafana/scenes'; import { useStyles2 } from '@grafana/ui'; -import { getSelectedScopes } from 'app/features/scopes'; import { DataTrailSettings } from './DataTrailSettings'; import { DataTrailHistory } from './DataTrailsHistory'; @@ -426,7 +425,11 @@ export class DataTrail extends SceneObjectBase implements SceneO if (timeRange) { const datasourceUid = sceneGraph.interpolate(trail, VAR_DATASOURCE_EXPR); const otelTargets = await totalOtelResources(datasourceUid, timeRange); - const deploymentEnvironments = await getDeploymentEnvironments(datasourceUid, timeRange, getSelectedScopes()); + const deploymentEnvironments = await getDeploymentEnvironments( + datasourceUid, + timeRange, + sceneGraph.getScopesBridge(trail)?.getValue() ?? [] + ); const hasOtelResources = otelTargets.jobs.length > 0 && otelTargets.instances.length > 0; // loading from the url with otel resources selected will result in turning on OTel experience const otelResourcesVariable = sceneGraph.lookupVariable(VAR_OTEL_AND_METRIC_FILTERS, this); diff --git a/public/app/features/trails/DataTrailsApp.tsx b/public/app/features/trails/DataTrailsApp.tsx index b1fdf17a467..156a77e3e47 100644 --- a/public/app/features/trails/DataTrailsApp.tsx +++ b/public/app/features/trails/DataTrailsApp.tsx @@ -1,20 +1,16 @@ -import { css } from '@emotion/css'; import { useEffect, useState } from 'react'; import { Routes, Route } from 'react-router-dom-v5-compat'; -import { - DataQueryRequest, - DataSourceGetTagKeysOptions, - DataSourceGetTagValuesOptions, - PageLayoutType, -} from '@grafana/data'; +import { PageLayoutType } from '@grafana/data'; import { config, locationService } from '@grafana/runtime'; -import { SceneComponentProps, SceneObjectBase, SceneObjectState, UrlSyncContextProvider } from '@grafana/scenes'; -import { useStyles2 } from '@grafana/ui/'; +import { + SceneComponentProps, + SceneObjectBase, + SceneObjectState, + SceneScopesBridge, + UrlSyncContextProvider, +} from '@grafana/scenes'; import { Page } from 'app/core/components/Page/Page'; -import { getClosestScopesFacade, ScopesFacade, ScopesSelector } from 'app/features/scopes'; - -import { AppChromeUpdate } from '../../core/components/AppChrome/AppChromeUpdate'; import { DataTrail } from './DataTrail'; import { DataTrailsHome } from './DataTrailsHome'; @@ -25,35 +21,14 @@ import { getMetricName, getUrlForTrail, newMetricsTrail } from './utils'; export interface DataTrailsAppState extends SceneObjectState { trail: DataTrail; home: DataTrailsHome; + scopesBridge?: SceneScopesBridge | undefined; } export class DataTrailsApp extends SceneObjectBase { - private _scopesFacade: ScopesFacade | null; + protected _renderBeforeActivation = true; public constructor(state: DataTrailsAppState) { super(state); - - this._scopesFacade = getClosestScopesFacade(this); - } - - public enrichDataRequest(): Partial { - if (!config.featureToggles.promQLScope) { - return {}; - } - - return { - scopes: this._scopesFacade?.value, - }; - } - - public enrichFiltersRequest(): Partial { - if (!config.featureToggles.promQLScope) { - return {}; - } - - return { - scopes: this._scopesFacade?.value, - }; } goToUrlForTrail(trail: DataTrail) { @@ -62,33 +37,35 @@ export class DataTrailsApp extends SceneObjectBase { } static Component = ({ model }: SceneComponentProps) => { - const { trail, home } = model.useState(); + const { trail, home, scopesBridge } = model.useState(); return ( - - {/* The routes are relative to the HOME_ROUTE */} - null} - subTitle="" - > - - - } - /> - } /> - + <> + {scopesBridge && } + + {/* The routes are relative to the HOME_ROUTE */} + null} + subTitle="" + > + + + } + /> + } /> + + ); }; } function DataTrailView({ trail }: { trail: DataTrail }) { - const styles = useStyles2(getStyles); const [isInitialized, setIsInitialized] = useState(false); const { metric } = trail.useState(); @@ -108,15 +85,6 @@ function DataTrailView({ trail }: { trail: DataTrail }) { return ( - {config.featureToggles.enableScopesInMetricsExplore && ( - - -
- } - /> - )} @@ -127,37 +95,32 @@ let dataTrailsApp: DataTrailsApp; export function getDataTrailsApp() { if (!dataTrailsApp) { - const $behaviors = config.featureToggles.enableScopesInMetricsExplore - ? [ - new ScopesFacade({ - handler: (facade) => { - const trail = facade.parent && 'trail' in facade.parent.state ? facade.parent.state.trail : undefined; - - if (trail instanceof DataTrail) { - trail.publishEvent(new RefreshMetricsEvent()); - trail.checkDataSourceForOTelResources(); - } - }, - }), - ] - : undefined; + const scopesBridge = + config.featureToggles.scopeFilters && config.featureToggles.enableScopesInMetricsExplore + ? new SceneScopesBridge({}) + : undefined; dataTrailsApp = new DataTrailsApp({ trail: newMetricsTrail(), home: new DataTrailsHome({}), - $behaviors, + scopesBridge, + $behaviors: [ + () => { + scopesBridge?.setEnabled(true); + + const sub = scopesBridge?.subscribeToValue(() => { + dataTrailsApp.state.trail.publishEvent(new RefreshMetricsEvent()); + dataTrailsApp.state.trail.checkDataSourceForOTelResources(); + }); + + return () => { + scopesBridge?.setEnabled(false); + sub?.unsubscribe(); + }; + }, + ], }); } return dataTrailsApp; } - -const getStyles = () => ({ - topNavContainer: css({ - width: '100%', - height: '100%', - display: 'flex', - flexDirection: 'row', - justifyItems: 'flex-start', - }), -}); diff --git a/public/app/features/trails/MetricSelect/MetricSelectScene.tsx b/public/app/features/trails/MetricSelect/MetricSelectScene.tsx index 8a3fcd462e3..9cea458adaa 100644 --- a/public/app/features/trails/MetricSelect/MetricSelectScene.tsx +++ b/public/app/features/trails/MetricSelect/MetricSelectScene.tsx @@ -27,7 +27,6 @@ import { } from '@grafana/scenes'; import { Alert, Badge, Field, Icon, IconButton, InlineSwitch, Input, Select, Tooltip, useStyles2 } from '@grafana/ui'; import { Trans } from 'app/core/internationalization'; -import { getSelectedScopes } from 'app/features/scopes'; import { MetricScene } from '../MetricScene'; import { StatusWrapper } from '../StatusWrapper'; @@ -257,7 +256,7 @@ export class MetricSelectScene extends SceneObjectBase i const response = await getMetricNames( datasourceUid, timeRange, - getSelectedScopes(), + sceneGraph.getScopesBridge(this)?.getValue() ?? [], filters, jobsList, instancesList, diff --git a/public/app/features/trails/utils.test.ts b/public/app/features/trails/utils.test.ts index 04b15995982..9552b691641 100644 --- a/public/app/features/trails/utils.test.ts +++ b/public/app/features/trails/utils.test.ts @@ -50,6 +50,7 @@ describe('limitAdhocProviders', () => { } as unknown as MetricDatasourceHelper; dataTrail = { + forEachChild: jest.fn(), getQueries: jest.fn().mockReturnValue([]), } as unknown as DataTrail; }); diff --git a/public/app/features/trails/utils.ts b/public/app/features/trails/utils.ts index 860dc630a30..2b721161203 100644 --- a/public/app/features/trails/utils.ts +++ b/public/app/features/trails/utils.ts @@ -20,12 +20,12 @@ import { SceneObject, SceneObjectState, SceneObjectUrlValues, + SceneScopesBridge, SceneTimeRange, sceneUtils, SceneVariable, SceneVariableState, } from '@grafana/scenes'; -import { getClosestScopesFacade } from 'app/features/scopes'; import { getDatasourceSrv } from '../plugins/datasource_srv'; @@ -53,6 +53,10 @@ export function getTrailFor(model: SceneObject): DataTrail { return sceneGraph.getAncestor(model, DataTrail); } +export function getScopesBridgeFor(model: SceneObject): SceneScopesBridge | undefined { + return sceneGraph.getScopesBridge(getTrailFor(model)); +} + export function getTrailSettings(model: SceneObject): DataTrailSettings { return sceneGraph.getAncestor(model, DataTrail).state.settings; } @@ -193,7 +197,7 @@ export function limitAdhocProviders( const opts = { filters, - scopes: getClosestScopesFacade(variable)?.value, + scopes: sceneGraph.getScopesBridge(dataTrail)?.getValue(), queries: dataTrail.getQueries(), }; @@ -237,7 +241,7 @@ export function limitAdhocProviders( const opts = { key: filter.key, filters, - scopes: getClosestScopesFacade(variable)?.value, + scopes: sceneGraph.getScopesBridge(dataTrail)?.getValue(), queries: dataTrail.getQueries(), }; diff --git a/yarn.lock b/yarn.lock index 3171da05a1d..a65a3d0f5dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -81,7 +81,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.3, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.24.2, @babel/code-frame@npm:^7.26.2": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.3, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.24.2, @babel/code-frame@npm:^7.25.9, @babel/code-frame@npm:^7.26.2": version: 7.26.2 resolution: "@babel/code-frame@npm:7.26.2" dependencies: @@ -362,6 +362,17 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.25.9": + version: 7.26.7 + resolution: "@babel/parser@npm:7.26.7" + dependencies: + "@babel/types": "npm:^7.26.7" + bin: + parser: ./bin/babel-parser.js + checksum: 10/3ccc384366ca9a9b49c54f5b24c9d8cff9a505f2fbdd1cfc04941c8e1897084cc32f100e77900c12bc14a176cf88daa3c155faad680d9a23491b997fd2a59ffc + languageName: node + linkType: hard + "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.25.9": version: 7.25.9 resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.25.9" @@ -1425,7 +1436,18 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.22.5, @babel/template@npm:^7.24.7, @babel/template@npm:^7.25.9, @babel/template@npm:^7.26.9, @babel/template@npm:^7.3.3": +"@babel/template@npm:^7.22.5, @babel/template@npm:^7.24.7, @babel/template@npm:^7.25.9, @babel/template@npm:^7.3.3": + version: 7.25.9 + resolution: "@babel/template@npm:7.25.9" + dependencies: + "@babel/code-frame": "npm:^7.25.9" + "@babel/parser": "npm:^7.25.9" + "@babel/types": "npm:^7.25.9" + checksum: 10/e861180881507210150c1335ad94aff80fd9e9be6202e1efa752059c93224e2d5310186ddcdd4c0f0b0fc658ce48cb47823f15142b5c00c8456dde54f5de80b2 + languageName: node + linkType: hard + +"@babel/template@npm:^7.26.9": version: 7.26.9 resolution: "@babel/template@npm:7.26.9" dependencies: @@ -1461,6 +1483,16 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.26.7": + version: 7.26.7 + resolution: "@babel/types@npm:7.26.7" + dependencies: + "@babel/helper-string-parser": "npm:^7.25.9" + "@babel/helper-validator-identifier": "npm:^7.25.9" + checksum: 10/2264efd02cc261ca5d1c5bc94497c8995238f28afd2b7483b24ea64dd694cf46b00d51815bf0c87f0d0061ea221569c77893aeecb0d4b4bb254e9c2f938d7669 + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -3597,11 +3629,11 @@ __metadata: languageName: unknown linkType: soft -"@grafana/scenes-react@npm:6.2.1": - version: 6.2.1 - resolution: "@grafana/scenes-react@npm:6.2.1" +"@grafana/scenes-react@npm:6.3.1": + version: 6.3.1 + resolution: "@grafana/scenes-react@npm:6.3.1" dependencies: - "@grafana/scenes": "npm:6.2.1" + "@grafana/scenes": "npm:6.3.1" lru-cache: "npm:^10.2.2" react-use: "npm:^17.4.0" peerDependencies: @@ -3613,13 +3645,13 @@ __metadata: react: ^18.0.0 react-dom: ^18.0.0 react-router-dom: ^6.28.0 - checksum: 10/b8f44f087999fd6074233090a005de03e9d0ed1ba965a05659773cf48afb3c11ed508371fcf0c4cdc3c9a360b3f33e5126ed9082e2f4ee306459d768bd0a5a34 + checksum: 10/77dd6f7bbe3699ece25435623a78f2ef5d831ab83b59612baa362581f7c3f6c02cb420b5acfff4e3d266872a694e08b98340370468bb246d102b20e9fcc79438 languageName: node linkType: hard -"@grafana/scenes@npm:6.2.1": - version: 6.2.1 - resolution: "@grafana/scenes@npm:6.2.1" +"@grafana/scenes@npm:6.3.1": + version: 6.3.1 + resolution: "@grafana/scenes@npm:6.3.1" dependencies: "@floating-ui/react": "npm:^0.26.16" "@leeoniya/ufuzzy": "npm:^1.0.16" @@ -3637,7 +3669,7 @@ __metadata: react: ^18.0.0 react-dom: ^18.0.0 react-router-dom: ^6.28.0 - checksum: 10/44e9a0386dd09a1a7a45bcdcbf285a00996e885cf56640179cbc35deb1f26af37ce34744321193f98aa078a7e02fc8a06b8f07c03b392229cc42ed56733bab05 + checksum: 10/98e3e96b9ce12ae67aa458819dc9eed1eabd1b7421e768074bd97a0fa2a0b1e080d4121b1ddd357ce41ccaf9252439163aae7e612f12cba878ee6dca34f73831 languageName: node linkType: hard @@ -18071,8 +18103,8 @@ __metadata: "@grafana/prometheus": "workspace:*" "@grafana/runtime": "workspace:*" "@grafana/saga-icons": "workspace:*" - "@grafana/scenes": "npm:6.2.1" - "@grafana/scenes-react": "npm:6.2.1" + "@grafana/scenes": "npm:6.3.1" + "@grafana/scenes-react": "npm:6.3.1" "@grafana/schema": "workspace:*" "@grafana/sql": "workspace:*" "@grafana/tsconfig": "npm:^2.0.0" From 3e7626cc96c91af4b168514a778f4fbab5b3281d Mon Sep 17 00:00:00 2001 From: Victor Marin <36818606+mdvictor@users.noreply.github.com> Date: Tue, 11 Mar 2025 12:40:37 +0200 Subject: [PATCH 32/63] Dashboards: Fix missing `v/e/i` keybindings to return back to dashboard (#101876) readd keybindings to return from edit/view/inspect modes --- .../scene/keyboardShortcuts.ts | 26 ++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/public/app/features/dashboard-scene/scene/keyboardShortcuts.ts b/public/app/features/dashboard-scene/scene/keyboardShortcuts.ts index 3a4bd4687f0..cde032a413e 100644 --- a/public/app/features/dashboard-scene/scene/keyboardShortcuts.ts +++ b/public/app/features/dashboard-scene/scene/keyboardShortcuts.ts @@ -43,7 +43,13 @@ export function setupKeyboardShortcuts(scene: DashboardScene) { keybindings.addBinding({ key: 'v', onTrigger: withFocusedPanel(scene, (vizPanel: VizPanel) => { - if (!scene.state.viewPanelScene) { + if (scene.state.viewPanelScene) { + locationService.push( + locationUtil.getUrlForPartial(locationService.getLocation(), { + viewPanel: undefined, + }) + ); + } else { const url = locationUtil.stripBaseFromUrl(getViewPanelUrl(vizPanel)); locationService.push(url); } @@ -105,7 +111,15 @@ export function setupKeyboardShortcuts(scene: DashboardScene) { keybindings.addBinding({ key: 'i', onTrigger: withFocusedPanel(scene, async (vizPanel: VizPanel) => { - locationService.push(locationUtil.stripBaseFromUrl(getInspectUrl(vizPanel))); + if (scene.state.inspectPanelKey) { + locationService.push( + locationUtil.getUrlForPartial(locationService.getLocation(), { + inspect: undefined, + }) + ); + } else { + locationService.push(locationUtil.stripBaseFromUrl(getInspectUrl(vizPanel))); + } }), }); @@ -178,7 +192,13 @@ export function setupKeyboardShortcuts(scene: DashboardScene) { const sceneRoot = vizPanel.getRoot(); if (sceneRoot instanceof DashboardScene) { const panelId = getPanelIdForVizPanel(vizPanel); - if (!scene.state.editPanel) { + if (scene.state.editPanel) { + locationService.push( + locationUtil.getUrlForPartial(locationService.getLocation(), { + editPanel: undefined, + }) + ); + } else { const url = locationUtil.stripBaseFromUrl(getEditPanelUrl(panelId)); locationService.push(url); } From 3fffb2872e20c895b0acdf48800ba81b9d5fa2f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Fern=C3=A1ndez?= Date: Tue, 11 Mar 2025 11:47:59 +0100 Subject: [PATCH 33/63] InlineField: Use `Combobox` instead of `Select` (#101923) Use Combobox instead of Select --- .../components/Forms/InlineField.story.tsx | 24 +++++++++---------- .../src/components/Forms/InlineField.test.tsx | 8 +++++-- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/packages/grafana-ui/src/components/Forms/InlineField.story.tsx b/packages/grafana-ui/src/components/Forms/InlineField.story.tsx index 384e5aa98de..da42f012f3a 100644 --- a/packages/grafana-ui/src/components/Forms/InlineField.story.tsx +++ b/packages/grafana-ui/src/components/Forms/InlineField.story.tsx @@ -1,8 +1,8 @@ -import { action } from '@storybook/addon-actions'; import { Meta, StoryFn } from '@storybook/react'; +import { useState } from 'react'; +import { Combobox } from '../Combobox/Combobox'; import { Input } from '../Input/Input'; -import { Select } from '../Select/Select'; import { InlineField } from './InlineField'; import mdx from './InlineField.mdx'; @@ -75,24 +75,22 @@ grow.args = { grow: true, }; -export const withSelect: StoryFn = (args) => { +export const withCombobox: StoryFn = (args) => { + const comboboxOptions = [ + { value: 1, label: 'One' }, + { value: 2, label: 'Two' }, + ]; + const [selected, setSelected] = useState(1); return ( - {}} /> + {}} /> ); From ea89a68028805fa1ec7d0d810a22b1d6d20bf8f2 Mon Sep 17 00:00:00 2001 From: Igor Suleymanov Date: Tue, 11 Mar 2025 13:00:37 +0200 Subject: [PATCH 34/63] K8s/Dashboards: Generate Dashboards k8s APIs using Grafana App SDK (#99966) * Generate Dashboard kinds with `grafana-app-sdk` Signed-off-by: Igor Suleymanov * Hack together a fix for invalid TS codegen for v0 & v1 Signed-off-by: Igor Suleymanov * Address Go linter issues Signed-off-by: Igor Suleymanov * Address TS linter issues Signed-off-by: Igor Suleymanov * Add new app to CODEOWNERS Signed-off-by: Igor Suleymanov * Fix a couple of issues detected by tests Signed-off-by: Igor Suleymanov * Update OpenAPI definitions and test files Signed-off-by: Igor Suleymanov * Remove title from Dashboard v1alpha1 spec Signed-off-by: Igor Suleymanov * Remove unused CUE schemas Signed-off-by: Igor Suleymanov * remove unrelated files * allow any in the generated betterer * Add a comment explaining why we don't use deepcopy-gen Signed-off-by: Igor Suleymanov * Default to v2alpha1 if dashboards v2 FF is enabled Signed-off-by: Igor Suleymanov --------- Signed-off-by: Igor Suleymanov Co-authored-by: Ryan McKinley --- .betterer.results | 6 + .github/CODEOWNERS | 1 + .prettierignore | 3 + apps/dashboard/Makefile | 18 + apps/dashboard/kinds/cue.mod/module.cue | 4 + apps/dashboard/kinds/dashboard.cue | 68 + apps/dashboard/kinds/manifest.cue | 9 + .../kinds/v0alpha1/dashboard_spec.cue | 6 + .../kinds/v1alpha1/dashboard_spec.cue | 6 + .../kinds/v2alpha1/dashboard_spec.cue | 923 ++++ apps/dashboard/tshack/v0alpha1_spec_gen.ts | 7 + apps/dashboard/tshack/v1alpha1_spec_gen.ts | 7 + .../v0alpha1/dashboard_object_gen.ts | 49 + .../dashboard/v0alpha1/types.metadata.gen.ts | 30 + .../dashboard/v0alpha1/types.spec.gen.ts | 7 + .../dashboard/v0alpha1/types.status.gen.ts | 30 + .../v1alpha1/dashboard_object_gen.ts | 49 + .../dashboard/v1alpha1/types.metadata.gen.ts | 30 + .../dashboard/v1alpha1/types.spec.gen.ts | 7 + .../dashboard/v1alpha1/types.status.gen.ts | 30 + .../v2alpha1/dashboard_object_gen.ts | 49 + .../dashboard/v2alpha1/types.metadata.gen.ts | 30 + .../dashboard/v2alpha1/types.spec.gen.ts | 1316 +++++ .../dashboard/v2alpha1/types.status.gen.ts | 30 + .../migration/conversion/conversion.go | 92 +- pkg/apis/dashboard/v0alpha1/constants.go | 18 + .../dashboard/v0alpha1/dashboard_codec_gen.go | 28 + .../v0alpha1/dashboard_metadata_gen.go | 28 + .../v0alpha1/dashboard_object_gen.go | 269 ++ .../v0alpha1/dashboard_schema_gen.go | 34 + pkg/apis/dashboard/v0alpha1/dashboard_spec.go | 13 + .../dashboard/v0alpha1/dashboard_spec_gen.go | 3 + .../v0alpha1/dashboard_status_gen.go | 34 + pkg/apis/dashboard/v0alpha1/deepcopy.go | 41 + pkg/apis/dashboard/v0alpha1/doc.go | 5 +- pkg/apis/dashboard/v0alpha1/search.go | 7 + pkg/apis/dashboard/v0alpha1/types.go | 46 +- .../v0alpha1/zz_generated.deepcopy.go | 102 - .../v0alpha1/zz_generated.openapi.go | 258 +- ...enerated.openapi_violation_exceptions.list | 3 +- pkg/apis/dashboard/v1alpha1/constants.go | 18 + .../dashboard/v1alpha1/dashboard_codec_gen.go | 28 + .../v1alpha1/dashboard_metadata_gen.go | 28 + .../v1alpha1/dashboard_object_gen.go | 269 ++ .../v1alpha1/dashboard_schema_gen.go | 34 + pkg/apis/dashboard/v1alpha1/dashboard_spec.go | 11 + .../dashboard/v1alpha1/dashboard_spec_gen.go | 3 + .../v1alpha1/dashboard_status_gen.go | 34 + pkg/apis/dashboard/v1alpha1/deepcopy.go | 41 + pkg/apis/dashboard/v1alpha1/doc.go | 5 +- pkg/apis/dashboard/v1alpha1/types.go | 45 +- .../v1alpha1/zz_generated.deepcopy.go | 102 - .../v1alpha1/zz_generated.openapi.go | 241 +- ...enerated.openapi_violation_exceptions.list | 3 +- pkg/apis/dashboard/v2alpha1/constants.go | 18 + .../dashboard/v2alpha1/dashboard_codec_gen.go | 28 + .../v2alpha1/dashboard_metadata_gen.go | 28 + .../v2alpha1/dashboard_object_gen.go | 269 ++ .../v2alpha1/dashboard_schema_gen.go | 34 + .../dashboard/v2alpha1/dashboard_spec_gen.go | 2373 +++++++++ .../v2alpha1/dashboard_status_gen.go | 34 + pkg/apis/dashboard/v2alpha1/deepcopy.go | 63 + pkg/apis/dashboard/v2alpha1/doc.go | 5 +- pkg/apis/dashboard/v2alpha1/register.go | 14 +- pkg/apis/dashboard/v2alpha1/types.go | 45 +- .../v2alpha1/zz_generated.deepcopy.go | 102 - .../v2alpha1/zz_generated.openapi.go | 4230 ++++++++++++++++- ...enerated.openapi_violation_exceptions.list | 65 +- pkg/apis/dashboard_manifest.go | 53 + pkg/registry/apis/dashboard/large.go | 20 +- pkg/registry/apis/dashboard/mutate.go | 5 +- pkg/registry/apis/dashboard/register.go | 10 + pkg/registry/apis/dashboard/register_test.go | 94 + pkg/storage/unified/apistore/go.mod | 1 + pkg/storage/unified/apistore/go.sum | 2 + pkg/storage/unified/resource/go.mod | 2 +- pkg/storage/unified/resource/go.sum | 2 + .../dashboard/testdata/dashboard-test-v2.yaml | 4 + .../dashboard.grafana.app-v0alpha1.json | 68 +- public/api-merged.json | 2 + public/openapi3.json | 2 + 81 files changed, 11452 insertions(+), 679 deletions(-) create mode 100644 apps/dashboard/Makefile create mode 100644 apps/dashboard/kinds/cue.mod/module.cue create mode 100644 apps/dashboard/kinds/dashboard.cue create mode 100644 apps/dashboard/kinds/manifest.cue create mode 100644 apps/dashboard/kinds/v0alpha1/dashboard_spec.cue create mode 100644 apps/dashboard/kinds/v1alpha1/dashboard_spec.cue create mode 100644 apps/dashboard/kinds/v2alpha1/dashboard_spec.cue create mode 100644 apps/dashboard/tshack/v0alpha1_spec_gen.ts create mode 100644 apps/dashboard/tshack/v1alpha1_spec_gen.ts create mode 100644 packages/grafana-schema/src/schema/dashboard/v0alpha1/dashboard_object_gen.ts create mode 100644 packages/grafana-schema/src/schema/dashboard/v0alpha1/types.metadata.gen.ts create mode 100644 packages/grafana-schema/src/schema/dashboard/v0alpha1/types.spec.gen.ts create mode 100644 packages/grafana-schema/src/schema/dashboard/v0alpha1/types.status.gen.ts create mode 100644 packages/grafana-schema/src/schema/dashboard/v1alpha1/dashboard_object_gen.ts create mode 100644 packages/grafana-schema/src/schema/dashboard/v1alpha1/types.metadata.gen.ts create mode 100644 packages/grafana-schema/src/schema/dashboard/v1alpha1/types.spec.gen.ts create mode 100644 packages/grafana-schema/src/schema/dashboard/v1alpha1/types.status.gen.ts create mode 100644 packages/grafana-schema/src/schema/dashboard/v2alpha1/dashboard_object_gen.ts create mode 100644 packages/grafana-schema/src/schema/dashboard/v2alpha1/types.metadata.gen.ts create mode 100644 packages/grafana-schema/src/schema/dashboard/v2alpha1/types.spec.gen.ts create mode 100644 packages/grafana-schema/src/schema/dashboard/v2alpha1/types.status.gen.ts create mode 100644 pkg/apis/dashboard/v0alpha1/constants.go create mode 100644 pkg/apis/dashboard/v0alpha1/dashboard_codec_gen.go create mode 100644 pkg/apis/dashboard/v0alpha1/dashboard_metadata_gen.go create mode 100644 pkg/apis/dashboard/v0alpha1/dashboard_object_gen.go create mode 100644 pkg/apis/dashboard/v0alpha1/dashboard_schema_gen.go create mode 100644 pkg/apis/dashboard/v0alpha1/dashboard_spec.go create mode 100644 pkg/apis/dashboard/v0alpha1/dashboard_spec_gen.go create mode 100644 pkg/apis/dashboard/v0alpha1/dashboard_status_gen.go create mode 100644 pkg/apis/dashboard/v0alpha1/deepcopy.go create mode 100644 pkg/apis/dashboard/v1alpha1/constants.go create mode 100644 pkg/apis/dashboard/v1alpha1/dashboard_codec_gen.go create mode 100644 pkg/apis/dashboard/v1alpha1/dashboard_metadata_gen.go create mode 100644 pkg/apis/dashboard/v1alpha1/dashboard_object_gen.go create mode 100644 pkg/apis/dashboard/v1alpha1/dashboard_schema_gen.go create mode 100644 pkg/apis/dashboard/v1alpha1/dashboard_spec.go create mode 100644 pkg/apis/dashboard/v1alpha1/dashboard_spec_gen.go create mode 100644 pkg/apis/dashboard/v1alpha1/dashboard_status_gen.go create mode 100644 pkg/apis/dashboard/v1alpha1/deepcopy.go create mode 100644 pkg/apis/dashboard/v2alpha1/constants.go create mode 100644 pkg/apis/dashboard/v2alpha1/dashboard_codec_gen.go create mode 100644 pkg/apis/dashboard/v2alpha1/dashboard_metadata_gen.go create mode 100644 pkg/apis/dashboard/v2alpha1/dashboard_object_gen.go create mode 100644 pkg/apis/dashboard/v2alpha1/dashboard_schema_gen.go create mode 100644 pkg/apis/dashboard/v2alpha1/dashboard_spec_gen.go create mode 100644 pkg/apis/dashboard/v2alpha1/dashboard_status_gen.go create mode 100644 pkg/apis/dashboard/v2alpha1/deepcopy.go create mode 100644 pkg/apis/dashboard_manifest.go diff --git a/.betterer.results b/.betterer.results index c0486d07719..b03dac144aa 100644 --- a/.betterer.results +++ b/.betterer.results @@ -5,6 +5,12 @@ // exports[`better eslint`] = { value: `{ + "apps/dashboard/tshack/v0alpha1_spec_gen.ts:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] + ], + "apps/dashboard/tshack/v1alpha1_spec_gen.ts:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] + ], "e2e/old-arch/utils/support/types.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 65f706f256e..7ff10207c35 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -71,6 +71,7 @@ /pkg/registry/apis/provisioning @grafana/grafana-git-ui-sync-team /apps/alerting/ @grafana/alerting-backend +/apps/dashboard/ @grafana/grafana-app-platform-squad @grafana/dashboards-squad /apps/playlist/ @grafana/grafana-app-platform-squad /apps/investigations/ @fcjack @matryer @svennergr /apps/advisor/ @grafana/plugins-platform-backend diff --git a/.prettierignore b/.prettierignore index 8bf9dc13276..23d9231bc49 100644 --- a/.prettierignore +++ b/.prettierignore @@ -19,6 +19,9 @@ vendor # TS generate from cue by cuetsy **/*.gen.ts +# TS generated by grafana-app-sdk +**/*_gen.ts + # Auto-generated theme files theme.light.generated.json theme.dark.generated.json diff --git a/apps/dashboard/Makefile b/apps/dashboard/Makefile new file mode 100644 index 00000000000..d95e25e1abd --- /dev/null +++ b/apps/dashboard/Makefile @@ -0,0 +1,18 @@ +.PHONY: generate +generate: + @grafana-app-sdk generate \ + --source=./kinds/ \ + --gogenpath=../../pkg/apis \ + --tsgenpath=../../packages/grafana-schema/src/schema \ + --grouping=group \ + --defencoding=none \ + --genoperatorstate=false \ + --noschemasinmanifest + + # This is a workaround for SDK codegen not producing correct output for v0alpha1 + @rm ../../packages/grafana-schema/src/schema/dashboard/v0alpha1/types.spec.gen.ts + @cp ./tshack/v0alpha1_spec_gen.ts ../../packages/grafana-schema/src/schema/dashboard/v0alpha1/types.spec.gen.ts + + # Same for v1alpha1 + @rm ../../packages/grafana-schema/src/schema/dashboard/v1alpha1/types.spec.gen.ts + @cp ./tshack/v1alpha1_spec_gen.ts ../../packages/grafana-schema/src/schema/dashboard/v1alpha1/types.spec.gen.ts diff --git a/apps/dashboard/kinds/cue.mod/module.cue b/apps/dashboard/kinds/cue.mod/module.cue new file mode 100644 index 00000000000..a3b88f8aa81 --- /dev/null +++ b/apps/dashboard/kinds/cue.mod/module.cue @@ -0,0 +1,4 @@ +module: "github.com/grafana/grafana/sdkkinds/dashboard" +language: { + version: "v0.9.0" +} diff --git a/apps/dashboard/kinds/dashboard.cue b/apps/dashboard/kinds/dashboard.cue new file mode 100644 index 00000000000..da09322e0e8 --- /dev/null +++ b/apps/dashboard/kinds/dashboard.cue @@ -0,0 +1,68 @@ +package kinds + +import ( + "github.com/grafana/grafana/sdkkinds/dashboard/v0alpha1" + "github.com/grafana/grafana/sdkkinds/dashboard/v1alpha1" + "github.com/grafana/grafana/sdkkinds/dashboard/v2alpha1" +) + +// Status is the shared status of all dashboard versions. +DashboardStatus: { + // Optional conversion status. + conversion?: ConversionStatus +} + +// ConversionStatus is the status of the conversion of the dashboard. +ConversionStatus: { + // Whether from another version has failed. + // If true, means that the dashboard is not valid, + // and the caller should instead fetch the stored version. + failed: bool + + // The version which was stored when the dashboard was created / updated. + // Fetching this version should always succeed. + storedVersion: string + + // The error message from the conversion. + // Empty if the conversion has not failed. + error: string +} + +dashboard: { + kind: "Dashboard" + pluralName: "Dashboards" + current: "v0alpha1" + + codegen: { + ts: { + enabled: true + config: { + enumsAsUnionTypes: true + } + } + go: { + enabled: true + } + } + + versions: { + "v0alpha1": { + schema: { + spec: v0alpha1.DashboardSpec + status: DashboardStatus + } + } + "v1alpha1": { + schema: { + spec: v1alpha1.DashboardSpec + status: DashboardStatus + } + } + "v2alpha1": { + schema: { + spec: v2alpha1.DashboardSpec + status: DashboardStatus + } + } + } +} diff --git a/apps/dashboard/kinds/manifest.cue b/apps/dashboard/kinds/manifest.cue new file mode 100644 index 00000000000..1ec0fb4f21c --- /dev/null +++ b/apps/dashboard/kinds/manifest.cue @@ -0,0 +1,9 @@ +package kinds + +manifest: { + appName: "dashboard" + groupOverride: "dashboard.grafana.app" + kinds: [ + dashboard, + ] +} diff --git a/apps/dashboard/kinds/v0alpha1/dashboard_spec.cue b/apps/dashboard/kinds/v0alpha1/dashboard_spec.cue new file mode 100644 index 00000000000..a59f79e97e9 --- /dev/null +++ b/apps/dashboard/kinds/v0alpha1/dashboard_spec.cue @@ -0,0 +1,6 @@ +package v0alpha1 + +// TODO: this outputs nothing. +// For now, we use unstructured for the spec, +// but it cannot be produced by the SDK codegen. +DashboardSpec: [string]: _ diff --git a/apps/dashboard/kinds/v1alpha1/dashboard_spec.cue b/apps/dashboard/kinds/v1alpha1/dashboard_spec.cue new file mode 100644 index 00000000000..709fb40fd02 --- /dev/null +++ b/apps/dashboard/kinds/v1alpha1/dashboard_spec.cue @@ -0,0 +1,6 @@ +package v1alpha1 + +// TODO: this outputs nothing. +// For now, we use unstructured for the spec, +// but it cannot be produced by the SDK codegen. +DashboardSpec: [string]: _ diff --git a/apps/dashboard/kinds/v2alpha1/dashboard_spec.cue b/apps/dashboard/kinds/v2alpha1/dashboard_spec.cue new file mode 100644 index 00000000000..a1216596268 --- /dev/null +++ b/apps/dashboard/kinds/v2alpha1/dashboard_spec.cue @@ -0,0 +1,923 @@ +package v2alpha1 + +DashboardSpec: { + // Title of dashboard. + annotations: [...AnnotationQueryKind] + + // Configuration of dashboard cursor sync behavior. + // "Off" for no shared crosshair or tooltip (default). + // "Crosshair" for shared crosshair. + // "Tooltip" for shared crosshair AND shared tooltip. + cursorSync: DashboardCursorSync + + // Description of dashboard. + description?: string + + // Whether a dashboard is editable or not. + editable?: bool | *true + + elements: [ElementReference.name]: Element + + layout: GridLayoutKind | RowsLayoutKind | ResponsiveGridLayoutKind | TabsLayoutKind + + // Links with references to other dashboards or external websites. + links: [...DashboardLink] + + // When set to true, the dashboard will redraw panels at an interval matching the pixel width. + // This will keep data "moving left" regardless of the query refresh rate. This setting helps + // avoid dashboards presenting stale live data. + liveNow?: bool + + // When set to true, the dashboard will load all panels in the dashboard when it's loaded. + preload: bool + + // Plugins only. The version of the dashboard installed together with the plugin. + // This is used to determine if the dashboard should be updated when the plugin is updated. + revision?: uint16 + + // Tags associated with dashboard. + tags: [...string] + + timeSettings: TimeSettingsSpec + + // Title of dashboard. + title: string + + // Configured template variables. + variables: [...VariableKind] +} + +// Supported dashboard elements +Element: PanelKind | LibraryPanelKind // |* more element types in the future + +LibraryPanelKind: { + kind: "LibraryPanel" + spec: LibraryPanelKindSpec +} + +LibraryPanelKindSpec: { + // Panel ID for the library panel in the dashboard + id: number + // Title for the library panel in the dashboard + title: string + + libraryPanel: LibraryPanelRef +} + +// A library panel is a reusable panel that you can use in any dashboard. +// When you make a change to a library panel, that change propagates to all instances of where the panel is used. +// Library panels streamline reuse of panels across multiple dashboards. +LibraryPanelRef: { + // Library panel name + name: string + // Library panel uid + uid: string +} + +AnnotationPanelFilter: { + // Should the specified panels be included or excluded + exclude?: bool | *false + + // Panel IDs that should be included or excluded + ids: [...uint8] +} + +// "Off" for no shared crosshair or tooltip (default). +// "Crosshair" for shared crosshair. +// "Tooltip" for shared crosshair AND shared tooltip. +DashboardCursorSync: "Off" | "Crosshair" | "Tooltip" + +// Links with references to other dashboards or external resources +DashboardLink: { + // Title to display with the link + title: string + // Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource) + // FIXME: The type is generated as `type: DashboardLinkType | dashboardLinkType.Link;` but it should be `type: DashboardLinkType` + type: DashboardLinkType + // Icon name to be displayed with the link + icon: string + // Tooltip to display when the user hovers their mouse over it + tooltip: string + // Link URL. Only required/valid if the type is link + url?: string + // List of tags to limit the linked dashboards. If empty, all dashboards will be displayed. Only valid if the type is dashboards + tags: [...string] + // If true, all dashboards links will be displayed in a dropdown. If false, all dashboards links will be displayed side by side. Only valid if the type is dashboards + asDropdown: bool | *false + // If true, the link will be opened in a new tab + targetBlank: bool | *false + // If true, includes current template variables values in the link as query params + includeVars: bool | *false + // If true, includes current time range in the link as query params + keepTime: bool | *false +} + +DataSourceRef: { + // The plugin type-id + type?: string + + // Specific datasource instance + uid?: string +} + +// A topic is attached to DataFrame metadata in query results. +// This specifies where the data should be used. +DataTopic: "series" | "annotations" | "alertStates" @cog(kind="enum",memberNames="Series|Annotations|AlertStates") + +// Transformations allow to manipulate data returned by a query before the system applies a visualization. +// Using transformations you can: rename fields, join time series data, perform mathematical operations across queries, +// use the output of one transformation as the input to another transformation, etc. +DataTransformerConfig: { + // Unique identifier of transformer + id: string + // Disabled transformations are skipped + disabled?: bool + // Optional frame matcher. When missing it will be applied to all results + filter?: MatcherConfig + // Where to pull DataFrames from as input to transformation + topic?: DataTopic + // Options to be passed to the transformer + // Valid options depend on the transformer id + options: _ +} + +DataLink: { + title: string + url: string + targetBlank?: bool +} + +// The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results. +// Each column within this structure is called a field. A field can represent a single time series or table column. +// Field options allow you to change how the data is displayed in your visualizations. +FieldConfigSource: { + // Defaults are the options applied to all fields. + defaults: FieldConfig + // Overrides are the options applied to specific fields overriding the defaults. + overrides: [...{ + matcher: MatcherConfig + properties: [...DynamicConfigValue] + }] +} + +// The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results. +// Each column within this structure is called a field. A field can represent a single time series or table column. +// Field options allow you to change how the data is displayed in your visualizations. +FieldConfig: { + // The display value for this field. This supports template variables blank is auto + displayName?: string + + // This can be used by data sources that return and explicit naming structure for values and labels + // When this property is configured, this value is used rather than the default naming strategy. + displayNameFromDS?: string + + // Human readable field metadata + description?: string + + // An explicit path to the field in the datasource. When the frame meta includes a path, + // This will default to `${frame.meta.path}/${field.name} + // + // When defined, this value can be used as an identifier within the datasource scope, and + // may be used to update the results + path?: string + + // True if data source can write a value to the path. Auth/authz are supported separately + writeable?: bool + + // True if data source field supports ad-hoc filters + filterable?: bool + + // Unit a field should use. The unit you select is applied to all fields except time. + // You can use the units ID availables in Grafana or a custom unit. + // Available units in Grafana: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/valueFormats/categories.ts + // As custom unit, you can use the following formats: + // `suffix:` for custom unit that should go after value. + // `prefix:` for custom unit that should go before value. + // `time:` For custom date time formats type for example `time:YYYY-MM-DD`. + // `si:` for custom SI units. For example: `si: mF`. This one is a bit more advanced as you can specify both a unit and the source data scale. So if your source data is represented as milli (thousands of) something prefix the unit with that SI scale character. + // `count:` for a custom count unit. + // `currency:` for custom a currency unit. + unit?: string + + // Specify the number of decimals Grafana includes in the rendered value. + // If you leave this field blank, Grafana automatically truncates the number of decimals based on the value. + // For example 1.1234 will display as 1.12 and 100.456 will display as 100. + // To display all decimals, set the unit to `String`. + decimals?: number + + // The minimum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields. + min?: number + // The maximum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields. + max?: number + + // Convert input values into a display string + mappings?: [...ValueMapping] + + // Map numeric values to states + thresholds?: ThresholdsConfig + + // Panel color configuration + color?: FieldColor + + // The behavior when clicking on a result + links?: [...] + + // Alternative to empty string + noValue?: string + + // custom is specified by the FieldConfig field + // in panel plugin schemas. + custom?: {...} +} + +DynamicConfigValue: { + id: string | *"" + value?: _ +} + +// Matcher is a predicate configuration. Based on the config a set of field(s) or values is filtered in order to apply override / transformation. +// It comes with in id ( to resolve implementation from registry) and a configuration that’s specific to a particular matcher type. +MatcherConfig: { + // The matcher id. This is used to find the matcher implementation from registry. + id: string | *"" + // The matcher options. This is specific to the matcher implementation. + options?: _ +} + +Threshold: { + value: number + color: string +} + +ThresholdsMode: "absolute" | "percentage" + +ThresholdsConfig: { + mode: ThresholdsMode + steps: [...Threshold] +} + +ValueMapping: ValueMap | RangeMap | RegexMap | SpecialValueMap + +// Supported value mapping types +// `value`: Maps text values to a color or different display text and color. For example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number. +// `range`: Maps numerical ranges to a display text and color. For example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number. +// `regex`: Maps regular expressions to replacement text and a color. For example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain. +// `special`: Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color. See SpecialValueMatch to see the list of special values. For example, you can configure a special value mapping so that null values appear as N/A. +MappingType: "value" | "range" | "regex" | "special" @cog(kind="enum",memberNames="ValueToText|RangeToText|RegexToText|SpecialValue") + +// Maps text values to a color or different display text and color. +// For example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number. +ValueMap: { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "value" + type: "value" + // Map with : ValueMappingResult. For example: { "10": { text: "Perfection!", color: "green" } } + options: [string]: ValueMappingResult +} + +// Maps numerical ranges to a display text and color. +// For example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number. +RangeMap: { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "range" + type: "range" + // Range to match against and the result to apply when the value is within the range + options: { + // Min value of the range. It can be null which means -Infinity + from: float64 | null + // Max value of the range. It can be null which means +Infinity + to: float64 | null + // Config to apply when the value is within the range + result: ValueMappingResult + } +} + +// Maps regular expressions to replacement text and a color. +// For example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain. +RegexMap: { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "regex" + type: "regex" + // Regular expression to match against and the result to apply when the value matches the regex + options: { + // Regular expression to match against + pattern: string + // Config to apply when the value matches the regex + result: ValueMappingResult + } +} + +// Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color. +// See SpecialValueMatch to see the list of special values. +// For example, you can configure a special value mapping so that null values appear as N/A. +SpecialValueMap: { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "special" + type: "special" + options: { + // Special value to match against + match: SpecialValueMatch + // Config to apply when the value matches the special value + result: ValueMappingResult + } +} + +// Special value types supported by the `SpecialValueMap` +SpecialValueMatch: "true" | "false" | "null" | "nan" | "null+nan" | "empty" @cog(kind="enum",memberNames="True|False|Null|NaN|NullAndNaN|Empty") + +// Result used as replacement with text and color when the value matches +ValueMappingResult: { + // Text to display when the value matches + text?: string + // Text to use when the value matches + color?: string + // Icon to display when the value matches. Only specific visualizations. + icon?: string + // Position in the mapping array. Only used internally. + index?: int32 +} + +// Color mode for a field. You can specify a single color, or select a continuous (gradient) color schemes, based on a value. +// Continuous color interpolates a color using the percentage of a value relative to min and max. +// Accepted values are: +// `thresholds`: From thresholds. Informs Grafana to take the color from the matching threshold +// `palette-classic`: Classic palette. Grafana will assign color by looking up a color in a palette by series index. Useful for Graphs and pie charts and other categorical data visualizations +// `palette-classic-by-name`: Classic palette (by name). Grafana will assign color by looking up a color in a palette by series name. Useful for Graphs and pie charts and other categorical data visualizations +// `continuous-GrYlRd`: ontinuous Green-Yellow-Red palette mode +// `continuous-RdYlGr`: Continuous Red-Yellow-Green palette mode +// `continuous-BlYlRd`: Continuous Blue-Yellow-Red palette mode +// `continuous-YlRd`: Continuous Yellow-Red palette mode +// `continuous-BlPu`: Continuous Blue-Purple palette mode +// `continuous-YlBl`: Continuous Yellow-Blue palette mode +// `continuous-blues`: Continuous Blue palette mode +// `continuous-reds`: Continuous Red palette mode +// `continuous-greens`: Continuous Green palette mode +// `continuous-purples`: Continuous Purple palette mode +// `shades`: Shades of a single color. Specify a single color, useful in an override rule. +// `fixed`: Fixed color mode. Specify a single color, useful in an override rule. +FieldColorModeId: "thresholds" | "palette-classic" | "palette-classic-by-name" | "continuous-GrYlRd" | "continuous-RdYlGr" | "continuous-BlYlRd" | "continuous-YlRd" | "continuous-BlPu" | "continuous-YlBl" | "continuous-blues" | "continuous-reds" | "continuous-greens" | "continuous-purples" | "fixed" | "shades" + +// Defines how to assign a series color from "by value" color schemes. For example for an aggregated data points like a timeseries, the color can be assigned by the min, max or last value. +FieldColorSeriesByMode: "min" | "max" | "last" + +// Map a field to a color. +FieldColor: { + // The main color scheme mode. + mode: FieldColorModeId + // The fixed color value for fixed or shades color modes. + fixedColor?: string + // Some visualizations need to know how to assign a series color from by value color schemes. + seriesBy?: FieldColorSeriesByMode +} + +// Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource) +DashboardLinkType: "link" | "dashboards" + +// --- Common types --- +Kind: { + kind: string + spec: _ + metadata?: _ +} + +// --- Kinds --- +VizConfigSpec: { + pluginVersion: string + options: [string]: _ + fieldConfig: FieldConfigSource +} + +VizConfigKind: { + // The kind of a VizConfigKind is the plugin ID + kind: string + spec: VizConfigSpec +} + +AnnotationQuerySpec: { + datasource?: DataSourceRef + query?: DataQueryKind + enable: bool + hide: bool + iconColor: string + name: string + builtIn?: bool | *false + filter?: AnnotationPanelFilter +} + +AnnotationQueryKind: { + kind: "AnnotationQuery" + spec: AnnotationQuerySpec +} + +QueryOptionsSpec: { + timeFrom?: string + maxDataPoints?: int + timeShift?: string + queryCachingTTL?: int + interval?: string + cacheTimeout?: string + hideTimeOverride?: bool +} + +DataQueryKind: { + // The kind of a DataQueryKind is the datasource type + kind: string + spec: [string]: _ +} + +PanelQuerySpec: { + query: DataQueryKind + datasource?: DataSourceRef + + refId: string + hidden: bool +} + +PanelQueryKind: { + kind: "PanelQuery" + spec: PanelQuerySpec +} + +TransformationKind: { + // The kind of a TransformationKind is the transformation ID + kind: string + spec: DataTransformerConfig +} + +QueryGroupSpec: { + queries: [...PanelQueryKind] + transformations: [...TransformationKind] + queryOptions: QueryOptionsSpec +} + +QueryGroupKind: { + kind: "QueryGroup" + spec: QueryGroupSpec +} + +TimeRangeOption: { + display: string | *"Last 6 hours" + from: string | *"now-6h" + to: string | *"now" +} + +// Time configuration +// It defines the default time config for the time picker, the refresh picker for the specific dashboard. +TimeSettingsSpec: { + // Timezone of dashboard. Accepted values are IANA TZDB zone ID or "browser" or "utc". + timezone?: string | *"browser" + // Start time range for dashboard. + // Accepted values are relative time strings like "now-6h" or absolute time strings like "2020-07-10T08:00:00.000Z". + from: string | *"now-6h" + // End time range for dashboard. + // Accepted values are relative time strings like "now-6h" or absolute time strings like "2020-07-10T08:00:00.000Z". + to: string | *"now" + // Refresh rate of dashboard. Represented via interval string, e.g. "5s", "1m", "1h", "1d". + autoRefresh: string // v1: refresh + // Interval options available in the refresh picker dropdown. + autoRefreshIntervals: [...string] | *["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] // v1: timepicker.refresh_intervals + // Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard. + quickRanges?: [...TimeRangeOption] // v1: timepicker.quick_ranges , not exposed in the UI + // Whether timepicker is visible or not. + hideTimepicker: bool // v1: timepicker.hidden + // Day when the week starts. Expressed by the name of the day in lowercase, e.g. "monday". + weekStart?: "saturday" | "monday" | "sunday" + // The month that the fiscal year starts on. 0 = January, 11 = December + fiscalYearStartMonth: int + // Override the now time by entering a time delay. Use this option to accommodate known delays in data aggregation to avoid null values. + nowDelay?: string // v1: timepicker.nowDelay +} + +RepeatMode: "variable" // other repeat modes will be added in the future: label, frame + +RepeatOptions: { + mode: RepeatMode + value: string + direction?: "h" | "v" + maxPerRow?: int +} + +RowRepeatOptions: { + mode: RepeatMode + value: string +} + +ResponsiveGridRepeatOptions: { + mode: RepeatMode + value: string +} + +GridLayoutItemSpec: { + x: int + y: int + width: int + height: int + element: ElementReference // reference to a PanelKind from dashboard.spec.elements Expressed as JSON Schema reference + repeat?: RepeatOptions +} + +GridLayoutItemKind: { + kind: "GridLayoutItem" + spec: GridLayoutItemSpec +} + +GridLayoutRowKind: { + kind: "GridLayoutRow" + spec: GridLayoutRowSpec +} + +GridLayoutRowSpec: { + y: int + collapsed: bool + title: string + elements: [...GridLayoutItemKind] // Grid items in the row will have their Y value be relative to the rows Y value. This means a panel positioned at Y: 0 in a row with Y: 10 will be positioned at Y: 11 (row header has a heigh of 1) in the dashboard. + repeat?: RowRepeatOptions +} + +GridLayoutSpec: { + items: [...GridLayoutItemKind | GridLayoutRowKind] +} + +GridLayoutKind: { + kind: "GridLayout" + spec: GridLayoutSpec +} + +RowsLayoutKind: { + kind: "RowsLayout" + spec: RowsLayoutSpec +} + +RowsLayoutSpec: { + rows: [...RowsLayoutRowKind] +} + +RowsLayoutRowKind: { + kind: "RowsLayoutRow" + spec: RowsLayoutRowSpec +} + +RowsLayoutRowSpec: { + title?: string + collapsed: bool + repeat?: RowRepeatOptions + layout: GridLayoutKind | ResponsiveGridLayoutKind | TabsLayoutKind +} + +ResponsiveGridLayoutKind: { + kind: "ResponsiveGridLayout" + spec: ResponsiveGridLayoutSpec +} + +ResponsiveGridLayoutSpec: { + row: string + col: string + items: [...ResponsiveGridLayoutItemKind] +} + +ResponsiveGridLayoutItemKind: { + kind: "ResponsiveGridLayoutItem" + spec: ResponsiveGridLayoutItemSpec +} + +ResponsiveGridLayoutItemSpec: { + element: ElementReference + repeat?: ResponsiveGridRepeatOptions +} + +TabsLayoutKind: { + kind: "TabsLayout" + spec: TabsLayoutSpec +} + +TabsLayoutSpec: { + tabs: [...TabsLayoutTabKind] +} + +TabsLayoutTabKind: { + kind: "TabsLayoutTab" + spec: TabsLayoutTabSpec +} + +TabsLayoutTabSpec: { + title?: string + layout: GridLayoutKind | RowsLayoutKind | ResponsiveGridLayoutKind +} + +PanelSpec: { + id: number + title: string + description: string + links: [...DataLink] + data: QueryGroupKind + vizConfig: VizConfigKind + transparent?: bool +} + +PanelKind: { + kind: "Panel" + spec: PanelSpec +} + +ElementReference: { + kind: "ElementReference" + name: string +} + +// Start FIXME: variables - in CUE PR - this are things that should be added into the cue schema +// TODO: properties such as `hide`, `skipUrlSync`, `multi` are type boolean, and in the old schema they are conditional, +// should we make them conditional in the new schema as well? or should we make them required but default to false? + +// Variable types +VariableValue: VariableValueSingle | [...VariableValueSingle] + +VariableValueSingle: string | bool | number | CustomVariableValue + +// Custom formatter variable +CustomFormatterVariable: { + name: string + type: VariableType + multi: bool + includeAll: bool +} + +// Custom variable value +CustomVariableValue: { + // The format name or function used in the expression + formatter: *null | string | VariableCustomFormatterFn +} + +// Custom formatter function +VariableCustomFormatterFn: { + value: _ + legacyVariableModel: { + name: string + type: VariableType + multi: bool + includeAll: bool + } + legacyDefaultFormatter?: VariableCustomFormatterFn +} + +// Dashboard variable type +// `query`: Query-generated list of values such as metric names, server names, sensor IDs, data centers, and so on. +// `adhoc`: Key/value filters that are automatically added to all metric queries for a data source (Prometheus, Loki, InfluxDB, and Elasticsearch only). +// `constant`: Define a hidden constant. +// `datasource`: Quickly change the data source for an entire dashboard. +// `interval`: Interval variables represent time spans. +// `textbox`: Display a free text input field with an optional default value. +// `custom`: Define the variable options manually using a comma-separated list. +// `system`: Variables defined by Grafana. See: https://grafana.com/docs/grafana/latest/dashboards/variables/add-template-variables/#global-variables +VariableType: "query" | "adhoc" | "groupby" | "constant" | "datasource" | "interval" | "textbox" | "custom" | + "system" | "snapshot" + +VariableKind: QueryVariableKind | TextVariableKind | ConstantVariableKind | DatasourceVariableKind | IntervalVariableKind | CustomVariableKind | GroupByVariableKind | AdhocVariableKind + +// Sort variable options +// Accepted values are: +// `disabled`: No sorting +// `alphabeticalAsc`: Alphabetical ASC +// `alphabeticalDesc`: Alphabetical DESC +// `numericalAsc`: Numerical ASC +// `numericalDesc`: Numerical DESC +// `alphabeticalCaseInsensitiveAsc`: Alphabetical Case Insensitive ASC +// `alphabeticalCaseInsensitiveDesc`: Alphabetical Case Insensitive DESC +// `naturalAsc`: Natural ASC +// `naturalDesc`: Natural DESC +// VariableSort enum with default value +VariableSort: "disabled" | "alphabeticalAsc" | "alphabeticalDesc" | "numericalAsc" | "numericalDesc" | "alphabeticalCaseInsensitiveAsc" | "alphabeticalCaseInsensitiveDesc" | "naturalAsc" | "naturalDesc" + +// Options to config when to refresh a variable +// `never`: Never refresh the variable +// `onDashboardLoad`: Queries the data source every time the dashboard loads. +// `onTimeRangeChanged`: Queries the data source when the dashboard time range changes. +VariableRefresh: *"never" | "onDashboardLoad" | "onTimeRangeChanged" + +// Determine if the variable shows on dashboard +// Accepted values are `dontHide` (show label and value), `hideLabel` (show value only), `hideVariable` (show nothing). +VariableHide: *"dontHide" | "hideLabel" | "hideVariable" + +// FIXME: should we introduce this? --- Variable value option +VariableValueOption: { + label: string + value: VariableValueSingle + group?: string +} + +// Variable option specification +VariableOption: { + // Whether the option is selected or not + selected?: bool + // Text to be displayed for the option + text: string | [...string] + // Value of the option + value: string | [...string] +} + +// Query variable specification +QueryVariableSpec: { + name: string | *"" + current: VariableOption | *{ + text: "" + value: "" + } + label?: string + hide: VariableHide + refresh: VariableRefresh + skipUrlSync: bool | *false + description?: string + datasource?: DataSourceRef + query: DataQueryKind + regex: string | *"" + sort: VariableSort + definition?: string + options: [...VariableOption] | *[] + multi: bool | *false + includeAll: bool | *false + allValue?: string + placeholder?: string +} + +// Query variable kind +QueryVariableKind: { + kind: "QueryVariable" + spec: QueryVariableSpec +} + +// Text variable specification +TextVariableSpec: { + name: string | *"" + current: VariableOption | *{ + text: "" + value: "" + } + query: string | *"" + label?: string + hide: VariableHide + skipUrlSync: bool | *false + description?: string +} + +// Text variable kind +TextVariableKind: { + kind: "TextVariable" + spec: TextVariableSpec +} + +// Constant variable specification +ConstantVariableSpec: { + name: string | *"" + query: string | *"" + current: VariableOption | *{ + text: "" + value: "" + } + label?: string + hide: VariableHide + skipUrlSync: bool | *false + description?: string +} + +// Constant variable kind +ConstantVariableKind: { + kind: "ConstantVariable" + spec: ConstantVariableSpec +} + +// Datasource variable specification +DatasourceVariableSpec: { + name: string | *"" + pluginId: string | *"" + refresh: VariableRefresh + regex: string | *"" + current: VariableOption | *{ + text: "" + value: "" + } + options: [...VariableOption] | *[] + multi: bool | *false + includeAll: bool | *false + allValue?: string + label?: string + hide: VariableHide + skipUrlSync: bool | *false + description?: string +} + +// Datasource variable kind +DatasourceVariableKind: { + kind: "DatasourceVariable" + spec: DatasourceVariableSpec +} + +// Interval variable specification +IntervalVariableSpec: { + name: string | *"" + query: string | *"" + current: VariableOption | *{ + text: "" + value: "" + } + options: [...VariableOption] | *[] + auto: bool | *false + auto_min: string | *"" + auto_count: int | *0 + refresh: VariableRefresh + label?: string + hide: VariableHide + skipUrlSync: bool | *false + description?: string +} + +// Interval variable kind +IntervalVariableKind: { + kind: "IntervalVariable" + spec: IntervalVariableSpec +} + +// Custom variable specification +CustomVariableSpec: { + name: string | *"" + query: string | *"" + current: VariableOption + options: [...VariableOption] | *[] + multi: bool | *false + includeAll: bool | *false + allValue?: string + label?: string + hide: VariableHide + skipUrlSync: bool | *false + description?: string +} + +// Custom variable kind +CustomVariableKind: { + kind: "CustomVariable" + spec: CustomVariableSpec +} + +// GroupBy variable specification +GroupByVariableSpec: { + name: string | *"" + datasource?: DataSourceRef + current: VariableOption | *{ + text: "" + value: "" + } + options: [...VariableOption] | *[] + multi: bool | *false + label?: string + hide: VariableHide + skipUrlSync: bool | *false + description?: string +} + +// Group variable kind +GroupByVariableKind: { + kind: "GroupByVariable" + spec: GroupByVariableSpec +} + +// Adhoc variable specification +AdhocVariableSpec: { + name: string | *"" + datasource?: DataSourceRef + baseFilters: [...AdHocFilterWithLabels] | *[] + filters: [...AdHocFilterWithLabels] | *[] + defaultKeys: [...MetricFindValue] | *[] + label?: string + hide: VariableHide + skipUrlSync: bool | *false + description?: string +} + +// Define the MetricFindValue type +MetricFindValue: { + text: string + value?: string | number + group?: string + expandable?: bool +} + +// Define the AdHocFilterWithLabels type +AdHocFilterWithLabels: { + key: string + operator: string + value: string + values?: [...string] + keyLabel?: string + valueLabels?: [...string] + forceEdit?: bool + // @deprecated + condition?: string +} + +// Adhoc variable kind +AdhocVariableKind: { + kind: "AdhocVariable" + spec: AdhocVariableSpec +} diff --git a/apps/dashboard/tshack/v0alpha1_spec_gen.ts b/apps/dashboard/tshack/v0alpha1_spec_gen.ts new file mode 100644 index 00000000000..3de7e52c72e --- /dev/null +++ b/apps/dashboard/tshack/v0alpha1_spec_gen.ts @@ -0,0 +1,7 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +export interface Spec { + [key: string]: any; +} + +export const defaultSpec = (): Spec => ({}); diff --git a/apps/dashboard/tshack/v1alpha1_spec_gen.ts b/apps/dashboard/tshack/v1alpha1_spec_gen.ts new file mode 100644 index 00000000000..3de7e52c72e --- /dev/null +++ b/apps/dashboard/tshack/v1alpha1_spec_gen.ts @@ -0,0 +1,7 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +export interface Spec { + [key: string]: any; +} + +export const defaultSpec = (): Spec => ({}); diff --git a/packages/grafana-schema/src/schema/dashboard/v0alpha1/dashboard_object_gen.ts b/packages/grafana-schema/src/schema/dashboard/v0alpha1/dashboard_object_gen.ts new file mode 100644 index 00000000000..a89d50ebd2d --- /dev/null +++ b/packages/grafana-schema/src/schema/dashboard/v0alpha1/dashboard_object_gen.ts @@ -0,0 +1,49 @@ +/* + * This file was generated by grafana-app-sdk. DO NOT EDIT. + */ +import { Spec } from './types.spec.gen'; +import { Status } from './types.status.gen'; + +export interface Metadata { + name: string; + namespace: string; + generateName?: string; + selfLink?: string; + uid?: string; + resourceVersion?: string; + generation?: number; + creationTimestamp?: string; + deletionTimestamp?: string; + deletionGracePeriodSeconds?: number; + labels?: Record; + annotations?: Record; + ownerReferences?: OwnerReference[]; + finalizers?: string[]; + managedFields?: ManagedFieldsEntry[]; +} + +export interface OwnerReference { + apiVersion: string; + kind: string; + name: string; + uid: string; + controller?: boolean; + blockOwnerDeletion?: boolean; +} + +export interface ManagedFieldsEntry { + manager?: string; + operation?: string; + apiVersion?: string; + time?: string; + fieldsType?: string; + subresource?: string; +} + +export interface Dashboard { + kind: string; + apiVersion: string; + metadata: Metadata; + spec: Spec; + status: Status; +} diff --git a/packages/grafana-schema/src/schema/dashboard/v0alpha1/types.metadata.gen.ts b/packages/grafana-schema/src/schema/dashboard/v0alpha1/types.metadata.gen.ts new file mode 100644 index 00000000000..4377f3c1d08 --- /dev/null +++ b/packages/grafana-schema/src/schema/dashboard/v0alpha1/types.metadata.gen.ts @@ -0,0 +1,30 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +// metadata contains embedded CommonMetadata and can be extended with custom string fields +// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here +// without external reference as using the CommonMetadata reference breaks thema codegen. +export interface Metadata { + updateTimestamp: string; + createdBy: string; + uid: string; + creationTimestamp: string; + deletionTimestamp?: string; + finalizers: string[]; + resourceVersion: string; + generation: number; + updatedBy: string; + labels: Record; +} + +export const defaultMetadata = (): Metadata => ({ + updateTimestamp: "", + createdBy: "", + uid: "", + creationTimestamp: "", + finalizers: [], + resourceVersion: "", + generation: 0, + updatedBy: "", + labels: {}, +}); + diff --git a/packages/grafana-schema/src/schema/dashboard/v0alpha1/types.spec.gen.ts b/packages/grafana-schema/src/schema/dashboard/v0alpha1/types.spec.gen.ts new file mode 100644 index 00000000000..3de7e52c72e --- /dev/null +++ b/packages/grafana-schema/src/schema/dashboard/v0alpha1/types.spec.gen.ts @@ -0,0 +1,7 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +export interface Spec { + [key: string]: any; +} + +export const defaultSpec = (): Spec => ({}); diff --git a/packages/grafana-schema/src/schema/dashboard/v0alpha1/types.status.gen.ts b/packages/grafana-schema/src/schema/dashboard/v0alpha1/types.status.gen.ts new file mode 100644 index 00000000000..29494dfaf24 --- /dev/null +++ b/packages/grafana-schema/src/schema/dashboard/v0alpha1/types.status.gen.ts @@ -0,0 +1,30 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +// ConversionStatus is the status of the conversion of the dashboard. +export interface ConversionStatus { + // Whether from another version has failed. + // If true, means that the dashboard is not valid, + // and the caller should instead fetch the stored version. + failed: boolean; + // The version which was stored when the dashboard was created / updated. + // Fetching this version should always succeed. + storedVersion: string; + // The error message from the conversion. + // Empty if the conversion has not failed. + error: string; +} + +export const defaultConversionStatus = (): ConversionStatus => ({ + failed: false, + storedVersion: "", + error: "", +}); + +export interface Status { + // Optional conversion status. + conversion?: ConversionStatus; +} + +export const defaultStatus = (): Status => ({ +}); + diff --git a/packages/grafana-schema/src/schema/dashboard/v1alpha1/dashboard_object_gen.ts b/packages/grafana-schema/src/schema/dashboard/v1alpha1/dashboard_object_gen.ts new file mode 100644 index 00000000000..a89d50ebd2d --- /dev/null +++ b/packages/grafana-schema/src/schema/dashboard/v1alpha1/dashboard_object_gen.ts @@ -0,0 +1,49 @@ +/* + * This file was generated by grafana-app-sdk. DO NOT EDIT. + */ +import { Spec } from './types.spec.gen'; +import { Status } from './types.status.gen'; + +export interface Metadata { + name: string; + namespace: string; + generateName?: string; + selfLink?: string; + uid?: string; + resourceVersion?: string; + generation?: number; + creationTimestamp?: string; + deletionTimestamp?: string; + deletionGracePeriodSeconds?: number; + labels?: Record; + annotations?: Record; + ownerReferences?: OwnerReference[]; + finalizers?: string[]; + managedFields?: ManagedFieldsEntry[]; +} + +export interface OwnerReference { + apiVersion: string; + kind: string; + name: string; + uid: string; + controller?: boolean; + blockOwnerDeletion?: boolean; +} + +export interface ManagedFieldsEntry { + manager?: string; + operation?: string; + apiVersion?: string; + time?: string; + fieldsType?: string; + subresource?: string; +} + +export interface Dashboard { + kind: string; + apiVersion: string; + metadata: Metadata; + spec: Spec; + status: Status; +} diff --git a/packages/grafana-schema/src/schema/dashboard/v1alpha1/types.metadata.gen.ts b/packages/grafana-schema/src/schema/dashboard/v1alpha1/types.metadata.gen.ts new file mode 100644 index 00000000000..4377f3c1d08 --- /dev/null +++ b/packages/grafana-schema/src/schema/dashboard/v1alpha1/types.metadata.gen.ts @@ -0,0 +1,30 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +// metadata contains embedded CommonMetadata and can be extended with custom string fields +// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here +// without external reference as using the CommonMetadata reference breaks thema codegen. +export interface Metadata { + updateTimestamp: string; + createdBy: string; + uid: string; + creationTimestamp: string; + deletionTimestamp?: string; + finalizers: string[]; + resourceVersion: string; + generation: number; + updatedBy: string; + labels: Record; +} + +export const defaultMetadata = (): Metadata => ({ + updateTimestamp: "", + createdBy: "", + uid: "", + creationTimestamp: "", + finalizers: [], + resourceVersion: "", + generation: 0, + updatedBy: "", + labels: {}, +}); + diff --git a/packages/grafana-schema/src/schema/dashboard/v1alpha1/types.spec.gen.ts b/packages/grafana-schema/src/schema/dashboard/v1alpha1/types.spec.gen.ts new file mode 100644 index 00000000000..3de7e52c72e --- /dev/null +++ b/packages/grafana-schema/src/schema/dashboard/v1alpha1/types.spec.gen.ts @@ -0,0 +1,7 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +export interface Spec { + [key: string]: any; +} + +export const defaultSpec = (): Spec => ({}); diff --git a/packages/grafana-schema/src/schema/dashboard/v1alpha1/types.status.gen.ts b/packages/grafana-schema/src/schema/dashboard/v1alpha1/types.status.gen.ts new file mode 100644 index 00000000000..29494dfaf24 --- /dev/null +++ b/packages/grafana-schema/src/schema/dashboard/v1alpha1/types.status.gen.ts @@ -0,0 +1,30 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +// ConversionStatus is the status of the conversion of the dashboard. +export interface ConversionStatus { + // Whether from another version has failed. + // If true, means that the dashboard is not valid, + // and the caller should instead fetch the stored version. + failed: boolean; + // The version which was stored when the dashboard was created / updated. + // Fetching this version should always succeed. + storedVersion: string; + // The error message from the conversion. + // Empty if the conversion has not failed. + error: string; +} + +export const defaultConversionStatus = (): ConversionStatus => ({ + failed: false, + storedVersion: "", + error: "", +}); + +export interface Status { + // Optional conversion status. + conversion?: ConversionStatus; +} + +export const defaultStatus = (): Status => ({ +}); + diff --git a/packages/grafana-schema/src/schema/dashboard/v2alpha1/dashboard_object_gen.ts b/packages/grafana-schema/src/schema/dashboard/v2alpha1/dashboard_object_gen.ts new file mode 100644 index 00000000000..a89d50ebd2d --- /dev/null +++ b/packages/grafana-schema/src/schema/dashboard/v2alpha1/dashboard_object_gen.ts @@ -0,0 +1,49 @@ +/* + * This file was generated by grafana-app-sdk. DO NOT EDIT. + */ +import { Spec } from './types.spec.gen'; +import { Status } from './types.status.gen'; + +export interface Metadata { + name: string; + namespace: string; + generateName?: string; + selfLink?: string; + uid?: string; + resourceVersion?: string; + generation?: number; + creationTimestamp?: string; + deletionTimestamp?: string; + deletionGracePeriodSeconds?: number; + labels?: Record; + annotations?: Record; + ownerReferences?: OwnerReference[]; + finalizers?: string[]; + managedFields?: ManagedFieldsEntry[]; +} + +export interface OwnerReference { + apiVersion: string; + kind: string; + name: string; + uid: string; + controller?: boolean; + blockOwnerDeletion?: boolean; +} + +export interface ManagedFieldsEntry { + manager?: string; + operation?: string; + apiVersion?: string; + time?: string; + fieldsType?: string; + subresource?: string; +} + +export interface Dashboard { + kind: string; + apiVersion: string; + metadata: Metadata; + spec: Spec; + status: Status; +} diff --git a/packages/grafana-schema/src/schema/dashboard/v2alpha1/types.metadata.gen.ts b/packages/grafana-schema/src/schema/dashboard/v2alpha1/types.metadata.gen.ts new file mode 100644 index 00000000000..4377f3c1d08 --- /dev/null +++ b/packages/grafana-schema/src/schema/dashboard/v2alpha1/types.metadata.gen.ts @@ -0,0 +1,30 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +// metadata contains embedded CommonMetadata and can be extended with custom string fields +// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here +// without external reference as using the CommonMetadata reference breaks thema codegen. +export interface Metadata { + updateTimestamp: string; + createdBy: string; + uid: string; + creationTimestamp: string; + deletionTimestamp?: string; + finalizers: string[]; + resourceVersion: string; + generation: number; + updatedBy: string; + labels: Record; +} + +export const defaultMetadata = (): Metadata => ({ + updateTimestamp: "", + createdBy: "", + uid: "", + creationTimestamp: "", + finalizers: [], + resourceVersion: "", + generation: 0, + updatedBy: "", + labels: {}, +}); + diff --git a/packages/grafana-schema/src/schema/dashboard/v2alpha1/types.spec.gen.ts b/packages/grafana-schema/src/schema/dashboard/v2alpha1/types.spec.gen.ts new file mode 100644 index 00000000000..477ec4e63ad --- /dev/null +++ b/packages/grafana-schema/src/schema/dashboard/v2alpha1/types.spec.gen.ts @@ -0,0 +1,1316 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +export interface AnnotationQueryKind { + kind: "AnnotationQuery"; + spec: AnnotationQuerySpec; +} + +export const defaultAnnotationQueryKind = (): AnnotationQueryKind => ({ + kind: "AnnotationQuery", + spec: defaultAnnotationQuerySpec(), +}); + +export interface AnnotationQuerySpec { + datasource?: DataSourceRef; + query?: DataQueryKind; + enable: boolean; + hide: boolean; + iconColor: string; + name: string; + builtIn?: boolean; + filter?: AnnotationPanelFilter; +} + +export const defaultAnnotationQuerySpec = (): AnnotationQuerySpec => ({ + enable: false, + hide: false, + iconColor: "", + name: "", + builtIn: false, +}); + +export interface DataSourceRef { + // The plugin type-id + type?: string; + // Specific datasource instance + uid?: string; +} + +export const defaultDataSourceRef = (): DataSourceRef => ({ +}); + +export interface DataQueryKind { + // The kind of a DataQueryKind is the datasource type + kind: string; + spec: Record; +} + +export const defaultDataQueryKind = (): DataQueryKind => ({ + kind: "", + spec: {}, +}); + +export interface AnnotationPanelFilter { + // Should the specified panels be included or excluded + exclude?: boolean; + // Panel IDs that should be included or excluded + ids: number[]; +} + +export const defaultAnnotationPanelFilter = (): AnnotationPanelFilter => ({ + exclude: false, + ids: [], +}); + +// "Off" for no shared crosshair or tooltip (default). +// "Crosshair" for shared crosshair. +// "Tooltip" for shared crosshair AND shared tooltip. +export type DashboardCursorSync = "Off" | "Crosshair" | "Tooltip"; + +export const defaultDashboardCursorSync = (): DashboardCursorSync => ("Off"); + +// Supported dashboard elements +// |* more element types in the future +export type Element = PanelKind | LibraryPanelKind; + +export const defaultElement = (): Element => (defaultPanelKind()); + +export interface PanelKind { + kind: "Panel"; + spec: PanelSpec; +} + +export const defaultPanelKind = (): PanelKind => ({ + kind: "Panel", + spec: defaultPanelSpec(), +}); + +export interface PanelSpec { + id: number; + title: string; + description: string; + links: DataLink[]; + data: QueryGroupKind; + vizConfig: VizConfigKind; + transparent?: boolean; +} + +export const defaultPanelSpec = (): PanelSpec => ({ + id: 0, + title: "", + description: "", + links: [], + data: defaultQueryGroupKind(), + vizConfig: defaultVizConfigKind(), +}); + +export interface DataLink { + title: string; + url: string; + targetBlank?: boolean; +} + +export const defaultDataLink = (): DataLink => ({ + title: "", + url: "", +}); + +export interface QueryGroupKind { + kind: "QueryGroup"; + spec: QueryGroupSpec; +} + +export const defaultQueryGroupKind = (): QueryGroupKind => ({ + kind: "QueryGroup", + spec: defaultQueryGroupSpec(), +}); + +export interface QueryGroupSpec { + queries: PanelQueryKind[]; + transformations: TransformationKind[]; + queryOptions: QueryOptionsSpec; +} + +export const defaultQueryGroupSpec = (): QueryGroupSpec => ({ + queries: [], + transformations: [], + queryOptions: defaultQueryOptionsSpec(), +}); + +export interface PanelQueryKind { + kind: "PanelQuery"; + spec: PanelQuerySpec; +} + +export const defaultPanelQueryKind = (): PanelQueryKind => ({ + kind: "PanelQuery", + spec: defaultPanelQuerySpec(), +}); + +export interface PanelQuerySpec { + query: DataQueryKind; + datasource?: DataSourceRef; + refId: string; + hidden: boolean; +} + +export const defaultPanelQuerySpec = (): PanelQuerySpec => ({ + query: defaultDataQueryKind(), + refId: "", + hidden: false, +}); + +export interface TransformationKind { + // The kind of a TransformationKind is the transformation ID + kind: string; + spec: DataTransformerConfig; +} + +export const defaultTransformationKind = (): TransformationKind => ({ + kind: "", + spec: defaultDataTransformerConfig(), +}); + +// Transformations allow to manipulate data returned by a query before the system applies a visualization. +// Using transformations you can: rename fields, join time series data, perform mathematical operations across queries, +// use the output of one transformation as the input to another transformation, etc. +export interface DataTransformerConfig { + // Unique identifier of transformer + id: string; + // Disabled transformations are skipped + disabled?: boolean; + // Optional frame matcher. When missing it will be applied to all results + filter?: MatcherConfig; + // Where to pull DataFrames from as input to transformation + topic?: DataTopic; + // Options to be passed to the transformer + // Valid options depend on the transformer id + options: any; +} + +export const defaultDataTransformerConfig = (): DataTransformerConfig => ({ + id: "", + options: {}, +}); + +// Matcher is a predicate configuration. Based on the config a set of field(s) or values is filtered in order to apply override / transformation. +// It comes with in id ( to resolve implementation from registry) and a configuration that’s specific to a particular matcher type. +export interface MatcherConfig { + // The matcher id. This is used to find the matcher implementation from registry. + id: string; + // The matcher options. This is specific to the matcher implementation. + options?: any; +} + +export const defaultMatcherConfig = (): MatcherConfig => ({ + id: "", +}); + +// A topic is attached to DataFrame metadata in query results. +// This specifies where the data should be used. +export type DataTopic = "series" | "annotations" | "alertStates"; + +export const defaultDataTopic = (): DataTopic => ("series"); + +export interface QueryOptionsSpec { + timeFrom?: string; + maxDataPoints?: number; + timeShift?: string; + queryCachingTTL?: number; + interval?: string; + cacheTimeout?: string; + hideTimeOverride?: boolean; +} + +export const defaultQueryOptionsSpec = (): QueryOptionsSpec => ({ +}); + +export interface VizConfigKind { + // The kind of a VizConfigKind is the plugin ID + kind: string; + spec: VizConfigSpec; +} + +export const defaultVizConfigKind = (): VizConfigKind => ({ + kind: "", + spec: defaultVizConfigSpec(), +}); + +// --- Kinds --- +export interface VizConfigSpec { + pluginVersion: string; + options: Record; + fieldConfig: FieldConfigSource; +} + +export const defaultVizConfigSpec = (): VizConfigSpec => ({ + pluginVersion: "", + options: {}, + fieldConfig: defaultFieldConfigSource(), +}); + +// The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results. +// Each column within this structure is called a field. A field can represent a single time series or table column. +// Field options allow you to change how the data is displayed in your visualizations. +export interface FieldConfigSource { + // Defaults are the options applied to all fields. + defaults: FieldConfig; + // Overrides are the options applied to specific fields overriding the defaults. + overrides: { + matcher: MatcherConfig; + properties: DynamicConfigValue[]; + }[]; +} + +export const defaultFieldConfigSource = (): FieldConfigSource => ({ + defaults: defaultFieldConfig(), + overrides: [], +}); + +// The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results. +// Each column within this structure is called a field. A field can represent a single time series or table column. +// Field options allow you to change how the data is displayed in your visualizations. +export interface FieldConfig { + // The display value for this field. This supports template variables blank is auto + displayName?: string; + // This can be used by data sources that return and explicit naming structure for values and labels + // When this property is configured, this value is used rather than the default naming strategy. + displayNameFromDS?: string; + // Human readable field metadata + description?: string; + // An explicit path to the field in the datasource. When the frame meta includes a path, + // This will default to `${frame.meta.path}/${field.name} + // + // When defined, this value can be used as an identifier within the datasource scope, and + // may be used to update the results + path?: string; + // True if data source can write a value to the path. Auth/authz are supported separately + writeable?: boolean; + // True if data source field supports ad-hoc filters + filterable?: boolean; + // Unit a field should use. The unit you select is applied to all fields except time. + // You can use the units ID availables in Grafana or a custom unit. + // Available units in Grafana: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/valueFormats/categories.ts + // As custom unit, you can use the following formats: + // `suffix:` for custom unit that should go after value. + // `prefix:` for custom unit that should go before value. + // `time:` For custom date time formats type for example `time:YYYY-MM-DD`. + // `si:` for custom SI units. For example: `si: mF`. This one is a bit more advanced as you can specify both a unit and the source data scale. So if your source data is represented as milli (thousands of) something prefix the unit with that SI scale character. + // `count:` for a custom count unit. + // `currency:` for custom a currency unit. + unit?: string; + // Specify the number of decimals Grafana includes in the rendered value. + // If you leave this field blank, Grafana automatically truncates the number of decimals based on the value. + // For example 1.1234 will display as 1.12 and 100.456 will display as 100. + // To display all decimals, set the unit to `String`. + decimals?: number; + // The minimum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields. + min?: number; + // The maximum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields. + max?: number; + // Convert input values into a display string + mappings?: ValueMapping[]; + // Map numeric values to states + thresholds?: ThresholdsConfig; + // Panel color configuration + color?: FieldColor; + // The behavior when clicking on a result + links?: any[]; + // Alternative to empty string + noValue?: string; + // custom is specified by the FieldConfig field + // in panel plugin schemas. + custom?: Record; +} + +export const defaultFieldConfig = (): FieldConfig => ({ +}); + +export type ValueMapping = ValueMap | RangeMap | RegexMap | SpecialValueMap; + +export const defaultValueMapping = (): ValueMapping => (defaultValueMap()); + +// Maps text values to a color or different display text and color. +// For example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number. +export interface ValueMap { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "value" + type: "value"; + // Map with : ValueMappingResult. For example: { "10": { text: "Perfection!", color: "green" } } + options: Record; +} + +export const defaultValueMap = (): ValueMap => ({ + type: "value", + options: {}, +}); + +// Result used as replacement with text and color when the value matches +export interface ValueMappingResult { + // Text to display when the value matches + text?: string; + // Text to use when the value matches + color?: string; + // Icon to display when the value matches. Only specific visualizations. + icon?: string; + // Position in the mapping array. Only used internally. + index?: number; +} + +export const defaultValueMappingResult = (): ValueMappingResult => ({ +}); + +// Maps numerical ranges to a display text and color. +// For example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number. +export interface RangeMap { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "range" + type: "range"; + // Range to match against and the result to apply when the value is within the range + options: { + // Min value of the range. It can be null which means -Infinity + from: number | null; + // Max value of the range. It can be null which means +Infinity + to: number | null; + // Config to apply when the value is within the range + result: ValueMappingResult; + }; +} + +export const defaultRangeMap = (): RangeMap => ({ + type: "range", + options: { + from: 0, + to: 0, + result: defaultValueMappingResult(), +}, +}); + +// Maps regular expressions to replacement text and a color. +// For example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain. +export interface RegexMap { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "regex" + type: "regex"; + // Regular expression to match against and the result to apply when the value matches the regex + options: { + // Regular expression to match against + pattern: string; + // Config to apply when the value matches the regex + result: ValueMappingResult; + }; +} + +export const defaultRegexMap = (): RegexMap => ({ + type: "regex", + options: { + pattern: "", + result: defaultValueMappingResult(), +}, +}); + +// Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color. +// See SpecialValueMatch to see the list of special values. +// For example, you can configure a special value mapping so that null values appear as N/A. +export interface SpecialValueMap { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "special" + type: "special"; + options: { + // Special value to match against + match: SpecialValueMatch; + // Config to apply when the value matches the special value + result: ValueMappingResult; + }; +} + +export const defaultSpecialValueMap = (): SpecialValueMap => ({ + type: "special", + options: { + match: "true", + result: defaultValueMappingResult(), +}, +}); + +// Special value types supported by the `SpecialValueMap` +export type SpecialValueMatch = "true" | "false" | "null" | "nan" | "null+nan" | "empty"; + +export const defaultSpecialValueMatch = (): SpecialValueMatch => ("true"); + +export interface ThresholdsConfig { + mode: ThresholdsMode; + steps: Threshold[]; +} + +export const defaultThresholdsConfig = (): ThresholdsConfig => ({ + mode: "absolute", + steps: [], +}); + +export type ThresholdsMode = "absolute" | "percentage"; + +export const defaultThresholdsMode = (): ThresholdsMode => ("absolute"); + +export interface Threshold { + value: number; + color: string; +} + +export const defaultThreshold = (): Threshold => ({ + value: 0, + color: "", +}); + +// Map a field to a color. +export interface FieldColor { + // The main color scheme mode. + mode: FieldColorModeId; + // The fixed color value for fixed or shades color modes. + fixedColor?: string; + // Some visualizations need to know how to assign a series color from by value color schemes. + seriesBy?: FieldColorSeriesByMode; +} + +export const defaultFieldColor = (): FieldColor => ({ + mode: "thresholds", +}); + +// Color mode for a field. You can specify a single color, or select a continuous (gradient) color schemes, based on a value. +// Continuous color interpolates a color using the percentage of a value relative to min and max. +// Accepted values are: +// `thresholds`: From thresholds. Informs Grafana to take the color from the matching threshold +// `palette-classic`: Classic palette. Grafana will assign color by looking up a color in a palette by series index. Useful for Graphs and pie charts and other categorical data visualizations +// `palette-classic-by-name`: Classic palette (by name). Grafana will assign color by looking up a color in a palette by series name. Useful for Graphs and pie charts and other categorical data visualizations +// `continuous-GrYlRd`: ontinuous Green-Yellow-Red palette mode +// `continuous-RdYlGr`: Continuous Red-Yellow-Green palette mode +// `continuous-BlYlRd`: Continuous Blue-Yellow-Red palette mode +// `continuous-YlRd`: Continuous Yellow-Red palette mode +// `continuous-BlPu`: Continuous Blue-Purple palette mode +// `continuous-YlBl`: Continuous Yellow-Blue palette mode +// `continuous-blues`: Continuous Blue palette mode +// `continuous-reds`: Continuous Red palette mode +// `continuous-greens`: Continuous Green palette mode +// `continuous-purples`: Continuous Purple palette mode +// `shades`: Shades of a single color. Specify a single color, useful in an override rule. +// `fixed`: Fixed color mode. Specify a single color, useful in an override rule. +export type FieldColorModeId = "thresholds" | "palette-classic" | "palette-classic-by-name" | "continuous-GrYlRd" | "continuous-RdYlGr" | "continuous-BlYlRd" | "continuous-YlRd" | "continuous-BlPu" | "continuous-YlBl" | "continuous-blues" | "continuous-reds" | "continuous-greens" | "continuous-purples" | "fixed" | "shades"; + +export const defaultFieldColorModeId = (): FieldColorModeId => ("thresholds"); + +// Defines how to assign a series color from "by value" color schemes. For example for an aggregated data points like a timeseries, the color can be assigned by the min, max or last value. +export type FieldColorSeriesByMode = "min" | "max" | "last"; + +export const defaultFieldColorSeriesByMode = (): FieldColorSeriesByMode => ("min"); + +export interface DynamicConfigValue { + id: string; + value?: any; +} + +export const defaultDynamicConfigValue = (): DynamicConfigValue => ({ + id: "", +}); + +export interface LibraryPanelKind { + kind: "LibraryPanel"; + spec: LibraryPanelKindSpec; +} + +export const defaultLibraryPanelKind = (): LibraryPanelKind => ({ + kind: "LibraryPanel", + spec: defaultLibraryPanelKindSpec(), +}); + +export interface LibraryPanelKindSpec { + // Panel ID for the library panel in the dashboard + id: number; + // Title for the library panel in the dashboard + title: string; + libraryPanel: LibraryPanelRef; +} + +export const defaultLibraryPanelKindSpec = (): LibraryPanelKindSpec => ({ + id: 0, + title: "", + libraryPanel: defaultLibraryPanelRef(), +}); + +// A library panel is a reusable panel that you can use in any dashboard. +// When you make a change to a library panel, that change propagates to all instances of where the panel is used. +// Library panels streamline reuse of panels across multiple dashboards. +export interface LibraryPanelRef { + // Library panel name + name: string; + // Library panel uid + uid: string; +} + +export const defaultLibraryPanelRef = (): LibraryPanelRef => ({ + name: "", + uid: "", +}); + +export interface GridLayoutKind { + kind: "GridLayout"; + spec: GridLayoutSpec; +} + +export const defaultGridLayoutKind = (): GridLayoutKind => ({ + kind: "GridLayout", + spec: defaultGridLayoutSpec(), +}); + +export interface GridLayoutSpec { + items: (GridLayoutItemKind | GridLayoutRowKind)[]; +} + +export const defaultGridLayoutSpec = (): GridLayoutSpec => ({ + items: [], +}); + +export interface GridLayoutItemKind { + kind: "GridLayoutItem"; + spec: GridLayoutItemSpec; +} + +export const defaultGridLayoutItemKind = (): GridLayoutItemKind => ({ + kind: "GridLayoutItem", + spec: defaultGridLayoutItemSpec(), +}); + +export interface GridLayoutItemSpec { + x: number; + y: number; + width: number; + height: number; + // reference to a PanelKind from dashboard.spec.elements Expressed as JSON Schema reference + element: ElementReference; + repeat?: RepeatOptions; +} + +export const defaultGridLayoutItemSpec = (): GridLayoutItemSpec => ({ + x: 0, + y: 0, + width: 0, + height: 0, + element: defaultElementReference(), +}); + +export interface ElementReference { + kind: "ElementReference"; + name: string; +} + +export const defaultElementReference = (): ElementReference => ({ + kind: "ElementReference", + name: "", +}); + +export interface RepeatOptions { + mode: "variable"; + value: string; + direction?: "h" | "v"; + maxPerRow?: number; +} + +export const defaultRepeatOptions = (): RepeatOptions => ({ + mode: RepeatMode, + value: "", +}); + +// other repeat modes will be added in the future: label, frame +export const RepeatMode = "variable"; + +export interface GridLayoutRowKind { + kind: "GridLayoutRow"; + spec: GridLayoutRowSpec; +} + +export const defaultGridLayoutRowKind = (): GridLayoutRowKind => ({ + kind: "GridLayoutRow", + spec: defaultGridLayoutRowSpec(), +}); + +export interface GridLayoutRowSpec { + y: number; + collapsed: boolean; + title: string; + // Grid items in the row will have their Y value be relative to the rows Y value. This means a panel positioned at Y: 0 in a row with Y: 10 will be positioned at Y: 11 (row header has a heigh of 1) in the dashboard. + elements: GridLayoutItemKind[]; + repeat?: RowRepeatOptions; +} + +export const defaultGridLayoutRowSpec = (): GridLayoutRowSpec => ({ + y: 0, + collapsed: false, + title: "", + elements: [], +}); + +export interface RowRepeatOptions { + mode: "variable"; + value: string; +} + +export const defaultRowRepeatOptions = (): RowRepeatOptions => ({ + mode: RepeatMode, + value: "", +}); + +export interface RowsLayoutKind { + kind: "RowsLayout"; + spec: RowsLayoutSpec; +} + +export const defaultRowsLayoutKind = (): RowsLayoutKind => ({ + kind: "RowsLayout", + spec: defaultRowsLayoutSpec(), +}); + +export interface RowsLayoutSpec { + rows: RowsLayoutRowKind[]; +} + +export const defaultRowsLayoutSpec = (): RowsLayoutSpec => ({ + rows: [], +}); + +export interface RowsLayoutRowKind { + kind: "RowsLayoutRow"; + spec: RowsLayoutRowSpec; +} + +export const defaultRowsLayoutRowKind = (): RowsLayoutRowKind => ({ + kind: "RowsLayoutRow", + spec: defaultRowsLayoutRowSpec(), +}); + +export interface RowsLayoutRowSpec { + title?: string; + collapsed: boolean; + repeat?: RowRepeatOptions; + layout: GridLayoutKind | ResponsiveGridLayoutKind | TabsLayoutKind; +} + +export const defaultRowsLayoutRowSpec = (): RowsLayoutRowSpec => ({ + collapsed: false, + layout: defaultGridLayoutKind(), +}); + +export interface ResponsiveGridLayoutKind { + kind: "ResponsiveGridLayout"; + spec: ResponsiveGridLayoutSpec; +} + +export const defaultResponsiveGridLayoutKind = (): ResponsiveGridLayoutKind => ({ + kind: "ResponsiveGridLayout", + spec: defaultResponsiveGridLayoutSpec(), +}); + +export interface ResponsiveGridLayoutSpec { + row: string; + col: string; + items: ResponsiveGridLayoutItemKind[]; +} + +export const defaultResponsiveGridLayoutSpec = (): ResponsiveGridLayoutSpec => ({ + row: "", + col: "", + items: [], +}); + +export interface ResponsiveGridLayoutItemKind { + kind: "ResponsiveGridLayoutItem"; + spec: ResponsiveGridLayoutItemSpec; +} + +export const defaultResponsiveGridLayoutItemKind = (): ResponsiveGridLayoutItemKind => ({ + kind: "ResponsiveGridLayoutItem", + spec: defaultResponsiveGridLayoutItemSpec(), +}); + +export interface ResponsiveGridLayoutItemSpec { + element: ElementReference; + repeat?: ResponsiveGridRepeatOptions; +} + +export const defaultResponsiveGridLayoutItemSpec = (): ResponsiveGridLayoutItemSpec => ({ + element: defaultElementReference(), +}); + +export interface ResponsiveGridRepeatOptions { + mode: "variable"; + value: string; +} + +export const defaultResponsiveGridRepeatOptions = (): ResponsiveGridRepeatOptions => ({ + mode: RepeatMode, + value: "", +}); + +export interface TabsLayoutKind { + kind: "TabsLayout"; + spec: TabsLayoutSpec; +} + +export const defaultTabsLayoutKind = (): TabsLayoutKind => ({ + kind: "TabsLayout", + spec: defaultTabsLayoutSpec(), +}); + +export interface TabsLayoutSpec { + tabs: TabsLayoutTabKind[]; +} + +export const defaultTabsLayoutSpec = (): TabsLayoutSpec => ({ + tabs: [], +}); + +export interface TabsLayoutTabKind { + kind: "TabsLayoutTab"; + spec: TabsLayoutTabSpec; +} + +export const defaultTabsLayoutTabKind = (): TabsLayoutTabKind => ({ + kind: "TabsLayoutTab", + spec: defaultTabsLayoutTabSpec(), +}); + +export interface TabsLayoutTabSpec { + title?: string; + layout: GridLayoutKind | RowsLayoutKind | ResponsiveGridLayoutKind; +} + +export const defaultTabsLayoutTabSpec = (): TabsLayoutTabSpec => ({ + layout: defaultGridLayoutKind(), +}); + +// Links with references to other dashboards or external resources +export interface DashboardLink { + // Title to display with the link + title: string; + // Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource) + // FIXME: The type is generated as `type: DashboardLinkType | dashboardLinkType.Link;` but it should be `type: DashboardLinkType` + type: DashboardLinkType; + // Icon name to be displayed with the link + icon: string; + // Tooltip to display when the user hovers their mouse over it + tooltip: string; + // Link URL. Only required/valid if the type is link + url?: string; + // List of tags to limit the linked dashboards. If empty, all dashboards will be displayed. Only valid if the type is dashboards + tags: string[]; + // If true, all dashboards links will be displayed in a dropdown. If false, all dashboards links will be displayed side by side. Only valid if the type is dashboards + asDropdown: boolean; + // If true, the link will be opened in a new tab + targetBlank: boolean; + // If true, includes current template variables values in the link as query params + includeVars: boolean; + // If true, includes current time range in the link as query params + keepTime: boolean; +} + +export const defaultDashboardLink = (): DashboardLink => ({ + title: "", + type: "link", + icon: "", + tooltip: "", + tags: [], + asDropdown: false, + targetBlank: false, + includeVars: false, + keepTime: false, +}); + +// Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource) +export type DashboardLinkType = "link" | "dashboards"; + +export const defaultDashboardLinkType = (): DashboardLinkType => ("link"); + +// Time configuration +// It defines the default time config for the time picker, the refresh picker for the specific dashboard. +export interface TimeSettingsSpec { + // Timezone of dashboard. Accepted values are IANA TZDB zone ID or "browser" or "utc". + timezone?: string; + // Start time range for dashboard. + // Accepted values are relative time strings like "now-6h" or absolute time strings like "2020-07-10T08:00:00.000Z". + from: string; + // End time range for dashboard. + // Accepted values are relative time strings like "now-6h" or absolute time strings like "2020-07-10T08:00:00.000Z". + to: string; + // Refresh rate of dashboard. Represented via interval string, e.g. "5s", "1m", "1h", "1d". + // v1: refresh + autoRefresh: string; + // Interval options available in the refresh picker dropdown. + // v1: timepicker.refresh_intervals + autoRefreshIntervals: string[]; + // Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard. + // v1: timepicker.quick_ranges , not exposed in the UI + quickRanges?: TimeRangeOption[]; + // Whether timepicker is visible or not. + // v1: timepicker.hidden + hideTimepicker: boolean; + // Day when the week starts. Expressed by the name of the day in lowercase, e.g. "monday". + weekStart?: "saturday" | "monday" | "sunday"; + // The month that the fiscal year starts on. 0 = January, 11 = December + fiscalYearStartMonth: number; + // Override the now time by entering a time delay. Use this option to accommodate known delays in data aggregation to avoid null values. + // v1: timepicker.nowDelay + nowDelay?: string; +} + +export const defaultTimeSettingsSpec = (): TimeSettingsSpec => ({ + timezone: "browser", + from: "now-6h", + to: "now", + autoRefresh: "", + autoRefreshIntervals: [ +"5s", +"10s", +"30s", +"1m", +"5m", +"15m", +"30m", +"1h", +"2h", +"1d", +], + hideTimepicker: false, + fiscalYearStartMonth: 0, +}); + +export interface TimeRangeOption { + display: string; + from: string; + to: string; +} + +export const defaultTimeRangeOption = (): TimeRangeOption => ({ + display: "Last 6 hours", + from: "now-6h", + to: "now", +}); + +export type VariableKind = QueryVariableKind | TextVariableKind | ConstantVariableKind | DatasourceVariableKind | IntervalVariableKind | CustomVariableKind | GroupByVariableKind | AdhocVariableKind; + +export const defaultVariableKind = (): VariableKind => (defaultQueryVariableKind()); + +// Query variable kind +export interface QueryVariableKind { + kind: "QueryVariable"; + spec: QueryVariableSpec; +} + +export const defaultQueryVariableKind = (): QueryVariableKind => ({ + kind: "QueryVariable", + spec: defaultQueryVariableSpec(), +}); + +// Query variable specification +export interface QueryVariableSpec { + name: string; + current: VariableOption; + label?: string; + hide: VariableHide; + refresh: VariableRefresh; + skipUrlSync: boolean; + description?: string; + datasource?: DataSourceRef; + query: DataQueryKind; + regex: string; + sort: VariableSort; + definition?: string; + options: VariableOption[]; + multi: boolean; + includeAll: boolean; + allValue?: string; + placeholder?: string; +} + +export const defaultQueryVariableSpec = (): QueryVariableSpec => ({ + name: "", + current: { text: "", value: "", }, + hide: "dontHide", + refresh: "never", + skipUrlSync: false, + query: defaultDataQueryKind(), + regex: "", + sort: "disabled", + options: [], + multi: false, + includeAll: false, +}); + +// Variable option specification +export interface VariableOption { + // Whether the option is selected or not + selected?: boolean; + // Text to be displayed for the option + text: string | string[]; + // Value of the option + value: string | string[]; +} + +export const defaultVariableOption = (): VariableOption => ({ + text: "", + value: "", +}); + +// Determine if the variable shows on dashboard +// Accepted values are `dontHide` (show label and value), `hideLabel` (show value only), `hideVariable` (show nothing). +export type VariableHide = "dontHide" | "hideLabel" | "hideVariable"; + +export const defaultVariableHide = (): VariableHide => ("dontHide"); + +// Options to config when to refresh a variable +// `never`: Never refresh the variable +// `onDashboardLoad`: Queries the data source every time the dashboard loads. +// `onTimeRangeChanged`: Queries the data source when the dashboard time range changes. +export type VariableRefresh = "never" | "onDashboardLoad" | "onTimeRangeChanged"; + +export const defaultVariableRefresh = (): VariableRefresh => ("never"); + +// Sort variable options +// Accepted values are: +// `disabled`: No sorting +// `alphabeticalAsc`: Alphabetical ASC +// `alphabeticalDesc`: Alphabetical DESC +// `numericalAsc`: Numerical ASC +// `numericalDesc`: Numerical DESC +// `alphabeticalCaseInsensitiveAsc`: Alphabetical Case Insensitive ASC +// `alphabeticalCaseInsensitiveDesc`: Alphabetical Case Insensitive DESC +// `naturalAsc`: Natural ASC +// `naturalDesc`: Natural DESC +// VariableSort enum with default value +export type VariableSort = "disabled" | "alphabeticalAsc" | "alphabeticalDesc" | "numericalAsc" | "numericalDesc" | "alphabeticalCaseInsensitiveAsc" | "alphabeticalCaseInsensitiveDesc" | "naturalAsc" | "naturalDesc"; + +export const defaultVariableSort = (): VariableSort => ("disabled"); + +// Text variable kind +export interface TextVariableKind { + kind: "TextVariable"; + spec: TextVariableSpec; +} + +export const defaultTextVariableKind = (): TextVariableKind => ({ + kind: "TextVariable", + spec: defaultTextVariableSpec(), +}); + +// Text variable specification +export interface TextVariableSpec { + name: string; + current: VariableOption; + query: string; + label?: string; + hide: VariableHide; + skipUrlSync: boolean; + description?: string; +} + +export const defaultTextVariableSpec = (): TextVariableSpec => ({ + name: "", + current: { text: "", value: "", }, + query: "", + hide: "dontHide", + skipUrlSync: false, +}); + +// Constant variable kind +export interface ConstantVariableKind { + kind: "ConstantVariable"; + spec: ConstantVariableSpec; +} + +export const defaultConstantVariableKind = (): ConstantVariableKind => ({ + kind: "ConstantVariable", + spec: defaultConstantVariableSpec(), +}); + +// Constant variable specification +export interface ConstantVariableSpec { + name: string; + query: string; + current: VariableOption; + label?: string; + hide: VariableHide; + skipUrlSync: boolean; + description?: string; +} + +export const defaultConstantVariableSpec = (): ConstantVariableSpec => ({ + name: "", + query: "", + current: { text: "", value: "", }, + hide: "dontHide", + skipUrlSync: false, +}); + +// Datasource variable kind +export interface DatasourceVariableKind { + kind: "DatasourceVariable"; + spec: DatasourceVariableSpec; +} + +export const defaultDatasourceVariableKind = (): DatasourceVariableKind => ({ + kind: "DatasourceVariable", + spec: defaultDatasourceVariableSpec(), +}); + +// Datasource variable specification +export interface DatasourceVariableSpec { + name: string; + pluginId: string; + refresh: VariableRefresh; + regex: string; + current: VariableOption; + options: VariableOption[]; + multi: boolean; + includeAll: boolean; + allValue?: string; + label?: string; + hide: VariableHide; + skipUrlSync: boolean; + description?: string; +} + +export const defaultDatasourceVariableSpec = (): DatasourceVariableSpec => ({ + name: "", + pluginId: "", + refresh: "never", + regex: "", + current: { text: "", value: "", }, + options: [], + multi: false, + includeAll: false, + hide: "dontHide", + skipUrlSync: false, +}); + +// Interval variable kind +export interface IntervalVariableKind { + kind: "IntervalVariable"; + spec: IntervalVariableSpec; +} + +export const defaultIntervalVariableKind = (): IntervalVariableKind => ({ + kind: "IntervalVariable", + spec: defaultIntervalVariableSpec(), +}); + +// Interval variable specification +export interface IntervalVariableSpec { + name: string; + query: string; + current: VariableOption; + options: VariableOption[]; + auto: boolean; + auto_min: string; + auto_count: number; + refresh: VariableRefresh; + label?: string; + hide: VariableHide; + skipUrlSync: boolean; + description?: string; +} + +export const defaultIntervalVariableSpec = (): IntervalVariableSpec => ({ + name: "", + query: "", + current: { text: "", value: "", }, + options: [], + auto: false, + auto_min: "", + auto_count: 0, + refresh: "never", + hide: "dontHide", + skipUrlSync: false, +}); + +// Custom variable kind +export interface CustomVariableKind { + kind: "CustomVariable"; + spec: CustomVariableSpec; +} + +export const defaultCustomVariableKind = (): CustomVariableKind => ({ + kind: "CustomVariable", + spec: defaultCustomVariableSpec(), +}); + +// Custom variable specification +export interface CustomVariableSpec { + name: string; + query: string; + current: VariableOption; + options: VariableOption[]; + multi: boolean; + includeAll: boolean; + allValue?: string; + label?: string; + hide: VariableHide; + skipUrlSync: boolean; + description?: string; +} + +export const defaultCustomVariableSpec = (): CustomVariableSpec => ({ + name: "", + query: "", + current: defaultVariableOption(), + options: [], + multi: false, + includeAll: false, + hide: "dontHide", + skipUrlSync: false, +}); + +// Group variable kind +export interface GroupByVariableKind { + kind: "GroupByVariable"; + spec: GroupByVariableSpec; +} + +export const defaultGroupByVariableKind = (): GroupByVariableKind => ({ + kind: "GroupByVariable", + spec: defaultGroupByVariableSpec(), +}); + +// GroupBy variable specification +export interface GroupByVariableSpec { + name: string; + datasource?: DataSourceRef; + current: VariableOption; + options: VariableOption[]; + multi: boolean; + label?: string; + hide: VariableHide; + skipUrlSync: boolean; + description?: string; +} + +export const defaultGroupByVariableSpec = (): GroupByVariableSpec => ({ + name: "", + current: { text: "", value: "", }, + options: [], + multi: false, + hide: "dontHide", + skipUrlSync: false, +}); + +// Adhoc variable kind +export interface AdhocVariableKind { + kind: "AdhocVariable"; + spec: AdhocVariableSpec; +} + +export const defaultAdhocVariableKind = (): AdhocVariableKind => ({ + kind: "AdhocVariable", + spec: defaultAdhocVariableSpec(), +}); + +// Adhoc variable specification +export interface AdhocVariableSpec { + name: string; + datasource?: DataSourceRef; + baseFilters: AdHocFilterWithLabels[]; + filters: AdHocFilterWithLabels[]; + defaultKeys: MetricFindValue[]; + label?: string; + hide: VariableHide; + skipUrlSync: boolean; + description?: string; +} + +export const defaultAdhocVariableSpec = (): AdhocVariableSpec => ({ + name: "", + baseFilters: [], + filters: [], + defaultKeys: [], + hide: "dontHide", + skipUrlSync: false, +}); + +// Define the AdHocFilterWithLabels type +export interface AdHocFilterWithLabels { + key: string; + operator: string; + value: string; + values?: string[]; + keyLabel?: string; + valueLabels?: string[]; + forceEdit?: boolean; + // @deprecated + condition?: string; +} + +export const defaultAdHocFilterWithLabels = (): AdHocFilterWithLabels => ({ + key: "", + operator: "", + value: "", +}); + +// Define the MetricFindValue type +export interface MetricFindValue { + text: string; + value?: string | number; + group?: string; + expandable?: boolean; +} + +export const defaultMetricFindValue = (): MetricFindValue => ({ + text: "", +}); + +export interface Spec { + // Title of dashboard. + annotations: AnnotationQueryKind[]; + // Configuration of dashboard cursor sync behavior. + // "Off" for no shared crosshair or tooltip (default). + // "Crosshair" for shared crosshair. + // "Tooltip" for shared crosshair AND shared tooltip. + cursorSync: DashboardCursorSync; + // Description of dashboard. + description?: string; + // Whether a dashboard is editable or not. + editable?: boolean; + elements: Record; + layout: GridLayoutKind | RowsLayoutKind | ResponsiveGridLayoutKind | TabsLayoutKind; + // Links with references to other dashboards or external websites. + links: DashboardLink[]; + // When set to true, the dashboard will redraw panels at an interval matching the pixel width. + // This will keep data "moving left" regardless of the query refresh rate. This setting helps + // avoid dashboards presenting stale live data. + liveNow?: boolean; + // When set to true, the dashboard will load all panels in the dashboard when it's loaded. + preload: boolean; + // Plugins only. The version of the dashboard installed together with the plugin. + // This is used to determine if the dashboard should be updated when the plugin is updated. + revision?: number; + // Tags associated with dashboard. + tags: string[]; + timeSettings: TimeSettingsSpec; + // Title of dashboard. + title: string; + // Configured template variables. + variables: VariableKind[]; +} + +export const defaultSpec = (): Spec => ({ + annotations: [], + cursorSync: "Off", + editable: true, + elements: {}, + layout: defaultGridLayoutKind(), + links: [], + preload: false, + tags: [], + timeSettings: defaultTimeSettingsSpec(), + title: "", + variables: [], +}); + diff --git a/packages/grafana-schema/src/schema/dashboard/v2alpha1/types.status.gen.ts b/packages/grafana-schema/src/schema/dashboard/v2alpha1/types.status.gen.ts new file mode 100644 index 00000000000..29494dfaf24 --- /dev/null +++ b/packages/grafana-schema/src/schema/dashboard/v2alpha1/types.status.gen.ts @@ -0,0 +1,30 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +// ConversionStatus is the status of the conversion of the dashboard. +export interface ConversionStatus { + // Whether from another version has failed. + // If true, means that the dashboard is not valid, + // and the caller should instead fetch the stored version. + failed: boolean; + // The version which was stored when the dashboard was created / updated. + // Fetching this version should always succeed. + storedVersion: string; + // The error message from the conversion. + // Empty if the conversion has not failed. + error: string; +} + +export const defaultConversionStatus = (): ConversionStatus => ({ + failed: false, + storedVersion: "", + error: "", +}); + +export interface Status { + // Optional conversion status. + conversion?: ConversionStatus; +} + +export const defaultStatus = (): Status => ({ +}); + diff --git a/pkg/apis/dashboard/migration/conversion/conversion.go b/pkg/apis/dashboard/migration/conversion/conversion.go index f14162ff817..830353ce1f2 100644 --- a/pkg/apis/dashboard/migration/conversion/conversion.go +++ b/pkg/apis/dashboard/migration/conversion/conversion.go @@ -47,79 +47,127 @@ func RegisterConversions(s *runtime.Scheme) error { func Convert_V0_to_V1(in *dashboardV0.Dashboard, out *dashboardV1.Dashboard, scope conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - out.Spec = in.Spec - out.Status = &dashboardV1.DashboardStatus{ - ConversionStatus: &dashboardV1.ConversionStatus{ + + out.Spec.Object = in.Spec.Object + + out.Status = dashboardV1.DashboardStatus{ + Conversion: &dashboardV1.DashboardConversionStatus{ StoredVersion: dashboardV0.VERSION, }, } - err := migration.Migrate(out.Spec.Object, schemaversion.LATEST_VERSION) - if err != nil { - out.Status.ConversionStatus.Failed = true - out.Status.ConversionStatus.Error = err.Error() + + if err := migration.Migrate(out.Spec.Object, schemaversion.LATEST_VERSION); err != nil { + out.Status.Conversion.Failed = true + out.Status.Conversion.Error = err.Error() } + return nil } func Convert_V0_to_V2(in *dashboardV0.Dashboard, out *dashboardV2.Dashboard, scope conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - out.Spec = in.Spec - out.Status = &dashboardV2.DashboardStatus{ - ConversionStatus: &dashboardV2.ConversionStatus{ + + // TODO (@radiohead): implement V0 to V2 conversion + // This is the bare minimum conversion that is needed to make the dashboard servable. + + if v, ok := in.Spec.Object["title"]; ok { + if title, ok := v.(string); ok { + out.Spec.Title = title + } + } + + // We need to make sure the layout is set to some value, otherwise the JSON marshaling will fail. + out.Spec.Layout = dashboardV2.DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashboardV2.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashboardV2.DashboardGridLayoutSpec{}, + }, + } + + out.Status = dashboardV2.DashboardStatus{ + Conversion: &dashboardV2.DashboardConversionStatus{ StoredVersion: dashboardV0.VERSION, Failed: true, Error: "backend conversion not yet implemented", }, } + return nil } func Convert_V1_to_V0(in *dashboardV1.Dashboard, out *dashboardV0.Dashboard, scope conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - out.Spec = in.Spec - out.Status = &dashboardV0.DashboardStatus{ - ConversionStatus: &dashboardV0.ConversionStatus{ + + out.Spec.Object = in.Spec.Object + + out.Status = dashboardV0.DashboardStatus{ + Conversion: &dashboardV0.DashboardConversionStatus{ StoredVersion: dashboardV1.VERSION, }, } + return nil } func Convert_V1_to_V2(in *dashboardV1.Dashboard, out *dashboardV2.Dashboard, scope conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - out.Spec = in.Spec - out.Status = &dashboardV2.DashboardStatus{ - ConversionStatus: &dashboardV2.ConversionStatus{ + + // TODO (@radiohead): implement V1 to V2 conversion + // This is the bare minimum conversion that is needed to make the dashboard servable. + + if v, ok := in.Spec.Object["title"]; ok { + if title, ok := v.(string); ok { + out.Spec.Title = title + } + } + + // We need to make sure the layout is set to some value, otherwise the JSON marshaling will fail. + out.Spec.Layout = dashboardV2.DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind{ + GridLayoutKind: &dashboardV2.DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: dashboardV2.DashboardGridLayoutSpec{}, + }, + } + + out.Status = dashboardV2.DashboardStatus{ + Conversion: &dashboardV2.DashboardConversionStatus{ StoredVersion: dashboardV1.VERSION, Failed: true, Error: "backend conversion not yet implemented", }, } + return nil } func Convert_V2_to_V0(in *dashboardV2.Dashboard, out *dashboardV0.Dashboard, scope conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - out.Spec = in.Spec - out.Status = &dashboardV0.DashboardStatus{ - ConversionStatus: &dashboardV0.ConversionStatus{ + + // TODO: implement V2 to V0 conversion + + out.Status = dashboardV0.DashboardStatus{ + Conversion: &dashboardV0.DashboardConversionStatus{ StoredVersion: dashboardV2.VERSION, Failed: true, Error: "backend conversion not yet implemented", }, } + return nil } func Convert_V2_to_V1(in *dashboardV2.Dashboard, out *dashboardV1.Dashboard, scope conversion.Scope) error { out.ObjectMeta = in.ObjectMeta - out.Spec = in.Spec - out.Status = &dashboardV1.DashboardStatus{ - ConversionStatus: &dashboardV1.ConversionStatus{ + + // TODO: implement V2 to V1 conversion + + out.Status = dashboardV1.DashboardStatus{ + Conversion: &dashboardV1.DashboardConversionStatus{ StoredVersion: dashboardV2.VERSION, Failed: true, Error: "backend conversion not yet implemented", }, } + return nil } diff --git a/pkg/apis/dashboard/v0alpha1/constants.go b/pkg/apis/dashboard/v0alpha1/constants.go new file mode 100644 index 00000000000..90cb8b29db7 --- /dev/null +++ b/pkg/apis/dashboard/v0alpha1/constants.go @@ -0,0 +1,18 @@ +package v0alpha1 + +import "k8s.io/apimachinery/pkg/runtime/schema" + +const ( + // Group is the API group used by all kinds in this package + Group = "dashboard.grafana.app" + // Version is the API version used by all kinds in this package + Version = "v0alpha1" +) + +var ( + // GroupVersion is a schema.GroupVersion consisting of the Group and Version constants for this package + GroupVersion = schema.GroupVersion{ + Group: Group, + Version: Version, + } +) diff --git a/pkg/apis/dashboard/v0alpha1/dashboard_codec_gen.go b/pkg/apis/dashboard/v0alpha1/dashboard_codec_gen.go new file mode 100644 index 00000000000..6186cb824b5 --- /dev/null +++ b/pkg/apis/dashboard/v0alpha1/dashboard_codec_gen.go @@ -0,0 +1,28 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v0alpha1 + +import ( + "encoding/json" + "io" + + "github.com/grafana/grafana-app-sdk/resource" +) + +// DashboardJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding +type DashboardJSONCodec struct{} + +// Read reads JSON-encoded bytes from `reader` and unmarshals them into `into` +func (*DashboardJSONCodec) Read(reader io.Reader, into resource.Object) error { + return json.NewDecoder(reader).Decode(into) +} + +// Write writes JSON-encoded bytes into `writer` marshaled from `from` +func (*DashboardJSONCodec) Write(writer io.Writer, from resource.Object) error { + return json.NewEncoder(writer).Encode(from) +} + +// Interface compliance checks +var _ resource.Codec = &DashboardJSONCodec{} diff --git a/pkg/apis/dashboard/v0alpha1/dashboard_metadata_gen.go b/pkg/apis/dashboard/v0alpha1/dashboard_metadata_gen.go new file mode 100644 index 00000000000..6e22219dbf4 --- /dev/null +++ b/pkg/apis/dashboard/v0alpha1/dashboard_metadata_gen.go @@ -0,0 +1,28 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +import ( + time "time" +) + +// metadata contains embedded CommonMetadata and can be extended with custom string fields +// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here +// without external reference as using the CommonMetadata reference breaks thema codegen. +type DashboardMetadata struct { + UpdateTimestamp time.Time `json:"updateTimestamp"` + CreatedBy string `json:"createdBy"` + Uid string `json:"uid"` + CreationTimestamp time.Time `json:"creationTimestamp"` + DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"` + Finalizers []string `json:"finalizers"` + ResourceVersion string `json:"resourceVersion"` + Generation int64 `json:"generation"` + UpdatedBy string `json:"updatedBy"` + Labels map[string]string `json:"labels"` +} + +// NewDashboardMetadata creates a new DashboardMetadata object. +func NewDashboardMetadata() *DashboardMetadata { + return &DashboardMetadata{} +} diff --git a/pkg/apis/dashboard/v0alpha1/dashboard_object_gen.go b/pkg/apis/dashboard/v0alpha1/dashboard_object_gen.go new file mode 100644 index 00000000000..ab406988c90 --- /dev/null +++ b/pkg/apis/dashboard/v0alpha1/dashboard_object_gen.go @@ -0,0 +1,269 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v0alpha1 + +import ( + "fmt" + "github.com/grafana/grafana-app-sdk/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "time" +) + +// +k8s:openapi-gen=true +type Dashboard struct { + metav1.TypeMeta `json:",inline" yaml:",inline"` + metav1.ObjectMeta `json:"metadata" yaml:"metadata"` + + // Spec is the spec of the Dashboard + Spec DashboardSpec `json:"spec" yaml:"spec"` + + Status DashboardStatus `json:"status" yaml:"status"` +} + +func (o *Dashboard) GetSpec() any { + return o.Spec +} + +func (o *Dashboard) SetSpec(spec any) error { + cast, ok := spec.(DashboardSpec) + if !ok { + return fmt.Errorf("cannot set spec type %#v, not of type Spec", spec) + } + o.Spec = cast + return nil +} + +func (o *Dashboard) GetSubresources() map[string]any { + return map[string]any{ + "status": o.Status, + } +} + +func (o *Dashboard) GetSubresource(name string) (any, bool) { + switch name { + case "status": + return o.Status, true + default: + return nil, false + } +} + +func (o *Dashboard) SetSubresource(name string, value any) error { + switch name { + case "status": + cast, ok := value.(DashboardStatus) + if !ok { + return fmt.Errorf("cannot set status type %#v, not of type DashboardStatus", value) + } + o.Status = cast + return nil + default: + return fmt.Errorf("subresource '%s' does not exist", name) + } +} + +func (o *Dashboard) GetStaticMetadata() resource.StaticMetadata { + gvk := o.GroupVersionKind() + return resource.StaticMetadata{ + Name: o.ObjectMeta.Name, + Namespace: o.ObjectMeta.Namespace, + Group: gvk.Group, + Version: gvk.Version, + Kind: gvk.Kind, + } +} + +func (o *Dashboard) SetStaticMetadata(metadata resource.StaticMetadata) { + o.Name = metadata.Name + o.Namespace = metadata.Namespace + o.SetGroupVersionKind(schema.GroupVersionKind{ + Group: metadata.Group, + Version: metadata.Version, + Kind: metadata.Kind, + }) +} + +func (o *Dashboard) GetCommonMetadata() resource.CommonMetadata { + dt := o.DeletionTimestamp + var deletionTimestamp *time.Time + if dt != nil { + deletionTimestamp = &dt.Time + } + // Legacy ExtraFields support + extraFields := make(map[string]any) + if o.Annotations != nil { + extraFields["annotations"] = o.Annotations + } + if o.ManagedFields != nil { + extraFields["managedFields"] = o.ManagedFields + } + if o.OwnerReferences != nil { + extraFields["ownerReferences"] = o.OwnerReferences + } + return resource.CommonMetadata{ + UID: string(o.UID), + ResourceVersion: o.ResourceVersion, + Generation: o.Generation, + Labels: o.Labels, + CreationTimestamp: o.CreationTimestamp.Time, + DeletionTimestamp: deletionTimestamp, + Finalizers: o.Finalizers, + UpdateTimestamp: o.GetUpdateTimestamp(), + CreatedBy: o.GetCreatedBy(), + UpdatedBy: o.GetUpdatedBy(), + ExtraFields: extraFields, + } +} + +func (o *Dashboard) SetCommonMetadata(metadata resource.CommonMetadata) { + o.UID = types.UID(metadata.UID) + o.ResourceVersion = metadata.ResourceVersion + o.Generation = metadata.Generation + o.Labels = metadata.Labels + o.CreationTimestamp = metav1.NewTime(metadata.CreationTimestamp) + if metadata.DeletionTimestamp != nil { + dt := metav1.NewTime(*metadata.DeletionTimestamp) + o.DeletionTimestamp = &dt + } else { + o.DeletionTimestamp = nil + } + o.Finalizers = metadata.Finalizers + if o.Annotations == nil { + o.Annotations = make(map[string]string) + } + if !metadata.UpdateTimestamp.IsZero() { + o.SetUpdateTimestamp(metadata.UpdateTimestamp) + } + if metadata.CreatedBy != "" { + o.SetCreatedBy(metadata.CreatedBy) + } + if metadata.UpdatedBy != "" { + o.SetUpdatedBy(metadata.UpdatedBy) + } + // Legacy support for setting Annotations, ManagedFields, and OwnerReferences via ExtraFields + if metadata.ExtraFields != nil { + if annotations, ok := metadata.ExtraFields["annotations"]; ok { + if cast, ok := annotations.(map[string]string); ok { + o.Annotations = cast + } + } + if managedFields, ok := metadata.ExtraFields["managedFields"]; ok { + if cast, ok := managedFields.([]metav1.ManagedFieldsEntry); ok { + o.ManagedFields = cast + } + } + if ownerReferences, ok := metadata.ExtraFields["ownerReferences"]; ok { + if cast, ok := ownerReferences.([]metav1.OwnerReference); ok { + o.OwnerReferences = cast + } + } + } +} + +func (o *Dashboard) GetCreatedBy() string { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + return o.ObjectMeta.Annotations["grafana.com/createdBy"] +} + +func (o *Dashboard) SetCreatedBy(createdBy string) { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + o.ObjectMeta.Annotations["grafana.com/createdBy"] = createdBy +} + +func (o *Dashboard) GetUpdateTimestamp() time.Time { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + parsed, _ := time.Parse(time.RFC3339, o.ObjectMeta.Annotations["grafana.com/updateTimestamp"]) + return parsed +} + +func (o *Dashboard) SetUpdateTimestamp(updateTimestamp time.Time) { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + o.ObjectMeta.Annotations["grafana.com/updateTimestamp"] = updateTimestamp.Format(time.RFC3339) +} + +func (o *Dashboard) GetUpdatedBy() string { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + return o.ObjectMeta.Annotations["grafana.com/updatedBy"] +} + +func (o *Dashboard) SetUpdatedBy(updatedBy string) { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + o.ObjectMeta.Annotations["grafana.com/updatedBy"] = updatedBy +} + +func (o *Dashboard) Copy() resource.Object { + return resource.CopyObject(o) +} + +func (o *Dashboard) DeepCopyObject() runtime.Object { + return o.Copy() +} + +// Interface compliance compile-time check +var _ resource.Object = &Dashboard{} + +// +k8s:openapi-gen=true +type DashboardList struct { + metav1.TypeMeta `json:",inline" yaml:",inline"` + metav1.ListMeta `json:"metadata" yaml:"metadata"` + Items []Dashboard `json:"items" yaml:"items"` +} + +func (o *DashboardList) DeepCopyObject() runtime.Object { + return o.Copy() +} + +func (o *DashboardList) Copy() resource.ListObject { + cpy := &DashboardList{ + TypeMeta: o.TypeMeta, + Items: make([]Dashboard, len(o.Items)), + } + o.ListMeta.DeepCopyInto(&cpy.ListMeta) + for i := 0; i < len(o.Items); i++ { + if item, ok := o.Items[i].Copy().(*Dashboard); ok { + cpy.Items[i] = *item + } + } + return cpy +} + +func (o *DashboardList) GetItems() []resource.Object { + items := make([]resource.Object, len(o.Items)) + for i := 0; i < len(o.Items); i++ { + items[i] = &o.Items[i] + } + return items +} + +func (o *DashboardList) SetItems(items []resource.Object) { + o.Items = make([]Dashboard, len(items)) + for i := 0; i < len(items); i++ { + o.Items[i] = *items[i].(*Dashboard) + } +} + +// Interface compliance compile-time check +var _ resource.ListObject = &DashboardList{} diff --git a/pkg/apis/dashboard/v0alpha1/dashboard_schema_gen.go b/pkg/apis/dashboard/v0alpha1/dashboard_schema_gen.go new file mode 100644 index 00000000000..5b2da44ec05 --- /dev/null +++ b/pkg/apis/dashboard/v0alpha1/dashboard_schema_gen.go @@ -0,0 +1,34 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v0alpha1 + +import ( + "github.com/grafana/grafana-app-sdk/resource" +) + +// schema is unexported to prevent accidental overwrites +var ( + schemaDashboard = resource.NewSimpleSchema("dashboard.grafana.app", "v0alpha1", &Dashboard{}, &DashboardList{}, resource.WithKind("Dashboard"), + resource.WithPlural("dashboards"), resource.WithScope(resource.NamespacedScope)) + kindDashboard = resource.Kind{ + Schema: schemaDashboard, + Codecs: map[resource.KindEncoding]resource.Codec{ + resource.KindEncodingJSON: &DashboardJSONCodec{}, + }, + } +) + +// Kind returns a resource.Kind for this Schema with a JSON codec +func DashboardKind() resource.Kind { + return kindDashboard +} + +// Schema returns a resource.SimpleSchema representation of Dashboard +func DashboardSchema() *resource.SimpleSchema { + return schemaDashboard +} + +// Interface compliance checks +var _ resource.Schema = kindDashboard diff --git a/pkg/apis/dashboard/v0alpha1/dashboard_spec.go b/pkg/apis/dashboard/v0alpha1/dashboard_spec.go new file mode 100644 index 00000000000..ec3bf1aeb1f --- /dev/null +++ b/pkg/apis/dashboard/v0alpha1/dashboard_spec.go @@ -0,0 +1,13 @@ +package v0alpha1 + +import ( + common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" +) + +// +k8s:openapi-gen=true +type DashboardSpec = common.Unstructured + +// NewDashboardSpec creates a new Spec object. +func NewDashboardSpec() *DashboardSpec { + return &DashboardSpec{} +} diff --git a/pkg/apis/dashboard/v0alpha1/dashboard_spec_gen.go b/pkg/apis/dashboard/v0alpha1/dashboard_spec_gen.go new file mode 100644 index 00000000000..90130b85cf3 --- /dev/null +++ b/pkg/apis/dashboard/v0alpha1/dashboard_spec_gen.go @@ -0,0 +1,3 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 diff --git a/pkg/apis/dashboard/v0alpha1/dashboard_status_gen.go b/pkg/apis/dashboard/v0alpha1/dashboard_status_gen.go new file mode 100644 index 00000000000..70fbb4e9263 --- /dev/null +++ b/pkg/apis/dashboard/v0alpha1/dashboard_status_gen.go @@ -0,0 +1,34 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +// ConversionStatus is the status of the conversion of the dashboard. +// +k8s:openapi-gen=true +type DashboardConversionStatus struct { + // Whether from another version has failed. + // If true, means that the dashboard is not valid, + // and the caller should instead fetch the stored version. + Failed bool `json:"failed"` + // The version which was stored when the dashboard was created / updated. + // Fetching this version should always succeed. + StoredVersion string `json:"storedVersion"` + // The error message from the conversion. + // Empty if the conversion has not failed. + Error string `json:"error"` +} + +// NewDashboardConversionStatus creates a new DashboardConversionStatus object. +func NewDashboardConversionStatus() *DashboardConversionStatus { + return &DashboardConversionStatus{} +} + +// +k8s:openapi-gen=true +type DashboardStatus struct { + // Optional conversion status. + Conversion *DashboardConversionStatus `json:"conversion,omitempty"` +} + +// NewDashboardStatus creates a new DashboardStatus object. +func NewDashboardStatus() *DashboardStatus { + return &DashboardStatus{} +} diff --git a/pkg/apis/dashboard/v0alpha1/deepcopy.go b/pkg/apis/dashboard/v0alpha1/deepcopy.go new file mode 100644 index 00000000000..ffdea428a67 --- /dev/null +++ b/pkg/apis/dashboard/v0alpha1/deepcopy.go @@ -0,0 +1,41 @@ +package v0alpha1 + +// TODO: these should be automatically generated by the SDK. + +func (in *Dashboard) DeepCopyInto(out *Dashboard) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +func (in *Dashboard) DeepCopy() *Dashboard { + if in == nil { + return nil + } + out := new(Dashboard) + in.DeepCopyInto(out) + return out +} + +func (in *DashboardList) DeepCopyInto(out *DashboardList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Dashboard, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +func (in *DashboardList) DeepCopy() *DashboardList { + if in == nil { + return nil + } + out := new(DashboardList) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apis/dashboard/v0alpha1/doc.go b/pkg/apis/dashboard/v0alpha1/doc.go index 5716d920d2a..748fa7fffd2 100644 --- a/pkg/apis/dashboard/v0alpha1/doc.go +++ b/pkg/apis/dashboard/v0alpha1/doc.go @@ -1,7 +1,10 @@ -// +k8s:deepcopy-gen=package // +k8s:openapi-gen=true // +k8s:defaulter-gen=TypeMeta // +k8s:conversion-gen=github.com/grafana/grafana/pkg/apis/dashboard // +groupName=dashboard.grafana.app +// NOTE (@radiohead): we do not use package-wide deepcopy generation +// because grafana-app-sdk already provides deepcopy functions. +// Kinds which are not generated by the SDK are explicitly opted in to deepcopy generation. + package v0alpha1 // import "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" diff --git a/pkg/apis/dashboard/v0alpha1/search.go b/pkg/apis/dashboard/v0alpha1/search.go index 96afdc447ff..5d768dbfc11 100644 --- a/pkg/apis/dashboard/v0alpha1/search.go +++ b/pkg/apis/dashboard/v0alpha1/search.go @@ -6,6 +6,7 @@ import ( common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" ) +// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type SearchResults struct { metav1.TypeMeta `json:",inline"` @@ -32,11 +33,13 @@ type SearchResults struct { Facets map[string]FacetResult `json:"facets,omitempty"` } +// +k8s:deepcopy-gen=true type SortBy struct { Field string `json:"field"` Descending bool `json:"desc,omitempty"` } +// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type SortableFields struct { metav1.TypeMeta `json:",inline"` @@ -45,12 +48,14 @@ type SortableFields struct { Fields []SortableField `json:"fields"` } +// +k8s:deepcopy-gen=true type SortableField struct { Field string `json:"string,omitempty"` Display string `json:"display,omitempty"` Type string `json:"type,omitempty"` // string or number } +// +k8s:deepcopy-gen=true type DashboardHit struct { // Dashboard or folder Resource string `json:"resource"` // dashboards | folders @@ -70,6 +75,7 @@ type DashboardHit struct { Explain *common.Unstructured `json:"explain,omitempty"` } +// +k8s:deepcopy-gen=true type FacetResult struct { Field string `json:"field,omitempty"` // The distinct terms @@ -80,6 +86,7 @@ type FacetResult struct { Terms []TermFacet `json:"terms,omitempty"` } +// +k8s:deepcopy-gen=true type TermFacet struct { Term string `json:"term,omitempty"` Count int64 `json:"count,omitempty"` diff --git a/pkg/apis/dashboard/v0alpha1/types.go b/pkg/apis/dashboard/v0alpha1/types.go index af6f62f2e95..ff4e38841d3 100644 --- a/pkg/apis/dashboard/v0alpha1/types.go +++ b/pkg/apis/dashboard/v0alpha1/types.go @@ -7,40 +7,7 @@ import ( common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" ) -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -type Dashboard struct { - metav1.TypeMeta `json:",inline"` - // Standard object's metadata - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - metav1.ObjectMeta `json:"metadata,omitempty"` - - // The dashboard body (unstructured for now) - Spec common.Unstructured `json:"spec"` - - // Optional dashboard status - Status *DashboardStatus `json:"status,omitempty"` -} - -type DashboardStatus struct { - ConversionStatus *ConversionStatus `json:"conversion,omitempty"` -} - -type ConversionStatus struct { - Failed bool `json:"failed,omitempty"` - StoredVersion string `json:"storedVersion,omitempty"` - Error string `json:"error,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -type DashboardList struct { - metav1.TypeMeta `json:",inline"` - // +optional - metav1.ListMeta `json:"metadata,omitempty"` - - Items []Dashboard `json:"items,omitempty"` -} - +// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type DashboardVersionList struct { metav1.TypeMeta `json:",inline"` @@ -50,6 +17,7 @@ type DashboardVersionList struct { Items []DashboardVersionInfo `json:"items,omitempty"` } +// +k8s:deepcopy-gen=true type DashboardVersionInfo struct { // The internal ID for this version (will be replaced with resourceVersion) Version int `json:"version"` @@ -67,6 +35,7 @@ type DashboardVersionInfo struct { Message string `json:"message,omitempty"` } +// +k8s:deepcopy-gen=true // +k8s:conversion-gen:explicit-from=net/url.Values // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type VersionsQueryOptions struct { @@ -80,6 +49,7 @@ type VersionsQueryOptions struct { Version int64 `json:"version,omitempty"` } +// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type LibraryPanel struct { metav1.TypeMeta `json:",inline"` @@ -95,6 +65,7 @@ type LibraryPanel struct { Status *LibraryPanelStatus `json:"status,omitempty"` } +// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type LibraryPanelList struct { metav1.TypeMeta `json:",inline"` @@ -104,6 +75,7 @@ type LibraryPanelList struct { Items []LibraryPanel `json:"items,omitempty"` } +// +k8s:deepcopy-gen=true type LibraryPanelSpec struct { // The panel type Type string `json:"type"` @@ -131,6 +103,7 @@ type LibraryPanelSpec struct { Targets []data.DataQuery `json:"targets,omitempty"` } +// +k8s:deepcopy-gen=true type LibraryPanelStatus struct { // Translation warnings (mostly things that were in SQL columns but not found in the saved body) Warnings []string `json:"warnings,omitempty"` @@ -140,6 +113,7 @@ type LibraryPanelStatus struct { } // This is like the legacy DTO where access and metadata are all returned in a single call +// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type DashboardWithAccessInfo struct { Dashboard `json:",inline"` @@ -147,7 +121,7 @@ type DashboardWithAccessInfo struct { Access DashboardAccess `json:"access"` } -// Information about how the requesting user can use a given dashboard +// +k8s:deepcopy-gen=true type DashboardAccess struct { // Metadata fields Slug string `json:"slug,omitempty"` @@ -162,11 +136,13 @@ type DashboardAccess struct { AnnotationsPermissions *AnnotationPermission `json:"annotationsPermissions"` } +// +k8s:deepcopy-gen=true type AnnotationPermission struct { Dashboard AnnotationActions `json:"dashboard"` Organization AnnotationActions `json:"organization"` } +// +k8s:deepcopy-gen=true type AnnotationActions struct { CanAdd bool `json:"canAdd"` CanEdit bool `json:"canEdit"` diff --git a/pkg/apis/dashboard/v0alpha1/zz_generated.deepcopy.go b/pkg/apis/dashboard/v0alpha1/zz_generated.deepcopy.go index 82e62ccdae6..8d851c4f6c2 100644 --- a/pkg/apis/dashboard/v0alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/dashboard/v0alpha1/zz_generated.deepcopy.go @@ -46,54 +46,6 @@ func (in *AnnotationPermission) DeepCopy() *AnnotationPermission { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ConversionStatus) DeepCopyInto(out *ConversionStatus) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionStatus. -func (in *ConversionStatus) DeepCopy() *ConversionStatus { - if in == nil { - return nil - } - out := new(ConversionStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Dashboard) DeepCopyInto(out *Dashboard) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - if in.Status != nil { - in, out := &in.Status, &out.Status - *out = new(DashboardStatus) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Dashboard. -func (in *Dashboard) DeepCopy() *Dashboard { - if in == nil { - return nil - } - out := new(Dashboard) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Dashboard) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DashboardAccess) DeepCopyInto(out *DashboardAccess) { *out = *in @@ -144,60 +96,6 @@ func (in *DashboardHit) DeepCopy() *DashboardHit { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DashboardList) DeepCopyInto(out *DashboardList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Dashboard, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardList. -func (in *DashboardList) DeepCopy() *DashboardList { - if in == nil { - return nil - } - out := new(DashboardList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DashboardList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DashboardStatus) DeepCopyInto(out *DashboardStatus) { - *out = *in - if in.ConversionStatus != nil { - in, out := &in.ConversionStatus, &out.ConversionStatus - *out = new(ConversionStatus) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardStatus. -func (in *DashboardStatus) DeepCopy() *DashboardStatus { - if in == nil { - return nil - } - out := new(DashboardStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DashboardVersionInfo) DeepCopyInto(out *DashboardVersionInfo) { *out = *in diff --git a/pkg/apis/dashboard/v0alpha1/zz_generated.openapi.go b/pkg/apis/dashboard/v0alpha1/zz_generated.openapi.go index 23197ec669b..6249102860d 100644 --- a/pkg/apis/dashboard/v0alpha1/zz_generated.openapi.go +++ b/pkg/apis/dashboard/v0alpha1/zz_generated.openapi.go @@ -8,34 +8,38 @@ package v0alpha1 import ( + commonv0alpha1 "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" common "k8s.io/kube-openapi/pkg/common" spec "k8s.io/kube-openapi/pkg/validation/spec" ) func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.AnnotationActions": schema_pkg_apis_dashboard_v0alpha1_AnnotationActions(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.AnnotationPermission": schema_pkg_apis_dashboard_v0alpha1_AnnotationPermission(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.ConversionStatus": schema_pkg_apis_dashboard_v0alpha1_ConversionStatus(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.Dashboard": schema_pkg_apis_dashboard_v0alpha1_Dashboard(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardAccess": schema_pkg_apis_dashboard_v0alpha1_DashboardAccess(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardHit": schema_pkg_apis_dashboard_v0alpha1_DashboardHit(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardList": schema_pkg_apis_dashboard_v0alpha1_DashboardList(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus": schema_pkg_apis_dashboard_v0alpha1_DashboardStatus(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardVersionInfo": schema_pkg_apis_dashboard_v0alpha1_DashboardVersionInfo(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardVersionList": schema_pkg_apis_dashboard_v0alpha1_DashboardVersionList(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardWithAccessInfo": schema_pkg_apis_dashboard_v0alpha1_DashboardWithAccessInfo(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.FacetResult": schema_pkg_apis_dashboard_v0alpha1_FacetResult(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanel": schema_pkg_apis_dashboard_v0alpha1_LibraryPanel(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanelList": schema_pkg_apis_dashboard_v0alpha1_LibraryPanelList(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanelSpec": schema_pkg_apis_dashboard_v0alpha1_LibraryPanelSpec(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanelStatus": schema_pkg_apis_dashboard_v0alpha1_LibraryPanelStatus(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SearchResults": schema_pkg_apis_dashboard_v0alpha1_SearchResults(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SortBy": schema_pkg_apis_dashboard_v0alpha1_SortBy(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SortableField": schema_pkg_apis_dashboard_v0alpha1_SortableField(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SortableFields": schema_pkg_apis_dashboard_v0alpha1_SortableFields(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.TermFacet": schema_pkg_apis_dashboard_v0alpha1_TermFacet(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.VersionsQueryOptions": schema_pkg_apis_dashboard_v0alpha1_VersionsQueryOptions(ref), + "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured": commonv0alpha1.Unstructured{}.OpenAPIDefinition(), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.AnnotationActions": schema_pkg_apis_dashboard_v0alpha1_AnnotationActions(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.AnnotationPermission": schema_pkg_apis_dashboard_v0alpha1_AnnotationPermission(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.Dashboard": schema_pkg_apis_dashboard_v0alpha1_Dashboard(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardAccess": schema_pkg_apis_dashboard_v0alpha1_DashboardAccess(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardConversionStatus": schema_pkg_apis_dashboard_v0alpha1_DashboardConversionStatus(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardHit": schema_pkg_apis_dashboard_v0alpha1_DashboardHit(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardJSONCodec": schema_pkg_apis_dashboard_v0alpha1_DashboardJSONCodec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardList": schema_pkg_apis_dashboard_v0alpha1_DashboardList(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardMetadata": schema_pkg_apis_dashboard_v0alpha1_DashboardMetadata(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus": schema_pkg_apis_dashboard_v0alpha1_DashboardStatus(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardVersionInfo": schema_pkg_apis_dashboard_v0alpha1_DashboardVersionInfo(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardVersionList": schema_pkg_apis_dashboard_v0alpha1_DashboardVersionList(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardWithAccessInfo": schema_pkg_apis_dashboard_v0alpha1_DashboardWithAccessInfo(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.FacetResult": schema_pkg_apis_dashboard_v0alpha1_FacetResult(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanel": schema_pkg_apis_dashboard_v0alpha1_LibraryPanel(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanelList": schema_pkg_apis_dashboard_v0alpha1_LibraryPanelList(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanelSpec": schema_pkg_apis_dashboard_v0alpha1_LibraryPanelSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.LibraryPanelStatus": schema_pkg_apis_dashboard_v0alpha1_LibraryPanelStatus(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SearchResults": schema_pkg_apis_dashboard_v0alpha1_SearchResults(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SortBy": schema_pkg_apis_dashboard_v0alpha1_SortBy(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SortableField": schema_pkg_apis_dashboard_v0alpha1_SortableField(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.SortableFields": schema_pkg_apis_dashboard_v0alpha1_SortableFields(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.TermFacet": schema_pkg_apis_dashboard_v0alpha1_TermFacet(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.VersionsQueryOptions": schema_pkg_apis_dashboard_v0alpha1_VersionsQueryOptions(ref), } } @@ -100,36 +104,6 @@ func schema_pkg_apis_dashboard_v0alpha1_AnnotationPermission(ref common.Referenc } } -func schema_pkg_apis_dashboard_v0alpha1_ConversionStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "failed": { - SchemaProps: spec.SchemaProps{ - Type: []string{"boolean"}, - Format: "", - }, - }, - "storedVersion": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "error": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - } -} - func schema_pkg_apis_dashboard_v0alpha1_Dashboard(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -152,25 +126,24 @@ func schema_pkg_apis_dashboard_v0alpha1_Dashboard(ref common.ReferenceCallback) }, "metadata": { SchemaProps: spec.SchemaProps{ - Description: "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), }, }, "spec": { SchemaProps: spec.SchemaProps{ - Description: "The dashboard body (unstructured for now)", + Description: "Spec is the spec of the Dashboard", Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"), }, }, "status": { SchemaProps: spec.SchemaProps{ - Description: "Optional dashboard status", - Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus"), + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus"), }, }, }, - Required: []string{"spec"}, + Required: []string{"metadata", "spec", "status"}, }, }, Dependencies: []string{ @@ -182,8 +155,7 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardAccess(ref common.ReferenceCall return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "Information about how the requesting user can use a given dashboard", - Type: []string{"object"}, + Type: []string{"object"}, Properties: map[string]spec.Schema{ "slug": { SchemaProps: spec.SchemaProps{ @@ -248,6 +220,44 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardAccess(ref common.ReferenceCall } } +func schema_pkg_apis_dashboard_v0alpha1_DashboardConversionStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ConversionStatus is the status of the conversion of the dashboard.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "failed": { + SchemaProps: spec.SchemaProps{ + Description: "Whether from another version has failed. If true, means that the dashboard is not valid, and the caller should instead fetch the stored version.", + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "storedVersion": { + SchemaProps: spec.SchemaProps{ + Description: "The version which was stored when the dashboard was created / updated. Fetching this version should always succeed.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "error": { + SchemaProps: spec.SchemaProps{ + Description: "The error message from the conversion. Empty if the conversion has not failed.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"failed", "storedVersion", "error"}, + }, + }, + } +} + func schema_pkg_apis_dashboard_v0alpha1_DashboardHit(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -328,6 +338,17 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardHit(ref common.ReferenceCallbac } } +func schema_pkg_apis_dashboard_v0alpha1_DashboardJSONCodec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DashboardJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding", + Type: []string{"object"}, + }, + }, + } +} + func schema_pkg_apis_dashboard_v0alpha1_DashboardList(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -368,6 +389,7 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardList(ref common.ReferenceCallba }, }, }, + Required: []string{"metadata", "items"}, }, }, Dependencies: []string{ @@ -375,6 +397,102 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardList(ref common.ReferenceCallba } } +func schema_pkg_apis_dashboard_v0alpha1_DashboardMetadata(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "metadata contains embedded CommonMetadata and can be extended with custom string fields without external reference as using the CommonMetadata reference breaks thema codegen.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "updateTimestamp": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "date-time", + }, + }, + "createdBy": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "uid": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "creationTimestamp": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "date-time", + }, + }, + "deletionTimestamp": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "date-time", + }, + }, + "finalizers": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "resourceVersion": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "generation": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "updatedBy": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "labels": { + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + Required: []string{"updateTimestamp", "createdBy", "uid", "creationTimestamp", "finalizers", "resourceVersion", "generation", "updatedBy", "labels"}, + }, + }, + } +} + func schema_pkg_apis_dashboard_v0alpha1_DashboardStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -383,14 +501,15 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardStatus(ref common.ReferenceCall Properties: map[string]spec.Schema{ "conversion": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.ConversionStatus"), + Description: "Optional conversion status.", + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardConversionStatus"), }, }, }, }, }, Dependencies: []string{ - "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.ConversionStatus"}, + "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardConversionStatus"}, } } @@ -514,21 +633,20 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardWithAccessInfo(ref common.Refer }, "metadata": { SchemaProps: spec.SchemaProps{ - Description: "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), }, }, "spec": { SchemaProps: spec.SchemaProps{ - Description: "The dashboard body (unstructured for now)", + Description: "Spec is the spec of the Dashboard", Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"), }, }, "status": { SchemaProps: spec.SchemaProps{ - Description: "Optional dashboard status", - Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus"), + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1.DashboardStatus"), }, }, "access": { @@ -538,7 +656,7 @@ func schema_pkg_apis_dashboard_v0alpha1_DashboardWithAccessInfo(ref common.Refer }, }, }, - Required: []string{"spec", "access"}, + Required: []string{"metadata", "spec", "status", "access"}, }, }, Dependencies: []string{ diff --git a/pkg/apis/dashboard/v0alpha1/zz_generated.openapi_violation_exceptions.list b/pkg/apis/dashboard/v0alpha1/zz_generated.openapi_violation_exceptions.list index afee90908cc..7061b042725 100644 --- a/pkg/apis/dashboard/v0alpha1/zz_generated.openapi_violation_exceptions.list +++ b/pkg/apis/dashboard/v0alpha1/zz_generated.openapi_violation_exceptions.list @@ -1,8 +1,9 @@ API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,DashboardHit,Tags +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,DashboardMetadata,Finalizers API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,FacetResult,Terms API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,LibraryPanelStatus,Warnings API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,SearchResults,Hits API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,SortableFields,Fields -API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,DashboardStatus,ConversionStatus +API rule violation: names_match,github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1,Unstructured,Object API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,SortBy,Descending API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1,SortableField,Field diff --git a/pkg/apis/dashboard/v1alpha1/constants.go b/pkg/apis/dashboard/v1alpha1/constants.go new file mode 100644 index 00000000000..b3732986f0b --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/constants.go @@ -0,0 +1,18 @@ +package v1alpha1 + +import "k8s.io/apimachinery/pkg/runtime/schema" + +const ( + // Group is the API group used by all kinds in this package + Group = "dashboard.grafana.app" + // Version is the API version used by all kinds in this package + Version = "v1alpha1" +) + +var ( + // GroupVersion is a schema.GroupVersion consisting of the Group and Version constants for this package + GroupVersion = schema.GroupVersion{ + Group: Group, + Version: Version, + } +) diff --git a/pkg/apis/dashboard/v1alpha1/dashboard_codec_gen.go b/pkg/apis/dashboard/v1alpha1/dashboard_codec_gen.go new file mode 100644 index 00000000000..24ee7ecd7bd --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/dashboard_codec_gen.go @@ -0,0 +1,28 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v1alpha1 + +import ( + "encoding/json" + "io" + + "github.com/grafana/grafana-app-sdk/resource" +) + +// DashboardJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding +type DashboardJSONCodec struct{} + +// Read reads JSON-encoded bytes from `reader` and unmarshals them into `into` +func (*DashboardJSONCodec) Read(reader io.Reader, into resource.Object) error { + return json.NewDecoder(reader).Decode(into) +} + +// Write writes JSON-encoded bytes into `writer` marshaled from `from` +func (*DashboardJSONCodec) Write(writer io.Writer, from resource.Object) error { + return json.NewEncoder(writer).Encode(from) +} + +// Interface compliance checks +var _ resource.Codec = &DashboardJSONCodec{} diff --git a/pkg/apis/dashboard/v1alpha1/dashboard_metadata_gen.go b/pkg/apis/dashboard/v1alpha1/dashboard_metadata_gen.go new file mode 100644 index 00000000000..16ead71d265 --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/dashboard_metadata_gen.go @@ -0,0 +1,28 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v1alpha1 + +import ( + time "time" +) + +// metadata contains embedded CommonMetadata and can be extended with custom string fields +// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here +// without external reference as using the CommonMetadata reference breaks thema codegen. +type DashboardMetadata struct { + UpdateTimestamp time.Time `json:"updateTimestamp"` + CreatedBy string `json:"createdBy"` + Uid string `json:"uid"` + CreationTimestamp time.Time `json:"creationTimestamp"` + DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"` + Finalizers []string `json:"finalizers"` + ResourceVersion string `json:"resourceVersion"` + Generation int64 `json:"generation"` + UpdatedBy string `json:"updatedBy"` + Labels map[string]string `json:"labels"` +} + +// NewDashboardMetadata creates a new DashboardMetadata object. +func NewDashboardMetadata() *DashboardMetadata { + return &DashboardMetadata{} +} diff --git a/pkg/apis/dashboard/v1alpha1/dashboard_object_gen.go b/pkg/apis/dashboard/v1alpha1/dashboard_object_gen.go new file mode 100644 index 00000000000..cdf11cabbd0 --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/dashboard_object_gen.go @@ -0,0 +1,269 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v1alpha1 + +import ( + "fmt" + "github.com/grafana/grafana-app-sdk/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "time" +) + +// +k8s:openapi-gen=true +type Dashboard struct { + metav1.TypeMeta `json:",inline" yaml:",inline"` + metav1.ObjectMeta `json:"metadata" yaml:"metadata"` + + // Spec is the spec of the Dashboard + Spec DashboardSpec `json:"spec" yaml:"spec"` + + Status DashboardStatus `json:"status" yaml:"status"` +} + +func (o *Dashboard) GetSpec() any { + return o.Spec +} + +func (o *Dashboard) SetSpec(spec any) error { + cast, ok := spec.(DashboardSpec) + if !ok { + return fmt.Errorf("cannot set spec type %#v, not of type Spec", spec) + } + o.Spec = cast + return nil +} + +func (o *Dashboard) GetSubresources() map[string]any { + return map[string]any{ + "status": o.Status, + } +} + +func (o *Dashboard) GetSubresource(name string) (any, bool) { + switch name { + case "status": + return o.Status, true + default: + return nil, false + } +} + +func (o *Dashboard) SetSubresource(name string, value any) error { + switch name { + case "status": + cast, ok := value.(DashboardStatus) + if !ok { + return fmt.Errorf("cannot set status type %#v, not of type DashboardStatus", value) + } + o.Status = cast + return nil + default: + return fmt.Errorf("subresource '%s' does not exist", name) + } +} + +func (o *Dashboard) GetStaticMetadata() resource.StaticMetadata { + gvk := o.GroupVersionKind() + return resource.StaticMetadata{ + Name: o.ObjectMeta.Name, + Namespace: o.ObjectMeta.Namespace, + Group: gvk.Group, + Version: gvk.Version, + Kind: gvk.Kind, + } +} + +func (o *Dashboard) SetStaticMetadata(metadata resource.StaticMetadata) { + o.Name = metadata.Name + o.Namespace = metadata.Namespace + o.SetGroupVersionKind(schema.GroupVersionKind{ + Group: metadata.Group, + Version: metadata.Version, + Kind: metadata.Kind, + }) +} + +func (o *Dashboard) GetCommonMetadata() resource.CommonMetadata { + dt := o.DeletionTimestamp + var deletionTimestamp *time.Time + if dt != nil { + deletionTimestamp = &dt.Time + } + // Legacy ExtraFields support + extraFields := make(map[string]any) + if o.Annotations != nil { + extraFields["annotations"] = o.Annotations + } + if o.ManagedFields != nil { + extraFields["managedFields"] = o.ManagedFields + } + if o.OwnerReferences != nil { + extraFields["ownerReferences"] = o.OwnerReferences + } + return resource.CommonMetadata{ + UID: string(o.UID), + ResourceVersion: o.ResourceVersion, + Generation: o.Generation, + Labels: o.Labels, + CreationTimestamp: o.CreationTimestamp.Time, + DeletionTimestamp: deletionTimestamp, + Finalizers: o.Finalizers, + UpdateTimestamp: o.GetUpdateTimestamp(), + CreatedBy: o.GetCreatedBy(), + UpdatedBy: o.GetUpdatedBy(), + ExtraFields: extraFields, + } +} + +func (o *Dashboard) SetCommonMetadata(metadata resource.CommonMetadata) { + o.UID = types.UID(metadata.UID) + o.ResourceVersion = metadata.ResourceVersion + o.Generation = metadata.Generation + o.Labels = metadata.Labels + o.CreationTimestamp = metav1.NewTime(metadata.CreationTimestamp) + if metadata.DeletionTimestamp != nil { + dt := metav1.NewTime(*metadata.DeletionTimestamp) + o.DeletionTimestamp = &dt + } else { + o.DeletionTimestamp = nil + } + o.Finalizers = metadata.Finalizers + if o.Annotations == nil { + o.Annotations = make(map[string]string) + } + if !metadata.UpdateTimestamp.IsZero() { + o.SetUpdateTimestamp(metadata.UpdateTimestamp) + } + if metadata.CreatedBy != "" { + o.SetCreatedBy(metadata.CreatedBy) + } + if metadata.UpdatedBy != "" { + o.SetUpdatedBy(metadata.UpdatedBy) + } + // Legacy support for setting Annotations, ManagedFields, and OwnerReferences via ExtraFields + if metadata.ExtraFields != nil { + if annotations, ok := metadata.ExtraFields["annotations"]; ok { + if cast, ok := annotations.(map[string]string); ok { + o.Annotations = cast + } + } + if managedFields, ok := metadata.ExtraFields["managedFields"]; ok { + if cast, ok := managedFields.([]metav1.ManagedFieldsEntry); ok { + o.ManagedFields = cast + } + } + if ownerReferences, ok := metadata.ExtraFields["ownerReferences"]; ok { + if cast, ok := ownerReferences.([]metav1.OwnerReference); ok { + o.OwnerReferences = cast + } + } + } +} + +func (o *Dashboard) GetCreatedBy() string { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + return o.ObjectMeta.Annotations["grafana.com/createdBy"] +} + +func (o *Dashboard) SetCreatedBy(createdBy string) { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + o.ObjectMeta.Annotations["grafana.com/createdBy"] = createdBy +} + +func (o *Dashboard) GetUpdateTimestamp() time.Time { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + parsed, _ := time.Parse(time.RFC3339, o.ObjectMeta.Annotations["grafana.com/updateTimestamp"]) + return parsed +} + +func (o *Dashboard) SetUpdateTimestamp(updateTimestamp time.Time) { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + o.ObjectMeta.Annotations["grafana.com/updateTimestamp"] = updateTimestamp.Format(time.RFC3339) +} + +func (o *Dashboard) GetUpdatedBy() string { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + return o.ObjectMeta.Annotations["grafana.com/updatedBy"] +} + +func (o *Dashboard) SetUpdatedBy(updatedBy string) { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + o.ObjectMeta.Annotations["grafana.com/updatedBy"] = updatedBy +} + +func (o *Dashboard) Copy() resource.Object { + return resource.CopyObject(o) +} + +func (o *Dashboard) DeepCopyObject() runtime.Object { + return o.Copy() +} + +// Interface compliance compile-time check +var _ resource.Object = &Dashboard{} + +// +k8s:openapi-gen=true +type DashboardList struct { + metav1.TypeMeta `json:",inline" yaml:",inline"` + metav1.ListMeta `json:"metadata" yaml:"metadata"` + Items []Dashboard `json:"items" yaml:"items"` +} + +func (o *DashboardList) DeepCopyObject() runtime.Object { + return o.Copy() +} + +func (o *DashboardList) Copy() resource.ListObject { + cpy := &DashboardList{ + TypeMeta: o.TypeMeta, + Items: make([]Dashboard, len(o.Items)), + } + o.ListMeta.DeepCopyInto(&cpy.ListMeta) + for i := 0; i < len(o.Items); i++ { + if item, ok := o.Items[i].Copy().(*Dashboard); ok { + cpy.Items[i] = *item + } + } + return cpy +} + +func (o *DashboardList) GetItems() []resource.Object { + items := make([]resource.Object, len(o.Items)) + for i := 0; i < len(o.Items); i++ { + items[i] = &o.Items[i] + } + return items +} + +func (o *DashboardList) SetItems(items []resource.Object) { + o.Items = make([]Dashboard, len(items)) + for i := 0; i < len(items); i++ { + o.Items[i] = *items[i].(*Dashboard) + } +} + +// Interface compliance compile-time check +var _ resource.ListObject = &DashboardList{} diff --git a/pkg/apis/dashboard/v1alpha1/dashboard_schema_gen.go b/pkg/apis/dashboard/v1alpha1/dashboard_schema_gen.go new file mode 100644 index 00000000000..1c09a83e2bd --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/dashboard_schema_gen.go @@ -0,0 +1,34 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v1alpha1 + +import ( + "github.com/grafana/grafana-app-sdk/resource" +) + +// schema is unexported to prevent accidental overwrites +var ( + schemaDashboard = resource.NewSimpleSchema("dashboard.grafana.app", "v1alpha1", &Dashboard{}, &DashboardList{}, resource.WithKind("Dashboard"), + resource.WithPlural("dashboards"), resource.WithScope(resource.NamespacedScope)) + kindDashboard = resource.Kind{ + Schema: schemaDashboard, + Codecs: map[resource.KindEncoding]resource.Codec{ + resource.KindEncodingJSON: &DashboardJSONCodec{}, + }, + } +) + +// Kind returns a resource.Kind for this Schema with a JSON codec +func DashboardKind() resource.Kind { + return kindDashboard +} + +// Schema returns a resource.SimpleSchema representation of Dashboard +func DashboardSchema() *resource.SimpleSchema { + return schemaDashboard +} + +// Interface compliance checks +var _ resource.Schema = kindDashboard diff --git a/pkg/apis/dashboard/v1alpha1/dashboard_spec.go b/pkg/apis/dashboard/v1alpha1/dashboard_spec.go new file mode 100644 index 00000000000..0b341e6e55e --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/dashboard_spec.go @@ -0,0 +1,11 @@ +package v1alpha1 + +import common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" + +// +k8s:openapi-gen=true +type DashboardSpec = common.Unstructured + +// NewDashboardSpec creates a new Spec object. +func NewDashboardSpec() *DashboardSpec { + return &DashboardSpec{} +} diff --git a/pkg/apis/dashboard/v1alpha1/dashboard_spec_gen.go b/pkg/apis/dashboard/v1alpha1/dashboard_spec_gen.go new file mode 100644 index 00000000000..4f48fee9aae --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/dashboard_spec_gen.go @@ -0,0 +1,3 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v1alpha1 diff --git a/pkg/apis/dashboard/v1alpha1/dashboard_status_gen.go b/pkg/apis/dashboard/v1alpha1/dashboard_status_gen.go new file mode 100644 index 00000000000..556d5ddba53 --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/dashboard_status_gen.go @@ -0,0 +1,34 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v1alpha1 + +// ConversionStatus is the status of the conversion of the dashboard. +// +k8s:openapi-gen=true +type DashboardConversionStatus struct { + // Whether from another version has failed. + // If true, means that the dashboard is not valid, + // and the caller should instead fetch the stored version. + Failed bool `json:"failed"` + // The version which was stored when the dashboard was created / updated. + // Fetching this version should always succeed. + StoredVersion string `json:"storedVersion"` + // The error message from the conversion. + // Empty if the conversion has not failed. + Error string `json:"error"` +} + +// NewDashboardConversionStatus creates a new DashboardConversionStatus object. +func NewDashboardConversionStatus() *DashboardConversionStatus { + return &DashboardConversionStatus{} +} + +// +k8s:openapi-gen=true +type DashboardStatus struct { + // Optional conversion status. + Conversion *DashboardConversionStatus `json:"conversion,omitempty"` +} + +// NewDashboardStatus creates a new DashboardStatus object. +func NewDashboardStatus() *DashboardStatus { + return &DashboardStatus{} +} diff --git a/pkg/apis/dashboard/v1alpha1/deepcopy.go b/pkg/apis/dashboard/v1alpha1/deepcopy.go new file mode 100644 index 00000000000..1e05aa647f2 --- /dev/null +++ b/pkg/apis/dashboard/v1alpha1/deepcopy.go @@ -0,0 +1,41 @@ +package v1alpha1 + +// TODO: these should be automatically generated by the SDK. + +func (in *Dashboard) DeepCopyInto(out *Dashboard) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +func (in *Dashboard) DeepCopy() *Dashboard { + if in == nil { + return nil + } + out := new(Dashboard) + in.DeepCopyInto(out) + return out +} + +func (in *DashboardList) DeepCopyInto(out *DashboardList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Dashboard, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +func (in *DashboardList) DeepCopy() *DashboardList { + if in == nil { + return nil + } + out := new(DashboardList) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apis/dashboard/v1alpha1/doc.go b/pkg/apis/dashboard/v1alpha1/doc.go index 288a406db14..f10d157ec41 100644 --- a/pkg/apis/dashboard/v1alpha1/doc.go +++ b/pkg/apis/dashboard/v1alpha1/doc.go @@ -1,7 +1,10 @@ -// +k8s:deepcopy-gen=package // +k8s:openapi-gen=true // +k8s:defaulter-gen=TypeMeta // +k8s:conversion-gen=github.com/grafana/grafana/pkg/apis/dashboard // +groupName=dashboard.grafana.app +// NOTE (@radiohead): we do not use package-wide deepcopy generation +// because grafana-app-sdk already provides deepcopy functions. +// Kinds which are not generated by the SDK are explicitly opted in to deepcopy generation. + package v1alpha1 // import "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1" diff --git a/pkg/apis/dashboard/v1alpha1/types.go b/pkg/apis/dashboard/v1alpha1/types.go index 0a5144508a1..43844655505 100644 --- a/pkg/apis/dashboard/v1alpha1/types.go +++ b/pkg/apis/dashboard/v1alpha1/types.go @@ -7,40 +7,7 @@ import ( common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" ) -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -type Dashboard struct { - metav1.TypeMeta `json:",inline"` - // Standard object's metadata - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - metav1.ObjectMeta `json:"metadata,omitempty"` - - // The dashboard body (unstructured for now) - Spec common.Unstructured `json:"spec"` - - // Optional dashboard status - Status *DashboardStatus `json:"status,omitempty"` -} - -type DashboardStatus struct { - ConversionStatus *ConversionStatus `json:"conversion,omitempty"` -} - -type ConversionStatus struct { - Failed bool `json:"failed,omitempty"` - StoredVersion string `json:"storedVersion,omitempty"` - Error string `json:"error,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -type DashboardList struct { - metav1.TypeMeta `json:",inline"` - // +optional - metav1.ListMeta `json:"metadata,omitempty"` - - Items []Dashboard `json:"items,omitempty"` -} - +// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type DashboardVersionList struct { metav1.TypeMeta `json:",inline"` @@ -50,6 +17,7 @@ type DashboardVersionList struct { Items []DashboardVersionInfo `json:"items,omitempty"` } +// +k8s:deepcopy-gen=true type DashboardVersionInfo struct { // The internal ID for this version (will be replaced with resourceVersion) Version int `json:"version"` @@ -67,6 +35,7 @@ type DashboardVersionInfo struct { Message string `json:"message,omitempty"` } +// +k8s:deepcopy-gen=true // +k8s:conversion-gen:explicit-from=net/url.Values // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type VersionsQueryOptions struct { @@ -80,6 +49,7 @@ type VersionsQueryOptions struct { Version int64 `json:"version,omitempty"` } +// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type LibraryPanel struct { metav1.TypeMeta `json:",inline"` @@ -95,6 +65,7 @@ type LibraryPanel struct { Status *LibraryPanelStatus `json:"status,omitempty"` } +// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type LibraryPanelList struct { metav1.TypeMeta `json:",inline"` @@ -104,6 +75,7 @@ type LibraryPanelList struct { Items []LibraryPanel `json:"items,omitempty"` } +// +k8s:deepcopy-gen=true type LibraryPanelSpec struct { // The panel type Type string `json:"type"` @@ -131,6 +103,7 @@ type LibraryPanelSpec struct { Targets []data.DataQuery `json:"targets,omitempty"` } +// +k8s:deepcopy-gen=true type LibraryPanelStatus struct { // Translation warnings (mostly things that were in SQL columns but not found in the saved body) Warnings []string `json:"warnings,omitempty"` @@ -140,6 +113,7 @@ type LibraryPanelStatus struct { } // This is like the legacy DTO where access and metadata are all returned in a single call +// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type DashboardWithAccessInfo struct { Dashboard `json:",inline"` @@ -148,6 +122,7 @@ type DashboardWithAccessInfo struct { } // Information about how the requesting user can use a given dashboard +// +k8s:deepcopy-gen=true type DashboardAccess struct { // Metadata fields Slug string `json:"slug,omitempty"` @@ -162,11 +137,13 @@ type DashboardAccess struct { AnnotationsPermissions *AnnotationPermission `json:"annotationsPermissions"` } +// +k8s:deepcopy-gen=true type AnnotationPermission struct { Dashboard AnnotationActions `json:"dashboard"` Organization AnnotationActions `json:"organization"` } +// +k8s:deepcopy-gen=true type AnnotationActions struct { CanAdd bool `json:"canAdd"` CanEdit bool `json:"canEdit"` diff --git a/pkg/apis/dashboard/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/dashboard/v1alpha1/zz_generated.deepcopy.go index c94be011e07..8e38161cc58 100644 --- a/pkg/apis/dashboard/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/dashboard/v1alpha1/zz_generated.deepcopy.go @@ -46,54 +46,6 @@ func (in *AnnotationPermission) DeepCopy() *AnnotationPermission { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ConversionStatus) DeepCopyInto(out *ConversionStatus) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionStatus. -func (in *ConversionStatus) DeepCopy() *ConversionStatus { - if in == nil { - return nil - } - out := new(ConversionStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Dashboard) DeepCopyInto(out *Dashboard) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - if in.Status != nil { - in, out := &in.Status, &out.Status - *out = new(DashboardStatus) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Dashboard. -func (in *Dashboard) DeepCopy() *Dashboard { - if in == nil { - return nil - } - out := new(Dashboard) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Dashboard) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DashboardAccess) DeepCopyInto(out *DashboardAccess) { *out = *in @@ -115,60 +67,6 @@ func (in *DashboardAccess) DeepCopy() *DashboardAccess { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DashboardList) DeepCopyInto(out *DashboardList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Dashboard, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardList. -func (in *DashboardList) DeepCopy() *DashboardList { - if in == nil { - return nil - } - out := new(DashboardList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DashboardList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DashboardStatus) DeepCopyInto(out *DashboardStatus) { - *out = *in - if in.ConversionStatus != nil { - in, out := &in.ConversionStatus, &out.ConversionStatus - *out = new(ConversionStatus) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardStatus. -func (in *DashboardStatus) DeepCopy() *DashboardStatus { - if in == nil { - return nil - } - out := new(DashboardStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DashboardVersionInfo) DeepCopyInto(out *DashboardVersionInfo) { *out = *in diff --git a/pkg/apis/dashboard/v1alpha1/zz_generated.openapi.go b/pkg/apis/dashboard/v1alpha1/zz_generated.openapi.go index e6f99cd895c..f9de16ee169 100644 --- a/pkg/apis/dashboard/v1alpha1/zz_generated.openapi.go +++ b/pkg/apis/dashboard/v1alpha1/zz_generated.openapi.go @@ -8,27 +8,31 @@ package v1alpha1 import ( + v0alpha1 "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" common "k8s.io/kube-openapi/pkg/common" spec "k8s.io/kube-openapi/pkg/validation/spec" ) func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.AnnotationActions": schema_pkg_apis_dashboard_v1alpha1_AnnotationActions(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.AnnotationPermission": schema_pkg_apis_dashboard_v1alpha1_AnnotationPermission(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.ConversionStatus": schema_pkg_apis_dashboard_v1alpha1_ConversionStatus(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.Dashboard": schema_pkg_apis_dashboard_v1alpha1_Dashboard(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardAccess": schema_pkg_apis_dashboard_v1alpha1_DashboardAccess(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardList": schema_pkg_apis_dashboard_v1alpha1_DashboardList(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardStatus": schema_pkg_apis_dashboard_v1alpha1_DashboardStatus(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardVersionInfo": schema_pkg_apis_dashboard_v1alpha1_DashboardVersionInfo(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardVersionList": schema_pkg_apis_dashboard_v1alpha1_DashboardVersionList(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardWithAccessInfo": schema_pkg_apis_dashboard_v1alpha1_DashboardWithAccessInfo(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanel": schema_pkg_apis_dashboard_v1alpha1_LibraryPanel(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanelList": schema_pkg_apis_dashboard_v1alpha1_LibraryPanelList(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanelSpec": schema_pkg_apis_dashboard_v1alpha1_LibraryPanelSpec(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanelStatus": schema_pkg_apis_dashboard_v1alpha1_LibraryPanelStatus(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.VersionsQueryOptions": schema_pkg_apis_dashboard_v1alpha1_VersionsQueryOptions(ref), + "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured": v0alpha1.Unstructured{}.OpenAPIDefinition(), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.AnnotationActions": schema_pkg_apis_dashboard_v1alpha1_AnnotationActions(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.AnnotationPermission": schema_pkg_apis_dashboard_v1alpha1_AnnotationPermission(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.Dashboard": schema_pkg_apis_dashboard_v1alpha1_Dashboard(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardAccess": schema_pkg_apis_dashboard_v1alpha1_DashboardAccess(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardConversionStatus": schema_pkg_apis_dashboard_v1alpha1_DashboardConversionStatus(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardJSONCodec": schema_pkg_apis_dashboard_v1alpha1_DashboardJSONCodec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardList": schema_pkg_apis_dashboard_v1alpha1_DashboardList(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardMetadata": schema_pkg_apis_dashboard_v1alpha1_DashboardMetadata(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardStatus": schema_pkg_apis_dashboard_v1alpha1_DashboardStatus(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardVersionInfo": schema_pkg_apis_dashboard_v1alpha1_DashboardVersionInfo(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardVersionList": schema_pkg_apis_dashboard_v1alpha1_DashboardVersionList(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardWithAccessInfo": schema_pkg_apis_dashboard_v1alpha1_DashboardWithAccessInfo(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanel": schema_pkg_apis_dashboard_v1alpha1_LibraryPanel(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanelList": schema_pkg_apis_dashboard_v1alpha1_LibraryPanelList(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanelSpec": schema_pkg_apis_dashboard_v1alpha1_LibraryPanelSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.LibraryPanelStatus": schema_pkg_apis_dashboard_v1alpha1_LibraryPanelStatus(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.VersionsQueryOptions": schema_pkg_apis_dashboard_v1alpha1_VersionsQueryOptions(ref), } } @@ -93,36 +97,6 @@ func schema_pkg_apis_dashboard_v1alpha1_AnnotationPermission(ref common.Referenc } } -func schema_pkg_apis_dashboard_v1alpha1_ConversionStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "failed": { - SchemaProps: spec.SchemaProps{ - Type: []string{"boolean"}, - Format: "", - }, - }, - "storedVersion": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "error": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - } -} - func schema_pkg_apis_dashboard_v1alpha1_Dashboard(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -145,25 +119,24 @@ func schema_pkg_apis_dashboard_v1alpha1_Dashboard(ref common.ReferenceCallback) }, "metadata": { SchemaProps: spec.SchemaProps{ - Description: "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), }, }, "spec": { SchemaProps: spec.SchemaProps{ - Description: "The dashboard body (unstructured for now)", + Description: "Spec is the spec of the Dashboard", Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"), }, }, "status": { SchemaProps: spec.SchemaProps{ - Description: "Optional dashboard status", - Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardStatus"), + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardStatus"), }, }, }, - Required: []string{"spec"}, + Required: []string{"metadata", "spec", "status"}, }, }, Dependencies: []string{ @@ -241,6 +214,55 @@ func schema_pkg_apis_dashboard_v1alpha1_DashboardAccess(ref common.ReferenceCall } } +func schema_pkg_apis_dashboard_v1alpha1_DashboardConversionStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ConversionStatus is the status of the conversion of the dashboard.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "failed": { + SchemaProps: spec.SchemaProps{ + Description: "Whether from another version has failed. If true, means that the dashboard is not valid, and the caller should instead fetch the stored version.", + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "storedVersion": { + SchemaProps: spec.SchemaProps{ + Description: "The version which was stored when the dashboard was created / updated. Fetching this version should always succeed.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "error": { + SchemaProps: spec.SchemaProps{ + Description: "The error message from the conversion. Empty if the conversion has not failed.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"failed", "storedVersion", "error"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v1alpha1_DashboardJSONCodec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DashboardJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding", + Type: []string{"object"}, + }, + }, + } +} + func schema_pkg_apis_dashboard_v1alpha1_DashboardList(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -281,6 +303,7 @@ func schema_pkg_apis_dashboard_v1alpha1_DashboardList(ref common.ReferenceCallba }, }, }, + Required: []string{"metadata", "items"}, }, }, Dependencies: []string{ @@ -288,6 +311,102 @@ func schema_pkg_apis_dashboard_v1alpha1_DashboardList(ref common.ReferenceCallba } } +func schema_pkg_apis_dashboard_v1alpha1_DashboardMetadata(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "metadata contains embedded CommonMetadata and can be extended with custom string fields without external reference as using the CommonMetadata reference breaks thema codegen.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "updateTimestamp": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "date-time", + }, + }, + "createdBy": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "uid": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "creationTimestamp": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "date-time", + }, + }, + "deletionTimestamp": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "date-time", + }, + }, + "finalizers": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "resourceVersion": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "generation": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "updatedBy": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "labels": { + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + Required: []string{"updateTimestamp", "createdBy", "uid", "creationTimestamp", "finalizers", "resourceVersion", "generation", "updatedBy", "labels"}, + }, + }, + } +} + func schema_pkg_apis_dashboard_v1alpha1_DashboardStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -296,14 +415,15 @@ func schema_pkg_apis_dashboard_v1alpha1_DashboardStatus(ref common.ReferenceCall Properties: map[string]spec.Schema{ "conversion": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.ConversionStatus"), + Description: "Optional conversion status.", + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardConversionStatus"), }, }, }, }, }, Dependencies: []string{ - "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.ConversionStatus"}, + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardConversionStatus"}, } } @@ -427,21 +547,20 @@ func schema_pkg_apis_dashboard_v1alpha1_DashboardWithAccessInfo(ref common.Refer }, "metadata": { SchemaProps: spec.SchemaProps{ - Description: "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), }, }, "spec": { SchemaProps: spec.SchemaProps{ - Description: "The dashboard body (unstructured for now)", + Description: "Spec is the spec of the Dashboard", Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"), }, }, "status": { SchemaProps: spec.SchemaProps{ - Description: "Optional dashboard status", - Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardStatus"), + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1.DashboardStatus"), }, }, "access": { @@ -451,7 +570,7 @@ func schema_pkg_apis_dashboard_v1alpha1_DashboardWithAccessInfo(ref common.Refer }, }, }, - Required: []string{"spec", "access"}, + Required: []string{"metadata", "spec", "status", "access"}, }, }, Dependencies: []string{ diff --git a/pkg/apis/dashboard/v1alpha1/zz_generated.openapi_violation_exceptions.list b/pkg/apis/dashboard/v1alpha1/zz_generated.openapi_violation_exceptions.list index bbfa46dae2b..a34c29a7192 100644 --- a/pkg/apis/dashboard/v1alpha1/zz_generated.openapi_violation_exceptions.list +++ b/pkg/apis/dashboard/v1alpha1/zz_generated.openapi_violation_exceptions.list @@ -1,2 +1,3 @@ +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1,DashboardMetadata,Finalizers API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1,LibraryPanelStatus,Warnings -API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1,DashboardStatus,ConversionStatus +API rule violation: names_match,github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1,Unstructured,Object diff --git a/pkg/apis/dashboard/v2alpha1/constants.go b/pkg/apis/dashboard/v2alpha1/constants.go new file mode 100644 index 00000000000..84b030c8994 --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/constants.go @@ -0,0 +1,18 @@ +package v2alpha1 + +import "k8s.io/apimachinery/pkg/runtime/schema" + +const ( + // Group is the API group used by all kinds in this package + Group = "dashboard.grafana.app" + // Version is the API version used by all kinds in this package + Version = "v2alpha1" +) + +var ( + // GroupVersion is a schema.GroupVersion consisting of the Group and Version constants for this package + GroupVersion = schema.GroupVersion{ + Group: Group, + Version: Version, + } +) diff --git a/pkg/apis/dashboard/v2alpha1/dashboard_codec_gen.go b/pkg/apis/dashboard/v2alpha1/dashboard_codec_gen.go new file mode 100644 index 00000000000..a1892865692 --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/dashboard_codec_gen.go @@ -0,0 +1,28 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v2alpha1 + +import ( + "encoding/json" + "io" + + "github.com/grafana/grafana-app-sdk/resource" +) + +// DashboardJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding +type DashboardJSONCodec struct{} + +// Read reads JSON-encoded bytes from `reader` and unmarshals them into `into` +func (*DashboardJSONCodec) Read(reader io.Reader, into resource.Object) error { + return json.NewDecoder(reader).Decode(into) +} + +// Write writes JSON-encoded bytes into `writer` marshaled from `from` +func (*DashboardJSONCodec) Write(writer io.Writer, from resource.Object) error { + return json.NewEncoder(writer).Encode(from) +} + +// Interface compliance checks +var _ resource.Codec = &DashboardJSONCodec{} diff --git a/pkg/apis/dashboard/v2alpha1/dashboard_metadata_gen.go b/pkg/apis/dashboard/v2alpha1/dashboard_metadata_gen.go new file mode 100644 index 00000000000..f4e92178780 --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/dashboard_metadata_gen.go @@ -0,0 +1,28 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v2alpha1 + +import ( + time "time" +) + +// metadata contains embedded CommonMetadata and can be extended with custom string fields +// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here +// without external reference as using the CommonMetadata reference breaks thema codegen. +type DashboardMetadata struct { + UpdateTimestamp time.Time `json:"updateTimestamp"` + CreatedBy string `json:"createdBy"` + Uid string `json:"uid"` + CreationTimestamp time.Time `json:"creationTimestamp"` + DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"` + Finalizers []string `json:"finalizers"` + ResourceVersion string `json:"resourceVersion"` + Generation int64 `json:"generation"` + UpdatedBy string `json:"updatedBy"` + Labels map[string]string `json:"labels"` +} + +// NewDashboardMetadata creates a new DashboardMetadata object. +func NewDashboardMetadata() *DashboardMetadata { + return &DashboardMetadata{} +} diff --git a/pkg/apis/dashboard/v2alpha1/dashboard_object_gen.go b/pkg/apis/dashboard/v2alpha1/dashboard_object_gen.go new file mode 100644 index 00000000000..504dc5a25f1 --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/dashboard_object_gen.go @@ -0,0 +1,269 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v2alpha1 + +import ( + "fmt" + "github.com/grafana/grafana-app-sdk/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "time" +) + +// +k8s:openapi-gen=true +type Dashboard struct { + metav1.TypeMeta `json:",inline" yaml:",inline"` + metav1.ObjectMeta `json:"metadata" yaml:"metadata"` + + // Spec is the spec of the Dashboard + Spec DashboardSpec `json:"spec" yaml:"spec"` + + Status DashboardStatus `json:"status" yaml:"status"` +} + +func (o *Dashboard) GetSpec() any { + return o.Spec +} + +func (o *Dashboard) SetSpec(spec any) error { + cast, ok := spec.(DashboardSpec) + if !ok { + return fmt.Errorf("cannot set spec type %#v, not of type Spec", spec) + } + o.Spec = cast + return nil +} + +func (o *Dashboard) GetSubresources() map[string]any { + return map[string]any{ + "status": o.Status, + } +} + +func (o *Dashboard) GetSubresource(name string) (any, bool) { + switch name { + case "status": + return o.Status, true + default: + return nil, false + } +} + +func (o *Dashboard) SetSubresource(name string, value any) error { + switch name { + case "status": + cast, ok := value.(DashboardStatus) + if !ok { + return fmt.Errorf("cannot set status type %#v, not of type DashboardStatus", value) + } + o.Status = cast + return nil + default: + return fmt.Errorf("subresource '%s' does not exist", name) + } +} + +func (o *Dashboard) GetStaticMetadata() resource.StaticMetadata { + gvk := o.GroupVersionKind() + return resource.StaticMetadata{ + Name: o.ObjectMeta.Name, + Namespace: o.ObjectMeta.Namespace, + Group: gvk.Group, + Version: gvk.Version, + Kind: gvk.Kind, + } +} + +func (o *Dashboard) SetStaticMetadata(metadata resource.StaticMetadata) { + o.Name = metadata.Name + o.Namespace = metadata.Namespace + o.SetGroupVersionKind(schema.GroupVersionKind{ + Group: metadata.Group, + Version: metadata.Version, + Kind: metadata.Kind, + }) +} + +func (o *Dashboard) GetCommonMetadata() resource.CommonMetadata { + dt := o.DeletionTimestamp + var deletionTimestamp *time.Time + if dt != nil { + deletionTimestamp = &dt.Time + } + // Legacy ExtraFields support + extraFields := make(map[string]any) + if o.Annotations != nil { + extraFields["annotations"] = o.Annotations + } + if o.ManagedFields != nil { + extraFields["managedFields"] = o.ManagedFields + } + if o.OwnerReferences != nil { + extraFields["ownerReferences"] = o.OwnerReferences + } + return resource.CommonMetadata{ + UID: string(o.UID), + ResourceVersion: o.ResourceVersion, + Generation: o.Generation, + Labels: o.Labels, + CreationTimestamp: o.CreationTimestamp.Time, + DeletionTimestamp: deletionTimestamp, + Finalizers: o.Finalizers, + UpdateTimestamp: o.GetUpdateTimestamp(), + CreatedBy: o.GetCreatedBy(), + UpdatedBy: o.GetUpdatedBy(), + ExtraFields: extraFields, + } +} + +func (o *Dashboard) SetCommonMetadata(metadata resource.CommonMetadata) { + o.UID = types.UID(metadata.UID) + o.ResourceVersion = metadata.ResourceVersion + o.Generation = metadata.Generation + o.Labels = metadata.Labels + o.CreationTimestamp = metav1.NewTime(metadata.CreationTimestamp) + if metadata.DeletionTimestamp != nil { + dt := metav1.NewTime(*metadata.DeletionTimestamp) + o.DeletionTimestamp = &dt + } else { + o.DeletionTimestamp = nil + } + o.Finalizers = metadata.Finalizers + if o.Annotations == nil { + o.Annotations = make(map[string]string) + } + if !metadata.UpdateTimestamp.IsZero() { + o.SetUpdateTimestamp(metadata.UpdateTimestamp) + } + if metadata.CreatedBy != "" { + o.SetCreatedBy(metadata.CreatedBy) + } + if metadata.UpdatedBy != "" { + o.SetUpdatedBy(metadata.UpdatedBy) + } + // Legacy support for setting Annotations, ManagedFields, and OwnerReferences via ExtraFields + if metadata.ExtraFields != nil { + if annotations, ok := metadata.ExtraFields["annotations"]; ok { + if cast, ok := annotations.(map[string]string); ok { + o.Annotations = cast + } + } + if managedFields, ok := metadata.ExtraFields["managedFields"]; ok { + if cast, ok := managedFields.([]metav1.ManagedFieldsEntry); ok { + o.ManagedFields = cast + } + } + if ownerReferences, ok := metadata.ExtraFields["ownerReferences"]; ok { + if cast, ok := ownerReferences.([]metav1.OwnerReference); ok { + o.OwnerReferences = cast + } + } + } +} + +func (o *Dashboard) GetCreatedBy() string { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + return o.ObjectMeta.Annotations["grafana.com/createdBy"] +} + +func (o *Dashboard) SetCreatedBy(createdBy string) { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + o.ObjectMeta.Annotations["grafana.com/createdBy"] = createdBy +} + +func (o *Dashboard) GetUpdateTimestamp() time.Time { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + parsed, _ := time.Parse(time.RFC3339, o.ObjectMeta.Annotations["grafana.com/updateTimestamp"]) + return parsed +} + +func (o *Dashboard) SetUpdateTimestamp(updateTimestamp time.Time) { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + o.ObjectMeta.Annotations["grafana.com/updateTimestamp"] = updateTimestamp.Format(time.RFC3339) +} + +func (o *Dashboard) GetUpdatedBy() string { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + return o.ObjectMeta.Annotations["grafana.com/updatedBy"] +} + +func (o *Dashboard) SetUpdatedBy(updatedBy string) { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + o.ObjectMeta.Annotations["grafana.com/updatedBy"] = updatedBy +} + +func (o *Dashboard) Copy() resource.Object { + return resource.CopyObject(o) +} + +func (o *Dashboard) DeepCopyObject() runtime.Object { + return o.Copy() +} + +// Interface compliance compile-time check +var _ resource.Object = &Dashboard{} + +// +k8s:openapi-gen=true +type DashboardList struct { + metav1.TypeMeta `json:",inline" yaml:",inline"` + metav1.ListMeta `json:"metadata" yaml:"metadata"` + Items []Dashboard `json:"items" yaml:"items"` +} + +func (o *DashboardList) DeepCopyObject() runtime.Object { + return o.Copy() +} + +func (o *DashboardList) Copy() resource.ListObject { + cpy := &DashboardList{ + TypeMeta: o.TypeMeta, + Items: make([]Dashboard, len(o.Items)), + } + o.ListMeta.DeepCopyInto(&cpy.ListMeta) + for i := 0; i < len(o.Items); i++ { + if item, ok := o.Items[i].Copy().(*Dashboard); ok { + cpy.Items[i] = *item + } + } + return cpy +} + +func (o *DashboardList) GetItems() []resource.Object { + items := make([]resource.Object, len(o.Items)) + for i := 0; i < len(o.Items); i++ { + items[i] = &o.Items[i] + } + return items +} + +func (o *DashboardList) SetItems(items []resource.Object) { + o.Items = make([]Dashboard, len(items)) + for i := 0; i < len(items); i++ { + o.Items[i] = *items[i].(*Dashboard) + } +} + +// Interface compliance compile-time check +var _ resource.ListObject = &DashboardList{} diff --git a/pkg/apis/dashboard/v2alpha1/dashboard_schema_gen.go b/pkg/apis/dashboard/v2alpha1/dashboard_schema_gen.go new file mode 100644 index 00000000000..136698cf70f --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/dashboard_schema_gen.go @@ -0,0 +1,34 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v2alpha1 + +import ( + "github.com/grafana/grafana-app-sdk/resource" +) + +// schema is unexported to prevent accidental overwrites +var ( + schemaDashboard = resource.NewSimpleSchema("dashboard.grafana.app", "v2alpha1", &Dashboard{}, &DashboardList{}, resource.WithKind("Dashboard"), + resource.WithPlural("dashboards"), resource.WithScope(resource.NamespacedScope)) + kindDashboard = resource.Kind{ + Schema: schemaDashboard, + Codecs: map[resource.KindEncoding]resource.Codec{ + resource.KindEncodingJSON: &DashboardJSONCodec{}, + }, + } +) + +// Kind returns a resource.Kind for this Schema with a JSON codec +func DashboardKind() resource.Kind { + return kindDashboard +} + +// Schema returns a resource.SimpleSchema representation of Dashboard +func DashboardSchema() *resource.SimpleSchema { + return schemaDashboard +} + +// Interface compliance checks +var _ resource.Schema = kindDashboard diff --git a/pkg/apis/dashboard/v2alpha1/dashboard_spec_gen.go b/pkg/apis/dashboard/v2alpha1/dashboard_spec_gen.go new file mode 100644 index 00000000000..ade7b3398b0 --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/dashboard_spec_gen.go @@ -0,0 +1,2373 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v2alpha1 + +import ( + json "encoding/json" + errors "errors" + fmt "fmt" +) + +// +k8s:openapi-gen=true +type DashboardAnnotationQueryKind struct { + Kind string `json:"kind"` + Spec DashboardAnnotationQuerySpec `json:"spec"` +} + +// NewDashboardAnnotationQueryKind creates a new DashboardAnnotationQueryKind object. +func NewDashboardAnnotationQueryKind() *DashboardAnnotationQueryKind { + return &DashboardAnnotationQueryKind{ + Kind: "AnnotationQuery", + Spec: *NewDashboardAnnotationQuerySpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardAnnotationQuerySpec struct { + Datasource *DashboardDataSourceRef `json:"datasource,omitempty"` + Query *DashboardDataQueryKind `json:"query,omitempty"` + Enable bool `json:"enable"` + Hide bool `json:"hide"` + IconColor string `json:"iconColor"` + Name string `json:"name"` + BuiltIn *bool `json:"builtIn,omitempty"` + Filter *DashboardAnnotationPanelFilter `json:"filter,omitempty"` +} + +// NewDashboardAnnotationQuerySpec creates a new DashboardAnnotationQuerySpec object. +func NewDashboardAnnotationQuerySpec() *DashboardAnnotationQuerySpec { + return &DashboardAnnotationQuerySpec{ + BuiltIn: (func(input bool) *bool { return &input })(false), + } +} + +// +k8s:openapi-gen=true +type DashboardDataSourceRef struct { + // The plugin type-id + Type *string `json:"type,omitempty"` + // Specific datasource instance + Uid *string `json:"uid,omitempty"` +} + +// NewDashboardDataSourceRef creates a new DashboardDataSourceRef object. +func NewDashboardDataSourceRef() *DashboardDataSourceRef { + return &DashboardDataSourceRef{} +} + +// +k8s:openapi-gen=true +type DashboardDataQueryKind struct { + // The kind of a DataQueryKind is the datasource type + Kind string `json:"kind"` + Spec map[string]interface{} `json:"spec"` +} + +// NewDashboardDataQueryKind creates a new DashboardDataQueryKind object. +func NewDashboardDataQueryKind() *DashboardDataQueryKind { + return &DashboardDataQueryKind{} +} + +// +k8s:openapi-gen=true +type DashboardAnnotationPanelFilter struct { + // Should the specified panels be included or excluded + Exclude *bool `json:"exclude,omitempty"` + // Panel IDs that should be included or excluded + Ids []uint8 `json:"ids"` +} + +// NewDashboardAnnotationPanelFilter creates a new DashboardAnnotationPanelFilter object. +func NewDashboardAnnotationPanelFilter() *DashboardAnnotationPanelFilter { + return &DashboardAnnotationPanelFilter{ + Exclude: (func(input bool) *bool { return &input })(false), + } +} + +// "Off" for no shared crosshair or tooltip (default). +// "Crosshair" for shared crosshair. +// "Tooltip" for shared crosshair AND shared tooltip. +// +k8s:openapi-gen=true +type DashboardDashboardCursorSync string + +const ( + DashboardDashboardCursorSyncOff DashboardDashboardCursorSync = "Off" + DashboardDashboardCursorSyncCrosshair DashboardDashboardCursorSync = "Crosshair" + DashboardDashboardCursorSyncTooltip DashboardDashboardCursorSync = "Tooltip" +) + +// Supported dashboard elements +// |* more element types in the future +// +k8s:openapi-gen=true +type DashboardElement = DashboardPanelKindOrLibraryPanelKind + +// NewDashboardElement creates a new DashboardElement object. +func NewDashboardElement() *DashboardElement { + return NewDashboardPanelKindOrLibraryPanelKind() +} + +// +k8s:openapi-gen=true +type DashboardPanelKind struct { + Kind string `json:"kind"` + Spec DashboardPanelSpec `json:"spec"` +} + +// NewDashboardPanelKind creates a new DashboardPanelKind object. +func NewDashboardPanelKind() *DashboardPanelKind { + return &DashboardPanelKind{ + Kind: "Panel", + Spec: *NewDashboardPanelSpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardPanelSpec struct { + Id float64 `json:"id"` + Title string `json:"title"` + Description string `json:"description"` + Links []DashboardDataLink `json:"links"` + Data DashboardQueryGroupKind `json:"data"` + VizConfig DashboardVizConfigKind `json:"vizConfig"` + Transparent *bool `json:"transparent,omitempty"` +} + +// NewDashboardPanelSpec creates a new DashboardPanelSpec object. +func NewDashboardPanelSpec() *DashboardPanelSpec { + return &DashboardPanelSpec{ + Data: *NewDashboardQueryGroupKind(), + VizConfig: *NewDashboardVizConfigKind(), + } +} + +// +k8s:openapi-gen=true +type DashboardDataLink struct { + Title string `json:"title"` + Url string `json:"url"` + TargetBlank *bool `json:"targetBlank,omitempty"` +} + +// NewDashboardDataLink creates a new DashboardDataLink object. +func NewDashboardDataLink() *DashboardDataLink { + return &DashboardDataLink{} +} + +// +k8s:openapi-gen=true +type DashboardQueryGroupKind struct { + Kind string `json:"kind"` + Spec DashboardQueryGroupSpec `json:"spec"` +} + +// NewDashboardQueryGroupKind creates a new DashboardQueryGroupKind object. +func NewDashboardQueryGroupKind() *DashboardQueryGroupKind { + return &DashboardQueryGroupKind{ + Kind: "QueryGroup", + Spec: *NewDashboardQueryGroupSpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardQueryGroupSpec struct { + Queries []DashboardPanelQueryKind `json:"queries"` + Transformations []DashboardTransformationKind `json:"transformations"` + QueryOptions DashboardQueryOptionsSpec `json:"queryOptions"` +} + +// NewDashboardQueryGroupSpec creates a new DashboardQueryGroupSpec object. +func NewDashboardQueryGroupSpec() *DashboardQueryGroupSpec { + return &DashboardQueryGroupSpec{ + QueryOptions: *NewDashboardQueryOptionsSpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardPanelQueryKind struct { + Kind string `json:"kind"` + Spec DashboardPanelQuerySpec `json:"spec"` +} + +// NewDashboardPanelQueryKind creates a new DashboardPanelQueryKind object. +func NewDashboardPanelQueryKind() *DashboardPanelQueryKind { + return &DashboardPanelQueryKind{ + Kind: "PanelQuery", + Spec: *NewDashboardPanelQuerySpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardPanelQuerySpec struct { + Query DashboardDataQueryKind `json:"query"` + Datasource *DashboardDataSourceRef `json:"datasource,omitempty"` + RefId string `json:"refId"` + Hidden bool `json:"hidden"` +} + +// NewDashboardPanelQuerySpec creates a new DashboardPanelQuerySpec object. +func NewDashboardPanelQuerySpec() *DashboardPanelQuerySpec { + return &DashboardPanelQuerySpec{ + Query: *NewDashboardDataQueryKind(), + } +} + +// +k8s:openapi-gen=true +type DashboardTransformationKind struct { + // The kind of a TransformationKind is the transformation ID + Kind string `json:"kind"` + Spec DashboardDataTransformerConfig `json:"spec"` +} + +// NewDashboardTransformationKind creates a new DashboardTransformationKind object. +func NewDashboardTransformationKind() *DashboardTransformationKind { + return &DashboardTransformationKind{ + Spec: *NewDashboardDataTransformerConfig(), + } +} + +// Transformations allow to manipulate data returned by a query before the system applies a visualization. +// Using transformations you can: rename fields, join time series data, perform mathematical operations across queries, +// use the output of one transformation as the input to another transformation, etc. +// +k8s:openapi-gen=true +type DashboardDataTransformerConfig struct { + // Unique identifier of transformer + Id string `json:"id"` + // Disabled transformations are skipped + Disabled *bool `json:"disabled,omitempty"` + // Optional frame matcher. When missing it will be applied to all results + Filter *DashboardMatcherConfig `json:"filter,omitempty"` + // Where to pull DataFrames from as input to transformation + Topic *DashboardDataTopic `json:"topic,omitempty"` + // Options to be passed to the transformer + // Valid options depend on the transformer id + Options interface{} `json:"options"` +} + +// NewDashboardDataTransformerConfig creates a new DashboardDataTransformerConfig object. +func NewDashboardDataTransformerConfig() *DashboardDataTransformerConfig { + return &DashboardDataTransformerConfig{} +} + +// Matcher is a predicate configuration. Based on the config a set of field(s) or values is filtered in order to apply override / transformation. +// It comes with in id ( to resolve implementation from registry) and a configuration that’s specific to a particular matcher type. +// +k8s:openapi-gen=true +type DashboardMatcherConfig struct { + // The matcher id. This is used to find the matcher implementation from registry. + Id string `json:"id"` + // The matcher options. This is specific to the matcher implementation. + Options interface{} `json:"options,omitempty"` +} + +// NewDashboardMatcherConfig creates a new DashboardMatcherConfig object. +func NewDashboardMatcherConfig() *DashboardMatcherConfig { + return &DashboardMatcherConfig{ + Id: "", + } +} + +// A topic is attached to DataFrame metadata in query results. +// This specifies where the data should be used. +// +k8s:openapi-gen=true +type DashboardDataTopic string + +const ( + DashboardDataTopicSeries DashboardDataTopic = "series" + DashboardDataTopicAnnotations DashboardDataTopic = "annotations" + DashboardDataTopicAlertStates DashboardDataTopic = "alertStates" +) + +// +k8s:openapi-gen=true +type DashboardQueryOptionsSpec struct { + TimeFrom *string `json:"timeFrom,omitempty"` + MaxDataPoints *int64 `json:"maxDataPoints,omitempty"` + TimeShift *string `json:"timeShift,omitempty"` + QueryCachingTTL *int64 `json:"queryCachingTTL,omitempty"` + Interval *string `json:"interval,omitempty"` + CacheTimeout *string `json:"cacheTimeout,omitempty"` + HideTimeOverride *bool `json:"hideTimeOverride,omitempty"` +} + +// NewDashboardQueryOptionsSpec creates a new DashboardQueryOptionsSpec object. +func NewDashboardQueryOptionsSpec() *DashboardQueryOptionsSpec { + return &DashboardQueryOptionsSpec{} +} + +// +k8s:openapi-gen=true +type DashboardVizConfigKind struct { + // The kind of a VizConfigKind is the plugin ID + Kind string `json:"kind"` + Spec DashboardVizConfigSpec `json:"spec"` +} + +// NewDashboardVizConfigKind creates a new DashboardVizConfigKind object. +func NewDashboardVizConfigKind() *DashboardVizConfigKind { + return &DashboardVizConfigKind{ + Spec: *NewDashboardVizConfigSpec(), + } +} + +// --- Kinds --- +// +k8s:openapi-gen=true +type DashboardVizConfigSpec struct { + PluginVersion string `json:"pluginVersion"` + Options map[string]interface{} `json:"options"` + FieldConfig DashboardFieldConfigSource `json:"fieldConfig"` +} + +// NewDashboardVizConfigSpec creates a new DashboardVizConfigSpec object. +func NewDashboardVizConfigSpec() *DashboardVizConfigSpec { + return &DashboardVizConfigSpec{ + FieldConfig: *NewDashboardFieldConfigSource(), + } +} + +// The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results. +// Each column within this structure is called a field. A field can represent a single time series or table column. +// Field options allow you to change how the data is displayed in your visualizations. +// +k8s:openapi-gen=true +type DashboardFieldConfigSource struct { + // Defaults are the options applied to all fields. + Defaults DashboardFieldConfig `json:"defaults"` + // Overrides are the options applied to specific fields overriding the defaults. + Overrides []DashboardV2alpha1FieldConfigSourceOverrides `json:"overrides"` +} + +// NewDashboardFieldConfigSource creates a new DashboardFieldConfigSource object. +func NewDashboardFieldConfigSource() *DashboardFieldConfigSource { + return &DashboardFieldConfigSource{ + Defaults: *NewDashboardFieldConfig(), + } +} + +// The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results. +// Each column within this structure is called a field. A field can represent a single time series or table column. +// Field options allow you to change how the data is displayed in your visualizations. +// +k8s:openapi-gen=true +type DashboardFieldConfig struct { + // The display value for this field. This supports template variables blank is auto + DisplayName *string `json:"displayName,omitempty"` + // This can be used by data sources that return and explicit naming structure for values and labels + // When this property is configured, this value is used rather than the default naming strategy. + DisplayNameFromDS *string `json:"displayNameFromDS,omitempty"` + // Human readable field metadata + Description *string `json:"description,omitempty"` + // An explicit path to the field in the datasource. When the frame meta includes a path, + // This will default to `${frame.meta.path}/${field.name} + // + // When defined, this value can be used as an identifier within the datasource scope, and + // may be used to update the results + Path *string `json:"path,omitempty"` + // True if data source can write a value to the path. Auth/authz are supported separately + Writeable *bool `json:"writeable,omitempty"` + // True if data source field supports ad-hoc filters + Filterable *bool `json:"filterable,omitempty"` + // Unit a field should use. The unit you select is applied to all fields except time. + // You can use the units ID availables in Grafana or a custom unit. + // Available units in Grafana: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/valueFormats/categories.ts + // As custom unit, you can use the following formats: + // `suffix:` for custom unit that should go after value. + // `prefix:` for custom unit that should go before value. + // `time:` For custom date time formats type for example `time:YYYY-MM-DD`. + // `si:` for custom SI units. For example: `si: mF`. This one is a bit more advanced as you can specify both a unit and the source data scale. So if your source data is represented as milli (thousands of) something prefix the unit with that SI scale character. + // `count:` for a custom count unit. + // `currency:` for custom a currency unit. + Unit *string `json:"unit,omitempty"` + // Specify the number of decimals Grafana includes in the rendered value. + // If you leave this field blank, Grafana automatically truncates the number of decimals based on the value. + // For example 1.1234 will display as 1.12 and 100.456 will display as 100. + // To display all decimals, set the unit to `String`. + Decimals *float64 `json:"decimals,omitempty"` + // The minimum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields. + Min *float64 `json:"min,omitempty"` + // The maximum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields. + Max *float64 `json:"max,omitempty"` + // Convert input values into a display string + Mappings []DashboardValueMapping `json:"mappings,omitempty"` + // Map numeric values to states + Thresholds *DashboardThresholdsConfig `json:"thresholds,omitempty"` + // Panel color configuration + Color *DashboardFieldColor `json:"color,omitempty"` + // The behavior when clicking on a result + Links []interface{} `json:"links,omitempty"` + // Alternative to empty string + NoValue *string `json:"noValue,omitempty"` + // custom is specified by the FieldConfig field + // in panel plugin schemas. + Custom map[string]interface{} `json:"custom,omitempty"` +} + +// NewDashboardFieldConfig creates a new DashboardFieldConfig object. +func NewDashboardFieldConfig() *DashboardFieldConfig { + return &DashboardFieldConfig{} +} + +// +k8s:openapi-gen=true +type DashboardValueMapping = DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap + +// NewDashboardValueMapping creates a new DashboardValueMapping object. +func NewDashboardValueMapping() *DashboardValueMapping { + return NewDashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap() +} + +// Maps text values to a color or different display text and color. +// For example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number. +// +k8s:openapi-gen=true +type DashboardValueMap struct { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "value" + Type string `json:"type"` + // Map with : ValueMappingResult. For example: { "10": { text: "Perfection!", color: "green" } } + Options map[string]DashboardValueMappingResult `json:"options"` +} + +// NewDashboardValueMap creates a new DashboardValueMap object. +func NewDashboardValueMap() *DashboardValueMap { + return &DashboardValueMap{ + Type: "value", + } +} + +// Result used as replacement with text and color when the value matches +// +k8s:openapi-gen=true +type DashboardValueMappingResult struct { + // Text to display when the value matches + Text *string `json:"text,omitempty"` + // Text to use when the value matches + Color *string `json:"color,omitempty"` + // Icon to display when the value matches. Only specific visualizations. + Icon *string `json:"icon,omitempty"` + // Position in the mapping array. Only used internally. + Index *int32 `json:"index,omitempty"` +} + +// NewDashboardValueMappingResult creates a new DashboardValueMappingResult object. +func NewDashboardValueMappingResult() *DashboardValueMappingResult { + return &DashboardValueMappingResult{} +} + +// Maps numerical ranges to a display text and color. +// For example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number. +// +k8s:openapi-gen=true +type DashboardRangeMap struct { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "range" + Type string `json:"type"` + // Range to match against and the result to apply when the value is within the range + Options DashboardV2alpha1RangeMapOptions `json:"options"` +} + +// NewDashboardRangeMap creates a new DashboardRangeMap object. +func NewDashboardRangeMap() *DashboardRangeMap { + return &DashboardRangeMap{ + Type: "range", + Options: *NewDashboardV2alpha1RangeMapOptions(), + } +} + +// Maps regular expressions to replacement text and a color. +// For example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain. +// +k8s:openapi-gen=true +type DashboardRegexMap struct { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "regex" + Type string `json:"type"` + // Regular expression to match against and the result to apply when the value matches the regex + Options DashboardV2alpha1RegexMapOptions `json:"options"` +} + +// NewDashboardRegexMap creates a new DashboardRegexMap object. +func NewDashboardRegexMap() *DashboardRegexMap { + return &DashboardRegexMap{ + Type: "regex", + Options: *NewDashboardV2alpha1RegexMapOptions(), + } +} + +// Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color. +// See SpecialValueMatch to see the list of special values. +// For example, you can configure a special value mapping so that null values appear as N/A. +// +k8s:openapi-gen=true +type DashboardSpecialValueMap struct { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "special" + Type string `json:"type"` + Options DashboardV2alpha1SpecialValueMapOptions `json:"options"` +} + +// NewDashboardSpecialValueMap creates a new DashboardSpecialValueMap object. +func NewDashboardSpecialValueMap() *DashboardSpecialValueMap { + return &DashboardSpecialValueMap{ + Type: "special", + Options: *NewDashboardV2alpha1SpecialValueMapOptions(), + } +} + +// Special value types supported by the `SpecialValueMap` +// +k8s:openapi-gen=true +type DashboardSpecialValueMatch string + +const ( + DashboardSpecialValueMatchTrue DashboardSpecialValueMatch = "true" + DashboardSpecialValueMatchFalse DashboardSpecialValueMatch = "false" + DashboardSpecialValueMatchNull DashboardSpecialValueMatch = "null" + DashboardSpecialValueMatchNaN DashboardSpecialValueMatch = "nan" + DashboardSpecialValueMatchNullAndNaN DashboardSpecialValueMatch = "null+nan" + DashboardSpecialValueMatchEmpty DashboardSpecialValueMatch = "empty" +) + +// +k8s:openapi-gen=true +type DashboardThresholdsConfig struct { + Mode DashboardThresholdsMode `json:"mode"` + Steps []DashboardThreshold `json:"steps"` +} + +// NewDashboardThresholdsConfig creates a new DashboardThresholdsConfig object. +func NewDashboardThresholdsConfig() *DashboardThresholdsConfig { + return &DashboardThresholdsConfig{} +} + +// +k8s:openapi-gen=true +type DashboardThresholdsMode string + +const ( + DashboardThresholdsModeAbsolute DashboardThresholdsMode = "absolute" + DashboardThresholdsModePercentage DashboardThresholdsMode = "percentage" +) + +// +k8s:openapi-gen=true +type DashboardThreshold struct { + Value float64 `json:"value"` + Color string `json:"color"` +} + +// NewDashboardThreshold creates a new DashboardThreshold object. +func NewDashboardThreshold() *DashboardThreshold { + return &DashboardThreshold{} +} + +// Map a field to a color. +// +k8s:openapi-gen=true +type DashboardFieldColor struct { + // The main color scheme mode. + Mode DashboardFieldColorModeId `json:"mode"` + // The fixed color value for fixed or shades color modes. + FixedColor *string `json:"fixedColor,omitempty"` + // Some visualizations need to know how to assign a series color from by value color schemes. + SeriesBy *DashboardFieldColorSeriesByMode `json:"seriesBy,omitempty"` +} + +// NewDashboardFieldColor creates a new DashboardFieldColor object. +func NewDashboardFieldColor() *DashboardFieldColor { + return &DashboardFieldColor{} +} + +// Color mode for a field. You can specify a single color, or select a continuous (gradient) color schemes, based on a value. +// Continuous color interpolates a color using the percentage of a value relative to min and max. +// Accepted values are: +// `thresholds`: From thresholds. Informs Grafana to take the color from the matching threshold +// `palette-classic`: Classic palette. Grafana will assign color by looking up a color in a palette by series index. Useful for Graphs and pie charts and other categorical data visualizations +// `palette-classic-by-name`: Classic palette (by name). Grafana will assign color by looking up a color in a palette by series name. Useful for Graphs and pie charts and other categorical data visualizations +// `continuous-GrYlRd`: ontinuous Green-Yellow-Red palette mode +// `continuous-RdYlGr`: Continuous Red-Yellow-Green palette mode +// `continuous-BlYlRd`: Continuous Blue-Yellow-Red palette mode +// `continuous-YlRd`: Continuous Yellow-Red palette mode +// `continuous-BlPu`: Continuous Blue-Purple palette mode +// `continuous-YlBl`: Continuous Yellow-Blue palette mode +// `continuous-blues`: Continuous Blue palette mode +// `continuous-reds`: Continuous Red palette mode +// `continuous-greens`: Continuous Green palette mode +// `continuous-purples`: Continuous Purple palette mode +// `shades`: Shades of a single color. Specify a single color, useful in an override rule. +// `fixed`: Fixed color mode. Specify a single color, useful in an override rule. +// +k8s:openapi-gen=true +type DashboardFieldColorModeId string + +const ( + DashboardFieldColorModeIdThresholds DashboardFieldColorModeId = "thresholds" + DashboardFieldColorModeIdPaletteClassic DashboardFieldColorModeId = "palette-classic" + DashboardFieldColorModeIdPaletteClassicByName DashboardFieldColorModeId = "palette-classic-by-name" + DashboardFieldColorModeIdContinuousGrYlRd DashboardFieldColorModeId = "continuous-GrYlRd" + DashboardFieldColorModeIdContinuousRdYlGr DashboardFieldColorModeId = "continuous-RdYlGr" + DashboardFieldColorModeIdContinuousBlYlRd DashboardFieldColorModeId = "continuous-BlYlRd" + DashboardFieldColorModeIdContinuousYlRd DashboardFieldColorModeId = "continuous-YlRd" + DashboardFieldColorModeIdContinuousBlPu DashboardFieldColorModeId = "continuous-BlPu" + DashboardFieldColorModeIdContinuousYlBl DashboardFieldColorModeId = "continuous-YlBl" + DashboardFieldColorModeIdContinuousBlues DashboardFieldColorModeId = "continuous-blues" + DashboardFieldColorModeIdContinuousReds DashboardFieldColorModeId = "continuous-reds" + DashboardFieldColorModeIdContinuousGreens DashboardFieldColorModeId = "continuous-greens" + DashboardFieldColorModeIdContinuousPurples DashboardFieldColorModeId = "continuous-purples" + DashboardFieldColorModeIdFixed DashboardFieldColorModeId = "fixed" + DashboardFieldColorModeIdShades DashboardFieldColorModeId = "shades" +) + +// Defines how to assign a series color from "by value" color schemes. For example for an aggregated data points like a timeseries, the color can be assigned by the min, max or last value. +// +k8s:openapi-gen=true +type DashboardFieldColorSeriesByMode string + +const ( + DashboardFieldColorSeriesByModeMin DashboardFieldColorSeriesByMode = "min" + DashboardFieldColorSeriesByModeMax DashboardFieldColorSeriesByMode = "max" + DashboardFieldColorSeriesByModeLast DashboardFieldColorSeriesByMode = "last" +) + +// +k8s:openapi-gen=true +type DashboardDynamicConfigValue struct { + Id string `json:"id"` + Value interface{} `json:"value,omitempty"` +} + +// NewDashboardDynamicConfigValue creates a new DashboardDynamicConfigValue object. +func NewDashboardDynamicConfigValue() *DashboardDynamicConfigValue { + return &DashboardDynamicConfigValue{ + Id: "", + } +} + +// +k8s:openapi-gen=true +type DashboardLibraryPanelKind struct { + Kind string `json:"kind"` + Spec DashboardLibraryPanelKindSpec `json:"spec"` +} + +// NewDashboardLibraryPanelKind creates a new DashboardLibraryPanelKind object. +func NewDashboardLibraryPanelKind() *DashboardLibraryPanelKind { + return &DashboardLibraryPanelKind{ + Kind: "LibraryPanel", + Spec: *NewDashboardLibraryPanelKindSpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardLibraryPanelKindSpec struct { + // Panel ID for the library panel in the dashboard + Id float64 `json:"id"` + // Title for the library panel in the dashboard + Title string `json:"title"` + LibraryPanel DashboardLibraryPanelRef `json:"libraryPanel"` +} + +// NewDashboardLibraryPanelKindSpec creates a new DashboardLibraryPanelKindSpec object. +func NewDashboardLibraryPanelKindSpec() *DashboardLibraryPanelKindSpec { + return &DashboardLibraryPanelKindSpec{ + LibraryPanel: *NewDashboardLibraryPanelRef(), + } +} + +// A library panel is a reusable panel that you can use in any dashboard. +// When you make a change to a library panel, that change propagates to all instances of where the panel is used. +// Library panels streamline reuse of panels across multiple dashboards. +// +k8s:openapi-gen=true +type DashboardLibraryPanelRef struct { + // Library panel name + Name string `json:"name"` + // Library panel uid + Uid string `json:"uid"` +} + +// NewDashboardLibraryPanelRef creates a new DashboardLibraryPanelRef object. +func NewDashboardLibraryPanelRef() *DashboardLibraryPanelRef { + return &DashboardLibraryPanelRef{} +} + +// +k8s:openapi-gen=true +type DashboardGridLayoutKind struct { + Kind string `json:"kind"` + Spec DashboardGridLayoutSpec `json:"spec"` +} + +// NewDashboardGridLayoutKind creates a new DashboardGridLayoutKind object. +func NewDashboardGridLayoutKind() *DashboardGridLayoutKind { + return &DashboardGridLayoutKind{ + Kind: "GridLayout", + Spec: *NewDashboardGridLayoutSpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardGridLayoutSpec struct { + Items []DashboardGridLayoutItemKindOrGridLayoutRowKind `json:"items"` +} + +// NewDashboardGridLayoutSpec creates a new DashboardGridLayoutSpec object. +func NewDashboardGridLayoutSpec() *DashboardGridLayoutSpec { + return &DashboardGridLayoutSpec{} +} + +// +k8s:openapi-gen=true +type DashboardGridLayoutItemKind struct { + Kind string `json:"kind"` + Spec DashboardGridLayoutItemSpec `json:"spec"` +} + +// NewDashboardGridLayoutItemKind creates a new DashboardGridLayoutItemKind object. +func NewDashboardGridLayoutItemKind() *DashboardGridLayoutItemKind { + return &DashboardGridLayoutItemKind{ + Kind: "GridLayoutItem", + Spec: *NewDashboardGridLayoutItemSpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardGridLayoutItemSpec struct { + X int64 `json:"x"` + Y int64 `json:"y"` + Width int64 `json:"width"` + Height int64 `json:"height"` + // reference to a PanelKind from dashboard.spec.elements Expressed as JSON Schema reference + Element DashboardElementReference `json:"element"` + Repeat *DashboardRepeatOptions `json:"repeat,omitempty"` +} + +// NewDashboardGridLayoutItemSpec creates a new DashboardGridLayoutItemSpec object. +func NewDashboardGridLayoutItemSpec() *DashboardGridLayoutItemSpec { + return &DashboardGridLayoutItemSpec{ + Element: *NewDashboardElementReference(), + } +} + +// +k8s:openapi-gen=true +type DashboardElementReference struct { + Kind string `json:"kind"` + Name string `json:"name"` +} + +// NewDashboardElementReference creates a new DashboardElementReference object. +func NewDashboardElementReference() *DashboardElementReference { + return &DashboardElementReference{ + Kind: "ElementReference", + } +} + +// +k8s:openapi-gen=true +type DashboardRepeatOptions struct { + Mode string `json:"mode"` + Value string `json:"value"` + Direction *DashboardRepeatOptionsDirection `json:"direction,omitempty"` + MaxPerRow *int64 `json:"maxPerRow,omitempty"` +} + +// NewDashboardRepeatOptions creates a new DashboardRepeatOptions object. +func NewDashboardRepeatOptions() *DashboardRepeatOptions { + return &DashboardRepeatOptions{} +} + +// other repeat modes will be added in the future: label, frame +// +k8s:openapi-gen=true +const DashboardRepeatMode = "variable" + +// +k8s:openapi-gen=true +type DashboardGridLayoutRowKind struct { + Kind string `json:"kind"` + Spec DashboardGridLayoutRowSpec `json:"spec"` +} + +// NewDashboardGridLayoutRowKind creates a new DashboardGridLayoutRowKind object. +func NewDashboardGridLayoutRowKind() *DashboardGridLayoutRowKind { + return &DashboardGridLayoutRowKind{ + Kind: "GridLayoutRow", + Spec: *NewDashboardGridLayoutRowSpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardGridLayoutRowSpec struct { + Y int64 `json:"y"` + Collapsed bool `json:"collapsed"` + Title string `json:"title"` + // Grid items in the row will have their Y value be relative to the rows Y value. This means a panel positioned at Y: 0 in a row with Y: 10 will be positioned at Y: 11 (row header has a heigh of 1) in the dashboard. + Elements []DashboardGridLayoutItemKind `json:"elements"` + Repeat *DashboardRowRepeatOptions `json:"repeat,omitempty"` +} + +// NewDashboardGridLayoutRowSpec creates a new DashboardGridLayoutRowSpec object. +func NewDashboardGridLayoutRowSpec() *DashboardGridLayoutRowSpec { + return &DashboardGridLayoutRowSpec{} +} + +// +k8s:openapi-gen=true +type DashboardRowRepeatOptions struct { + Mode string `json:"mode"` + Value string `json:"value"` +} + +// NewDashboardRowRepeatOptions creates a new DashboardRowRepeatOptions object. +func NewDashboardRowRepeatOptions() *DashboardRowRepeatOptions { + return &DashboardRowRepeatOptions{} +} + +// +k8s:openapi-gen=true +type DashboardRowsLayoutKind struct { + Kind string `json:"kind"` + Spec DashboardRowsLayoutSpec `json:"spec"` +} + +// NewDashboardRowsLayoutKind creates a new DashboardRowsLayoutKind object. +func NewDashboardRowsLayoutKind() *DashboardRowsLayoutKind { + return &DashboardRowsLayoutKind{ + Kind: "RowsLayout", + Spec: *NewDashboardRowsLayoutSpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardRowsLayoutSpec struct { + Rows []DashboardRowsLayoutRowKind `json:"rows"` +} + +// NewDashboardRowsLayoutSpec creates a new DashboardRowsLayoutSpec object. +func NewDashboardRowsLayoutSpec() *DashboardRowsLayoutSpec { + return &DashboardRowsLayoutSpec{} +} + +// +k8s:openapi-gen=true +type DashboardRowsLayoutRowKind struct { + Kind string `json:"kind"` + Spec DashboardRowsLayoutRowSpec `json:"spec"` +} + +// NewDashboardRowsLayoutRowKind creates a new DashboardRowsLayoutRowKind object. +func NewDashboardRowsLayoutRowKind() *DashboardRowsLayoutRowKind { + return &DashboardRowsLayoutRowKind{ + Kind: "RowsLayoutRow", + Spec: *NewDashboardRowsLayoutRowSpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardRowsLayoutRowSpec struct { + Title *string `json:"title,omitempty"` + Collapsed bool `json:"collapsed"` + Repeat *DashboardRowRepeatOptions `json:"repeat,omitempty"` + Layout DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind `json:"layout"` +} + +// NewDashboardRowsLayoutRowSpec creates a new DashboardRowsLayoutRowSpec object. +func NewDashboardRowsLayoutRowSpec() *DashboardRowsLayoutRowSpec { + return &DashboardRowsLayoutRowSpec{ + Layout: *NewDashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind(), + } +} + +// +k8s:openapi-gen=true +type DashboardResponsiveGridLayoutKind struct { + Kind string `json:"kind"` + Spec DashboardResponsiveGridLayoutSpec `json:"spec"` +} + +// NewDashboardResponsiveGridLayoutKind creates a new DashboardResponsiveGridLayoutKind object. +func NewDashboardResponsiveGridLayoutKind() *DashboardResponsiveGridLayoutKind { + return &DashboardResponsiveGridLayoutKind{ + Kind: "ResponsiveGridLayout", + Spec: *NewDashboardResponsiveGridLayoutSpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardResponsiveGridLayoutSpec struct { + Row string `json:"row"` + Col string `json:"col"` + Items []DashboardResponsiveGridLayoutItemKind `json:"items"` +} + +// NewDashboardResponsiveGridLayoutSpec creates a new DashboardResponsiveGridLayoutSpec object. +func NewDashboardResponsiveGridLayoutSpec() *DashboardResponsiveGridLayoutSpec { + return &DashboardResponsiveGridLayoutSpec{} +} + +// +k8s:openapi-gen=true +type DashboardResponsiveGridLayoutItemKind struct { + Kind string `json:"kind"` + Spec DashboardResponsiveGridLayoutItemSpec `json:"spec"` +} + +// NewDashboardResponsiveGridLayoutItemKind creates a new DashboardResponsiveGridLayoutItemKind object. +func NewDashboardResponsiveGridLayoutItemKind() *DashboardResponsiveGridLayoutItemKind { + return &DashboardResponsiveGridLayoutItemKind{ + Kind: "ResponsiveGridLayoutItem", + Spec: *NewDashboardResponsiveGridLayoutItemSpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardResponsiveGridLayoutItemSpec struct { + Element DashboardElementReference `json:"element"` + Repeat *DashboardResponsiveGridRepeatOptions `json:"repeat,omitempty"` +} + +// NewDashboardResponsiveGridLayoutItemSpec creates a new DashboardResponsiveGridLayoutItemSpec object. +func NewDashboardResponsiveGridLayoutItemSpec() *DashboardResponsiveGridLayoutItemSpec { + return &DashboardResponsiveGridLayoutItemSpec{ + Element: *NewDashboardElementReference(), + } +} + +// +k8s:openapi-gen=true +type DashboardResponsiveGridRepeatOptions struct { + Mode string `json:"mode"` + Value string `json:"value"` +} + +// NewDashboardResponsiveGridRepeatOptions creates a new DashboardResponsiveGridRepeatOptions object. +func NewDashboardResponsiveGridRepeatOptions() *DashboardResponsiveGridRepeatOptions { + return &DashboardResponsiveGridRepeatOptions{} +} + +// +k8s:openapi-gen=true +type DashboardTabsLayoutKind struct { + Kind string `json:"kind"` + Spec DashboardTabsLayoutSpec `json:"spec"` +} + +// NewDashboardTabsLayoutKind creates a new DashboardTabsLayoutKind object. +func NewDashboardTabsLayoutKind() *DashboardTabsLayoutKind { + return &DashboardTabsLayoutKind{ + Kind: "TabsLayout", + Spec: *NewDashboardTabsLayoutSpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardTabsLayoutSpec struct { + Tabs []DashboardTabsLayoutTabKind `json:"tabs"` +} + +// NewDashboardTabsLayoutSpec creates a new DashboardTabsLayoutSpec object. +func NewDashboardTabsLayoutSpec() *DashboardTabsLayoutSpec { + return &DashboardTabsLayoutSpec{} +} + +// +k8s:openapi-gen=true +type DashboardTabsLayoutTabKind struct { + Kind string `json:"kind"` + Spec DashboardTabsLayoutTabSpec `json:"spec"` +} + +// NewDashboardTabsLayoutTabKind creates a new DashboardTabsLayoutTabKind object. +func NewDashboardTabsLayoutTabKind() *DashboardTabsLayoutTabKind { + return &DashboardTabsLayoutTabKind{ + Kind: "TabsLayoutTab", + Spec: *NewDashboardTabsLayoutTabSpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardTabsLayoutTabSpec struct { + Title *string `json:"title,omitempty"` + Layout DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind `json:"layout"` +} + +// NewDashboardTabsLayoutTabSpec creates a new DashboardTabsLayoutTabSpec object. +func NewDashboardTabsLayoutTabSpec() *DashboardTabsLayoutTabSpec { + return &DashboardTabsLayoutTabSpec{ + Layout: *NewDashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind(), + } +} + +// Links with references to other dashboards or external resources +// +k8s:openapi-gen=true +type DashboardDashboardLink struct { + // Title to display with the link + Title string `json:"title"` + // Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource) + // FIXME: The type is generated as `type: DashboardLinkType | dashboardLinkType.Link;` but it should be `type: DashboardLinkType` + Type DashboardDashboardLinkType `json:"type"` + // Icon name to be displayed with the link + Icon string `json:"icon"` + // Tooltip to display when the user hovers their mouse over it + Tooltip string `json:"tooltip"` + // Link URL. Only required/valid if the type is link + Url *string `json:"url,omitempty"` + // List of tags to limit the linked dashboards. If empty, all dashboards will be displayed. Only valid if the type is dashboards + Tags []string `json:"tags"` + // If true, all dashboards links will be displayed in a dropdown. If false, all dashboards links will be displayed side by side. Only valid if the type is dashboards + AsDropdown bool `json:"asDropdown"` + // If true, the link will be opened in a new tab + TargetBlank bool `json:"targetBlank"` + // If true, includes current template variables values in the link as query params + IncludeVars bool `json:"includeVars"` + // If true, includes current time range in the link as query params + KeepTime bool `json:"keepTime"` +} + +// NewDashboardDashboardLink creates a new DashboardDashboardLink object. +func NewDashboardDashboardLink() *DashboardDashboardLink { + return &DashboardDashboardLink{ + AsDropdown: false, + TargetBlank: false, + IncludeVars: false, + KeepTime: false, + } +} + +// Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource) +// +k8s:openapi-gen=true +type DashboardDashboardLinkType string + +const ( + DashboardDashboardLinkTypeLink DashboardDashboardLinkType = "link" + DashboardDashboardLinkTypeDashboards DashboardDashboardLinkType = "dashboards" +) + +// Time configuration +// It defines the default time config for the time picker, the refresh picker for the specific dashboard. +// +k8s:openapi-gen=true +type DashboardTimeSettingsSpec struct { + // Timezone of dashboard. Accepted values are IANA TZDB zone ID or "browser" or "utc". + Timezone *string `json:"timezone,omitempty"` + // Start time range for dashboard. + // Accepted values are relative time strings like "now-6h" or absolute time strings like "2020-07-10T08:00:00.000Z". + From string `json:"from"` + // End time range for dashboard. + // Accepted values are relative time strings like "now-6h" or absolute time strings like "2020-07-10T08:00:00.000Z". + To string `json:"to"` + // Refresh rate of dashboard. Represented via interval string, e.g. "5s", "1m", "1h", "1d". + // v1: refresh + AutoRefresh string `json:"autoRefresh"` + // Interval options available in the refresh picker dropdown. + // v1: timepicker.refresh_intervals + AutoRefreshIntervals []string `json:"autoRefreshIntervals"` + // Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard. + // v1: timepicker.quick_ranges , not exposed in the UI + QuickRanges []DashboardTimeRangeOption `json:"quickRanges,omitempty"` + // Whether timepicker is visible or not. + // v1: timepicker.hidden + HideTimepicker bool `json:"hideTimepicker"` + // Day when the week starts. Expressed by the name of the day in lowercase, e.g. "monday". + WeekStart *DashboardTimeSettingsSpecWeekStart `json:"weekStart,omitempty"` + // The month that the fiscal year starts on. 0 = January, 11 = December + FiscalYearStartMonth int64 `json:"fiscalYearStartMonth"` + // Override the now time by entering a time delay. Use this option to accommodate known delays in data aggregation to avoid null values. + // v1: timepicker.nowDelay + NowDelay *string `json:"nowDelay,omitempty"` +} + +// NewDashboardTimeSettingsSpec creates a new DashboardTimeSettingsSpec object. +func NewDashboardTimeSettingsSpec() *DashboardTimeSettingsSpec { + return &DashboardTimeSettingsSpec{ + Timezone: (func(input string) *string { return &input })("browser"), + From: "now-6h", + To: "now", + AutoRefreshIntervals: []string{"5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"}, + } +} + +// +k8s:openapi-gen=true +type DashboardTimeRangeOption struct { + Display string `json:"display"` + From string `json:"from"` + To string `json:"to"` +} + +// NewDashboardTimeRangeOption creates a new DashboardTimeRangeOption object. +func NewDashboardTimeRangeOption() *DashboardTimeRangeOption { + return &DashboardTimeRangeOption{ + Display: "Last 6 hours", + From: "now-6h", + To: "now", + } +} + +// +k8s:openapi-gen=true +type DashboardVariableKind = DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind + +// NewDashboardVariableKind creates a new DashboardVariableKind object. +func NewDashboardVariableKind() *DashboardVariableKind { + return NewDashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind() +} + +// Query variable kind +// +k8s:openapi-gen=true +type DashboardQueryVariableKind struct { + Kind string `json:"kind"` + Spec DashboardQueryVariableSpec `json:"spec"` +} + +// NewDashboardQueryVariableKind creates a new DashboardQueryVariableKind object. +func NewDashboardQueryVariableKind() *DashboardQueryVariableKind { + return &DashboardQueryVariableKind{ + Kind: "QueryVariable", + Spec: *NewDashboardQueryVariableSpec(), + } +} + +// Query variable specification +// +k8s:openapi-gen=true +type DashboardQueryVariableSpec struct { + Name string `json:"name"` + Current DashboardVariableOption `json:"current"` + Label *string `json:"label,omitempty"` + Hide DashboardVariableHide `json:"hide"` + Refresh DashboardVariableRefresh `json:"refresh"` + SkipUrlSync bool `json:"skipUrlSync"` + Description *string `json:"description,omitempty"` + Datasource *DashboardDataSourceRef `json:"datasource,omitempty"` + Query DashboardDataQueryKind `json:"query"` + Regex string `json:"regex"` + Sort DashboardVariableSort `json:"sort"` + Definition *string `json:"definition,omitempty"` + Options []DashboardVariableOption `json:"options"` + Multi bool `json:"multi"` + IncludeAll bool `json:"includeAll"` + AllValue *string `json:"allValue,omitempty"` + Placeholder *string `json:"placeholder,omitempty"` +} + +// NewDashboardQueryVariableSpec creates a new DashboardQueryVariableSpec object. +func NewDashboardQueryVariableSpec() *DashboardQueryVariableSpec { + return &DashboardQueryVariableSpec{ + Name: "", + Current: DashboardVariableOption{ + Text: DashboardStringOrArrayOfString{ + String: (func(input string) *string { return &input })(""), + }, + Value: DashboardStringOrArrayOfString{ + String: (func(input string) *string { return &input })(""), + }, + }, + Hide: DashboardVariableHideDontHide, + Refresh: DashboardVariableRefreshNever, + SkipUrlSync: false, + Query: *NewDashboardDataQueryKind(), + Regex: "", + Multi: false, + IncludeAll: false, + } +} + +// Variable option specification +// +k8s:openapi-gen=true +type DashboardVariableOption struct { + // Whether the option is selected or not + Selected *bool `json:"selected,omitempty"` + // Text to be displayed for the option + Text DashboardStringOrArrayOfString `json:"text"` + // Value of the option + Value DashboardStringOrArrayOfString `json:"value"` +} + +// NewDashboardVariableOption creates a new DashboardVariableOption object. +func NewDashboardVariableOption() *DashboardVariableOption { + return &DashboardVariableOption{ + Text: *NewDashboardStringOrArrayOfString(), + Value: *NewDashboardStringOrArrayOfString(), + } +} + +// Determine if the variable shows on dashboard +// Accepted values are `dontHide` (show label and value), `hideLabel` (show value only), `hideVariable` (show nothing). +// +k8s:openapi-gen=true +type DashboardVariableHide string + +const ( + DashboardVariableHideDontHide DashboardVariableHide = "dontHide" + DashboardVariableHideHideLabel DashboardVariableHide = "hideLabel" + DashboardVariableHideHideVariable DashboardVariableHide = "hideVariable" +) + +// Options to config when to refresh a variable +// `never`: Never refresh the variable +// `onDashboardLoad`: Queries the data source every time the dashboard loads. +// `onTimeRangeChanged`: Queries the data source when the dashboard time range changes. +// +k8s:openapi-gen=true +type DashboardVariableRefresh string + +const ( + DashboardVariableRefreshNever DashboardVariableRefresh = "never" + DashboardVariableRefreshOnDashboardLoad DashboardVariableRefresh = "onDashboardLoad" + DashboardVariableRefreshOnTimeRangeChanged DashboardVariableRefresh = "onTimeRangeChanged" +) + +// Sort variable options +// Accepted values are: +// `disabled`: No sorting +// `alphabeticalAsc`: Alphabetical ASC +// `alphabeticalDesc`: Alphabetical DESC +// `numericalAsc`: Numerical ASC +// `numericalDesc`: Numerical DESC +// `alphabeticalCaseInsensitiveAsc`: Alphabetical Case Insensitive ASC +// `alphabeticalCaseInsensitiveDesc`: Alphabetical Case Insensitive DESC +// `naturalAsc`: Natural ASC +// `naturalDesc`: Natural DESC +// VariableSort enum with default value +// +k8s:openapi-gen=true +type DashboardVariableSort string + +const ( + DashboardVariableSortDisabled DashboardVariableSort = "disabled" + DashboardVariableSortAlphabeticalAsc DashboardVariableSort = "alphabeticalAsc" + DashboardVariableSortAlphabeticalDesc DashboardVariableSort = "alphabeticalDesc" + DashboardVariableSortNumericalAsc DashboardVariableSort = "numericalAsc" + DashboardVariableSortNumericalDesc DashboardVariableSort = "numericalDesc" + DashboardVariableSortAlphabeticalCaseInsensitiveAsc DashboardVariableSort = "alphabeticalCaseInsensitiveAsc" + DashboardVariableSortAlphabeticalCaseInsensitiveDesc DashboardVariableSort = "alphabeticalCaseInsensitiveDesc" + DashboardVariableSortNaturalAsc DashboardVariableSort = "naturalAsc" + DashboardVariableSortNaturalDesc DashboardVariableSort = "naturalDesc" +) + +// Text variable kind +// +k8s:openapi-gen=true +type DashboardTextVariableKind struct { + Kind string `json:"kind"` + Spec DashboardTextVariableSpec `json:"spec"` +} + +// NewDashboardTextVariableKind creates a new DashboardTextVariableKind object. +func NewDashboardTextVariableKind() *DashboardTextVariableKind { + return &DashboardTextVariableKind{ + Kind: "TextVariable", + Spec: *NewDashboardTextVariableSpec(), + } +} + +// Text variable specification +// +k8s:openapi-gen=true +type DashboardTextVariableSpec struct { + Name string `json:"name"` + Current DashboardVariableOption `json:"current"` + Query string `json:"query"` + Label *string `json:"label,omitempty"` + Hide DashboardVariableHide `json:"hide"` + SkipUrlSync bool `json:"skipUrlSync"` + Description *string `json:"description,omitempty"` +} + +// NewDashboardTextVariableSpec creates a new DashboardTextVariableSpec object. +func NewDashboardTextVariableSpec() *DashboardTextVariableSpec { + return &DashboardTextVariableSpec{ + Name: "", + Current: DashboardVariableOption{ + Text: DashboardStringOrArrayOfString{ + String: (func(input string) *string { return &input })(""), + }, + Value: DashboardStringOrArrayOfString{ + String: (func(input string) *string { return &input })(""), + }, + }, + Query: "", + Hide: DashboardVariableHideDontHide, + SkipUrlSync: false, + } +} + +// Constant variable kind +// +k8s:openapi-gen=true +type DashboardConstantVariableKind struct { + Kind string `json:"kind"` + Spec DashboardConstantVariableSpec `json:"spec"` +} + +// NewDashboardConstantVariableKind creates a new DashboardConstantVariableKind object. +func NewDashboardConstantVariableKind() *DashboardConstantVariableKind { + return &DashboardConstantVariableKind{ + Kind: "ConstantVariable", + Spec: *NewDashboardConstantVariableSpec(), + } +} + +// Constant variable specification +// +k8s:openapi-gen=true +type DashboardConstantVariableSpec struct { + Name string `json:"name"` + Query string `json:"query"` + Current DashboardVariableOption `json:"current"` + Label *string `json:"label,omitempty"` + Hide DashboardVariableHide `json:"hide"` + SkipUrlSync bool `json:"skipUrlSync"` + Description *string `json:"description,omitempty"` +} + +// NewDashboardConstantVariableSpec creates a new DashboardConstantVariableSpec object. +func NewDashboardConstantVariableSpec() *DashboardConstantVariableSpec { + return &DashboardConstantVariableSpec{ + Name: "", + Query: "", + Current: DashboardVariableOption{ + Text: DashboardStringOrArrayOfString{ + String: (func(input string) *string { return &input })(""), + }, + Value: DashboardStringOrArrayOfString{ + String: (func(input string) *string { return &input })(""), + }, + }, + Hide: DashboardVariableHideDontHide, + SkipUrlSync: false, + } +} + +// Datasource variable kind +// +k8s:openapi-gen=true +type DashboardDatasourceVariableKind struct { + Kind string `json:"kind"` + Spec DashboardDatasourceVariableSpec `json:"spec"` +} + +// NewDashboardDatasourceVariableKind creates a new DashboardDatasourceVariableKind object. +func NewDashboardDatasourceVariableKind() *DashboardDatasourceVariableKind { + return &DashboardDatasourceVariableKind{ + Kind: "DatasourceVariable", + Spec: *NewDashboardDatasourceVariableSpec(), + } +} + +// Datasource variable specification +// +k8s:openapi-gen=true +type DashboardDatasourceVariableSpec struct { + Name string `json:"name"` + PluginId string `json:"pluginId"` + Refresh DashboardVariableRefresh `json:"refresh"` + Regex string `json:"regex"` + Current DashboardVariableOption `json:"current"` + Options []DashboardVariableOption `json:"options"` + Multi bool `json:"multi"` + IncludeAll bool `json:"includeAll"` + AllValue *string `json:"allValue,omitempty"` + Label *string `json:"label,omitempty"` + Hide DashboardVariableHide `json:"hide"` + SkipUrlSync bool `json:"skipUrlSync"` + Description *string `json:"description,omitempty"` +} + +// NewDashboardDatasourceVariableSpec creates a new DashboardDatasourceVariableSpec object. +func NewDashboardDatasourceVariableSpec() *DashboardDatasourceVariableSpec { + return &DashboardDatasourceVariableSpec{ + Name: "", + PluginId: "", + Refresh: DashboardVariableRefreshNever, + Regex: "", + Current: DashboardVariableOption{ + Text: DashboardStringOrArrayOfString{ + String: (func(input string) *string { return &input })(""), + }, + Value: DashboardStringOrArrayOfString{ + String: (func(input string) *string { return &input })(""), + }, + }, + Multi: false, + IncludeAll: false, + Hide: DashboardVariableHideDontHide, + SkipUrlSync: false, + } +} + +// Interval variable kind +// +k8s:openapi-gen=true +type DashboardIntervalVariableKind struct { + Kind string `json:"kind"` + Spec DashboardIntervalVariableSpec `json:"spec"` +} + +// NewDashboardIntervalVariableKind creates a new DashboardIntervalVariableKind object. +func NewDashboardIntervalVariableKind() *DashboardIntervalVariableKind { + return &DashboardIntervalVariableKind{ + Kind: "IntervalVariable", + Spec: *NewDashboardIntervalVariableSpec(), + } +} + +// Interval variable specification +// +k8s:openapi-gen=true +type DashboardIntervalVariableSpec struct { + Name string `json:"name"` + Query string `json:"query"` + Current DashboardVariableOption `json:"current"` + Options []DashboardVariableOption `json:"options"` + Auto bool `json:"auto"` + AutoMin string `json:"auto_min"` + AutoCount int64 `json:"auto_count"` + Refresh DashboardVariableRefresh `json:"refresh"` + Label *string `json:"label,omitempty"` + Hide DashboardVariableHide `json:"hide"` + SkipUrlSync bool `json:"skipUrlSync"` + Description *string `json:"description,omitempty"` +} + +// NewDashboardIntervalVariableSpec creates a new DashboardIntervalVariableSpec object. +func NewDashboardIntervalVariableSpec() *DashboardIntervalVariableSpec { + return &DashboardIntervalVariableSpec{ + Name: "", + Query: "", + Current: DashboardVariableOption{ + Text: DashboardStringOrArrayOfString{ + String: (func(input string) *string { return &input })(""), + }, + Value: DashboardStringOrArrayOfString{ + String: (func(input string) *string { return &input })(""), + }, + }, + Auto: false, + AutoMin: "", + AutoCount: 0, + Refresh: DashboardVariableRefreshNever, + Hide: DashboardVariableHideDontHide, + SkipUrlSync: false, + } +} + +// Custom variable kind +// +k8s:openapi-gen=true +type DashboardCustomVariableKind struct { + Kind string `json:"kind"` + Spec DashboardCustomVariableSpec `json:"spec"` +} + +// NewDashboardCustomVariableKind creates a new DashboardCustomVariableKind object. +func NewDashboardCustomVariableKind() *DashboardCustomVariableKind { + return &DashboardCustomVariableKind{ + Kind: "CustomVariable", + Spec: *NewDashboardCustomVariableSpec(), + } +} + +// Custom variable specification +// +k8s:openapi-gen=true +type DashboardCustomVariableSpec struct { + Name string `json:"name"` + Query string `json:"query"` + Current DashboardVariableOption `json:"current"` + Options []DashboardVariableOption `json:"options"` + Multi bool `json:"multi"` + IncludeAll bool `json:"includeAll"` + AllValue *string `json:"allValue,omitempty"` + Label *string `json:"label,omitempty"` + Hide DashboardVariableHide `json:"hide"` + SkipUrlSync bool `json:"skipUrlSync"` + Description *string `json:"description,omitempty"` +} + +// NewDashboardCustomVariableSpec creates a new DashboardCustomVariableSpec object. +func NewDashboardCustomVariableSpec() *DashboardCustomVariableSpec { + return &DashboardCustomVariableSpec{ + Name: "", + Query: "", + Current: *NewDashboardVariableOption(), + Multi: false, + IncludeAll: false, + Hide: DashboardVariableHideDontHide, + SkipUrlSync: false, + } +} + +// Group variable kind +// +k8s:openapi-gen=true +type DashboardGroupByVariableKind struct { + Kind string `json:"kind"` + Spec DashboardGroupByVariableSpec `json:"spec"` +} + +// NewDashboardGroupByVariableKind creates a new DashboardGroupByVariableKind object. +func NewDashboardGroupByVariableKind() *DashboardGroupByVariableKind { + return &DashboardGroupByVariableKind{ + Kind: "GroupByVariable", + Spec: *NewDashboardGroupByVariableSpec(), + } +} + +// GroupBy variable specification +// +k8s:openapi-gen=true +type DashboardGroupByVariableSpec struct { + Name string `json:"name"` + Datasource *DashboardDataSourceRef `json:"datasource,omitempty"` + Current DashboardVariableOption `json:"current"` + Options []DashboardVariableOption `json:"options"` + Multi bool `json:"multi"` + Label *string `json:"label,omitempty"` + Hide DashboardVariableHide `json:"hide"` + SkipUrlSync bool `json:"skipUrlSync"` + Description *string `json:"description,omitempty"` +} + +// NewDashboardGroupByVariableSpec creates a new DashboardGroupByVariableSpec object. +func NewDashboardGroupByVariableSpec() *DashboardGroupByVariableSpec { + return &DashboardGroupByVariableSpec{ + Name: "", + Current: DashboardVariableOption{ + Text: DashboardStringOrArrayOfString{ + String: (func(input string) *string { return &input })(""), + }, + Value: DashboardStringOrArrayOfString{ + String: (func(input string) *string { return &input })(""), + }, + }, + Multi: false, + Hide: DashboardVariableHideDontHide, + SkipUrlSync: false, + } +} + +// Adhoc variable kind +// +k8s:openapi-gen=true +type DashboardAdhocVariableKind struct { + Kind string `json:"kind"` + Spec DashboardAdhocVariableSpec `json:"spec"` +} + +// NewDashboardAdhocVariableKind creates a new DashboardAdhocVariableKind object. +func NewDashboardAdhocVariableKind() *DashboardAdhocVariableKind { + return &DashboardAdhocVariableKind{ + Kind: "AdhocVariable", + Spec: *NewDashboardAdhocVariableSpec(), + } +} + +// Adhoc variable specification +// +k8s:openapi-gen=true +type DashboardAdhocVariableSpec struct { + Name string `json:"name"` + Datasource *DashboardDataSourceRef `json:"datasource,omitempty"` + BaseFilters []DashboardAdHocFilterWithLabels `json:"baseFilters"` + Filters []DashboardAdHocFilterWithLabels `json:"filters"` + DefaultKeys []DashboardMetricFindValue `json:"defaultKeys"` + Label *string `json:"label,omitempty"` + Hide DashboardVariableHide `json:"hide"` + SkipUrlSync bool `json:"skipUrlSync"` + Description *string `json:"description,omitempty"` +} + +// NewDashboardAdhocVariableSpec creates a new DashboardAdhocVariableSpec object. +func NewDashboardAdhocVariableSpec() *DashboardAdhocVariableSpec { + return &DashboardAdhocVariableSpec{ + Name: "", + Hide: DashboardVariableHideDontHide, + SkipUrlSync: false, + } +} + +// Define the AdHocFilterWithLabels type +// +k8s:openapi-gen=true +type DashboardAdHocFilterWithLabels struct { + Key string `json:"key"` + Operator string `json:"operator"` + Value string `json:"value"` + Values []string `json:"values,omitempty"` + KeyLabel *string `json:"keyLabel,omitempty"` + ValueLabels []string `json:"valueLabels,omitempty"` + ForceEdit *bool `json:"forceEdit,omitempty"` + // @deprecated + Condition *string `json:"condition,omitempty"` +} + +// NewDashboardAdHocFilterWithLabels creates a new DashboardAdHocFilterWithLabels object. +func NewDashboardAdHocFilterWithLabels() *DashboardAdHocFilterWithLabels { + return &DashboardAdHocFilterWithLabels{} +} + +// Define the MetricFindValue type +// +k8s:openapi-gen=true +type DashboardMetricFindValue struct { + Text string `json:"text"` + Value *DashboardStringOrFloat64 `json:"value,omitempty"` + Group *string `json:"group,omitempty"` + Expandable *bool `json:"expandable,omitempty"` +} + +// NewDashboardMetricFindValue creates a new DashboardMetricFindValue object. +func NewDashboardMetricFindValue() *DashboardMetricFindValue { + return &DashboardMetricFindValue{} +} + +// +k8s:openapi-gen=true +type DashboardSpec struct { + // Title of dashboard. + Annotations []DashboardAnnotationQueryKind `json:"annotations"` + // Configuration of dashboard cursor sync behavior. + // "Off" for no shared crosshair or tooltip (default). + // "Crosshair" for shared crosshair. + // "Tooltip" for shared crosshair AND shared tooltip. + CursorSync DashboardDashboardCursorSync `json:"cursorSync"` + // Description of dashboard. + Description *string `json:"description,omitempty"` + // Whether a dashboard is editable or not. + Editable *bool `json:"editable,omitempty"` + Elements map[string]DashboardElement `json:"elements"` + Layout DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind `json:"layout"` + // Links with references to other dashboards or external websites. + Links []DashboardDashboardLink `json:"links"` + // When set to true, the dashboard will redraw panels at an interval matching the pixel width. + // This will keep data "moving left" regardless of the query refresh rate. This setting helps + // avoid dashboards presenting stale live data. + LiveNow *bool `json:"liveNow,omitempty"` + // When set to true, the dashboard will load all panels in the dashboard when it's loaded. + Preload bool `json:"preload"` + // Plugins only. The version of the dashboard installed together with the plugin. + // This is used to determine if the dashboard should be updated when the plugin is updated. + Revision *uint16 `json:"revision,omitempty"` + // Tags associated with dashboard. + Tags []string `json:"tags"` + TimeSettings DashboardTimeSettingsSpec `json:"timeSettings"` + // Title of dashboard. + Title string `json:"title"` + // Configured template variables. + Variables []DashboardVariableKind `json:"variables"` +} + +// NewDashboardSpec creates a new DashboardSpec object. +func NewDashboardSpec() *DashboardSpec { + return &DashboardSpec{ + Editable: (func(input bool) *bool { return &input })(true), + Layout: *NewDashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind(), + TimeSettings: *NewDashboardTimeSettingsSpec(), + } +} + +// +k8s:openapi-gen=true +type DashboardV2alpha1FieldConfigSourceOverrides struct { + Matcher DashboardMatcherConfig `json:"matcher"` + Properties []DashboardDynamicConfigValue `json:"properties"` +} + +// NewDashboardV2alpha1FieldConfigSourceOverrides creates a new DashboardV2alpha1FieldConfigSourceOverrides object. +func NewDashboardV2alpha1FieldConfigSourceOverrides() *DashboardV2alpha1FieldConfigSourceOverrides { + return &DashboardV2alpha1FieldConfigSourceOverrides{ + Matcher: *NewDashboardMatcherConfig(), + } +} + +// +k8s:openapi-gen=true +type DashboardV2alpha1RangeMapOptions struct { + // Min value of the range. It can be null which means -Infinity + From *float64 `json:"from"` + // Max value of the range. It can be null which means +Infinity + To *float64 `json:"to"` + // Config to apply when the value is within the range + Result DashboardValueMappingResult `json:"result"` +} + +// NewDashboardV2alpha1RangeMapOptions creates a new DashboardV2alpha1RangeMapOptions object. +func NewDashboardV2alpha1RangeMapOptions() *DashboardV2alpha1RangeMapOptions { + return &DashboardV2alpha1RangeMapOptions{ + Result: *NewDashboardValueMappingResult(), + } +} + +// +k8s:openapi-gen=true +type DashboardV2alpha1RegexMapOptions struct { + // Regular expression to match against + Pattern string `json:"pattern"` + // Config to apply when the value matches the regex + Result DashboardValueMappingResult `json:"result"` +} + +// NewDashboardV2alpha1RegexMapOptions creates a new DashboardV2alpha1RegexMapOptions object. +func NewDashboardV2alpha1RegexMapOptions() *DashboardV2alpha1RegexMapOptions { + return &DashboardV2alpha1RegexMapOptions{ + Result: *NewDashboardValueMappingResult(), + } +} + +// +k8s:openapi-gen=true +type DashboardV2alpha1SpecialValueMapOptions struct { + // Special value to match against + Match DashboardSpecialValueMatch `json:"match"` + // Config to apply when the value matches the special value + Result DashboardValueMappingResult `json:"result"` +} + +// NewDashboardV2alpha1SpecialValueMapOptions creates a new DashboardV2alpha1SpecialValueMapOptions object. +func NewDashboardV2alpha1SpecialValueMapOptions() *DashboardV2alpha1SpecialValueMapOptions { + return &DashboardV2alpha1SpecialValueMapOptions{ + Result: *NewDashboardValueMappingResult(), + } +} + +// +k8s:openapi-gen=true +type DashboardRepeatOptionsDirection string + +const ( + DashboardRepeatOptionsDirectionH DashboardRepeatOptionsDirection = "h" + DashboardRepeatOptionsDirectionV DashboardRepeatOptionsDirection = "v" +) + +// +k8s:openapi-gen=true +type DashboardTimeSettingsSpecWeekStart string + +const ( + DashboardTimeSettingsSpecWeekStartSaturday DashboardTimeSettingsSpecWeekStart = "saturday" + DashboardTimeSettingsSpecWeekStartMonday DashboardTimeSettingsSpecWeekStart = "monday" + DashboardTimeSettingsSpecWeekStartSunday DashboardTimeSettingsSpecWeekStart = "sunday" +) + +// +k8s:openapi-gen=true +type DashboardPanelKindOrLibraryPanelKind struct { + PanelKind *DashboardPanelKind `json:"PanelKind,omitempty"` + LibraryPanelKind *DashboardLibraryPanelKind `json:"LibraryPanelKind,omitempty"` +} + +// NewDashboardPanelKindOrLibraryPanelKind creates a new DashboardPanelKindOrLibraryPanelKind object. +func NewDashboardPanelKindOrLibraryPanelKind() *DashboardPanelKindOrLibraryPanelKind { + return &DashboardPanelKindOrLibraryPanelKind{} +} + +// MarshalJSON implements a custom JSON marshalling logic to encode `DashboardPanelKindOrLibraryPanelKind` as JSON. +func (resource DashboardPanelKindOrLibraryPanelKind) MarshalJSON() ([]byte, error) { + if resource.PanelKind != nil { + return json.Marshal(resource.PanelKind) + } + if resource.LibraryPanelKind != nil { + return json.Marshal(resource.LibraryPanelKind) + } + + return nil, fmt.Errorf("no value for disjunction of refs") +} + +// UnmarshalJSON implements a custom JSON unmarshalling logic to decode `DashboardPanelKindOrLibraryPanelKind` from JSON. +func (resource *DashboardPanelKindOrLibraryPanelKind) UnmarshalJSON(raw []byte) error { + if raw == nil { + return nil + } + + // FIXME: this is wasteful, we need to find a more efficient way to unmarshal this. + parsedAsMap := make(map[string]interface{}) + if err := json.Unmarshal(raw, &parsedAsMap); err != nil { + return err + } + + discriminator, found := parsedAsMap["kind"] + if !found { + return errors.New("discriminator field 'kind' not found in payload") + } + + switch discriminator { + case "LibraryPanel": + var dashboardLibraryPanelKind DashboardLibraryPanelKind + if err := json.Unmarshal(raw, &dashboardLibraryPanelKind); err != nil { + return err + } + + resource.LibraryPanelKind = &dashboardLibraryPanelKind + return nil + case "Panel": + var dashboardPanelKind DashboardPanelKind + if err := json.Unmarshal(raw, &dashboardPanelKind); err != nil { + return err + } + + resource.PanelKind = &dashboardPanelKind + return nil + } + + return fmt.Errorf("could not unmarshal resource with `kind = %v`", discriminator) +} + +// +k8s:openapi-gen=true +type DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap struct { + ValueMap *DashboardValueMap `json:"ValueMap,omitempty"` + RangeMap *DashboardRangeMap `json:"RangeMap,omitempty"` + RegexMap *DashboardRegexMap `json:"RegexMap,omitempty"` + SpecialValueMap *DashboardSpecialValueMap `json:"SpecialValueMap,omitempty"` +} + +// NewDashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap creates a new DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap object. +func NewDashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap() *DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap { + return &DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap{} +} + +// MarshalJSON implements a custom JSON marshalling logic to encode `DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap` as JSON. +func (resource DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap) MarshalJSON() ([]byte, error) { + if resource.ValueMap != nil { + return json.Marshal(resource.ValueMap) + } + if resource.RangeMap != nil { + return json.Marshal(resource.RangeMap) + } + if resource.RegexMap != nil { + return json.Marshal(resource.RegexMap) + } + if resource.SpecialValueMap != nil { + return json.Marshal(resource.SpecialValueMap) + } + + return nil, fmt.Errorf("no value for disjunction of refs") +} + +// UnmarshalJSON implements a custom JSON unmarshalling logic to decode `DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap` from JSON. +func (resource *DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap) UnmarshalJSON(raw []byte) error { + if raw == nil { + return nil + } + + // FIXME: this is wasteful, we need to find a more efficient way to unmarshal this. + parsedAsMap := make(map[string]interface{}) + if err := json.Unmarshal(raw, &parsedAsMap); err != nil { + return err + } + + discriminator, found := parsedAsMap["type"] + if !found { + return errors.New("discriminator field 'type' not found in payload") + } + + switch discriminator { + case "range": + var dashboardRangeMap DashboardRangeMap + if err := json.Unmarshal(raw, &dashboardRangeMap); err != nil { + return err + } + + resource.RangeMap = &dashboardRangeMap + return nil + case "regex": + var dashboardRegexMap DashboardRegexMap + if err := json.Unmarshal(raw, &dashboardRegexMap); err != nil { + return err + } + + resource.RegexMap = &dashboardRegexMap + return nil + case "special": + var dashboardSpecialValueMap DashboardSpecialValueMap + if err := json.Unmarshal(raw, &dashboardSpecialValueMap); err != nil { + return err + } + + resource.SpecialValueMap = &dashboardSpecialValueMap + return nil + case "value": + var dashboardValueMap DashboardValueMap + if err := json.Unmarshal(raw, &dashboardValueMap); err != nil { + return err + } + + resource.ValueMap = &dashboardValueMap + return nil + } + + return fmt.Errorf("could not unmarshal resource with `type = %v`", discriminator) +} + +// +k8s:openapi-gen=true +type DashboardGridLayoutItemKindOrGridLayoutRowKind struct { + GridLayoutItemKind *DashboardGridLayoutItemKind `json:"GridLayoutItemKind,omitempty"` + GridLayoutRowKind *DashboardGridLayoutRowKind `json:"GridLayoutRowKind,omitempty"` +} + +// NewDashboardGridLayoutItemKindOrGridLayoutRowKind creates a new DashboardGridLayoutItemKindOrGridLayoutRowKind object. +func NewDashboardGridLayoutItemKindOrGridLayoutRowKind() *DashboardGridLayoutItemKindOrGridLayoutRowKind { + return &DashboardGridLayoutItemKindOrGridLayoutRowKind{} +} + +// MarshalJSON implements a custom JSON marshalling logic to encode `DashboardGridLayoutItemKindOrGridLayoutRowKind` as JSON. +func (resource DashboardGridLayoutItemKindOrGridLayoutRowKind) MarshalJSON() ([]byte, error) { + if resource.GridLayoutItemKind != nil { + return json.Marshal(resource.GridLayoutItemKind) + } + if resource.GridLayoutRowKind != nil { + return json.Marshal(resource.GridLayoutRowKind) + } + + return nil, fmt.Errorf("no value for disjunction of refs") +} + +// UnmarshalJSON implements a custom JSON unmarshalling logic to decode `DashboardGridLayoutItemKindOrGridLayoutRowKind` from JSON. +func (resource *DashboardGridLayoutItemKindOrGridLayoutRowKind) UnmarshalJSON(raw []byte) error { + if raw == nil { + return nil + } + + // FIXME: this is wasteful, we need to find a more efficient way to unmarshal this. + parsedAsMap := make(map[string]interface{}) + if err := json.Unmarshal(raw, &parsedAsMap); err != nil { + return err + } + + discriminator, found := parsedAsMap["kind"] + if !found { + return errors.New("discriminator field 'kind' not found in payload") + } + + switch discriminator { + case "GridLayoutItem": + var dashboardGridLayoutItemKind DashboardGridLayoutItemKind + if err := json.Unmarshal(raw, &dashboardGridLayoutItemKind); err != nil { + return err + } + + resource.GridLayoutItemKind = &dashboardGridLayoutItemKind + return nil + case "GridLayoutRow": + var dashboardGridLayoutRowKind DashboardGridLayoutRowKind + if err := json.Unmarshal(raw, &dashboardGridLayoutRowKind); err != nil { + return err + } + + resource.GridLayoutRowKind = &dashboardGridLayoutRowKind + return nil + } + + return fmt.Errorf("could not unmarshal resource with `kind = %v`", discriminator) +} + +// +k8s:openapi-gen=true +type DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind struct { + GridLayoutKind *DashboardGridLayoutKind `json:"GridLayoutKind,omitempty"` + ResponsiveGridLayoutKind *DashboardResponsiveGridLayoutKind `json:"ResponsiveGridLayoutKind,omitempty"` + TabsLayoutKind *DashboardTabsLayoutKind `json:"TabsLayoutKind,omitempty"` +} + +// NewDashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind creates a new DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind object. +func NewDashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind() *DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind { + return &DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind{} +} + +// MarshalJSON implements a custom JSON marshalling logic to encode `DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind` as JSON. +func (resource DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind) MarshalJSON() ([]byte, error) { + if resource.GridLayoutKind != nil { + return json.Marshal(resource.GridLayoutKind) + } + if resource.ResponsiveGridLayoutKind != nil { + return json.Marshal(resource.ResponsiveGridLayoutKind) + } + if resource.TabsLayoutKind != nil { + return json.Marshal(resource.TabsLayoutKind) + } + + return nil, fmt.Errorf("no value for disjunction of refs") +} + +// UnmarshalJSON implements a custom JSON unmarshalling logic to decode `DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind` from JSON. +func (resource *DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind) UnmarshalJSON(raw []byte) error { + if raw == nil { + return nil + } + + // FIXME: this is wasteful, we need to find a more efficient way to unmarshal this. + parsedAsMap := make(map[string]interface{}) + if err := json.Unmarshal(raw, &parsedAsMap); err != nil { + return err + } + + discriminator, found := parsedAsMap["kind"] + if !found { + return errors.New("discriminator field 'kind' not found in payload") + } + + switch discriminator { + case "GridLayout": + var dashboardGridLayoutKind DashboardGridLayoutKind + if err := json.Unmarshal(raw, &dashboardGridLayoutKind); err != nil { + return err + } + + resource.GridLayoutKind = &dashboardGridLayoutKind + return nil + case "ResponsiveGridLayout": + var dashboardResponsiveGridLayoutKind DashboardResponsiveGridLayoutKind + if err := json.Unmarshal(raw, &dashboardResponsiveGridLayoutKind); err != nil { + return err + } + + resource.ResponsiveGridLayoutKind = &dashboardResponsiveGridLayoutKind + return nil + case "TabsLayout": + var dashboardTabsLayoutKind DashboardTabsLayoutKind + if err := json.Unmarshal(raw, &dashboardTabsLayoutKind); err != nil { + return err + } + + resource.TabsLayoutKind = &dashboardTabsLayoutKind + return nil + } + + return fmt.Errorf("could not unmarshal resource with `kind = %v`", discriminator) +} + +// +k8s:openapi-gen=true +type DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind struct { + GridLayoutKind *DashboardGridLayoutKind `json:"GridLayoutKind,omitempty"` + RowsLayoutKind *DashboardRowsLayoutKind `json:"RowsLayoutKind,omitempty"` + ResponsiveGridLayoutKind *DashboardResponsiveGridLayoutKind `json:"ResponsiveGridLayoutKind,omitempty"` +} + +// NewDashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind creates a new DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind object. +func NewDashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind() *DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind { + return &DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind{} +} + +// MarshalJSON implements a custom JSON marshalling logic to encode `DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind` as JSON. +func (resource DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind) MarshalJSON() ([]byte, error) { + if resource.GridLayoutKind != nil { + return json.Marshal(resource.GridLayoutKind) + } + if resource.RowsLayoutKind != nil { + return json.Marshal(resource.RowsLayoutKind) + } + if resource.ResponsiveGridLayoutKind != nil { + return json.Marshal(resource.ResponsiveGridLayoutKind) + } + + return nil, fmt.Errorf("no value for disjunction of refs") +} + +// UnmarshalJSON implements a custom JSON unmarshalling logic to decode `DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind` from JSON. +func (resource *DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind) UnmarshalJSON(raw []byte) error { + if raw == nil { + return nil + } + + // FIXME: this is wasteful, we need to find a more efficient way to unmarshal this. + parsedAsMap := make(map[string]interface{}) + if err := json.Unmarshal(raw, &parsedAsMap); err != nil { + return err + } + + discriminator, found := parsedAsMap["kind"] + if !found { + return errors.New("discriminator field 'kind' not found in payload") + } + + switch discriminator { + case "GridLayout": + var dashboardGridLayoutKind DashboardGridLayoutKind + if err := json.Unmarshal(raw, &dashboardGridLayoutKind); err != nil { + return err + } + + resource.GridLayoutKind = &dashboardGridLayoutKind + return nil + case "ResponsiveGridLayout": + var dashboardResponsiveGridLayoutKind DashboardResponsiveGridLayoutKind + if err := json.Unmarshal(raw, &dashboardResponsiveGridLayoutKind); err != nil { + return err + } + + resource.ResponsiveGridLayoutKind = &dashboardResponsiveGridLayoutKind + return nil + case "RowsLayout": + var dashboardRowsLayoutKind DashboardRowsLayoutKind + if err := json.Unmarshal(raw, &dashboardRowsLayoutKind); err != nil { + return err + } + + resource.RowsLayoutKind = &dashboardRowsLayoutKind + return nil + } + + return fmt.Errorf("could not unmarshal resource with `kind = %v`", discriminator) +} + +// +k8s:openapi-gen=true +type DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind struct { + QueryVariableKind *DashboardQueryVariableKind `json:"QueryVariableKind,omitempty"` + TextVariableKind *DashboardTextVariableKind `json:"TextVariableKind,omitempty"` + ConstantVariableKind *DashboardConstantVariableKind `json:"ConstantVariableKind,omitempty"` + DatasourceVariableKind *DashboardDatasourceVariableKind `json:"DatasourceVariableKind,omitempty"` + IntervalVariableKind *DashboardIntervalVariableKind `json:"IntervalVariableKind,omitempty"` + CustomVariableKind *DashboardCustomVariableKind `json:"CustomVariableKind,omitempty"` + GroupByVariableKind *DashboardGroupByVariableKind `json:"GroupByVariableKind,omitempty"` + AdhocVariableKind *DashboardAdhocVariableKind `json:"AdhocVariableKind,omitempty"` +} + +// NewDashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind creates a new DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind object. +func NewDashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind() *DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind { + return &DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind{} +} + +// MarshalJSON implements a custom JSON marshalling logic to encode `DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind` as JSON. +func (resource DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind) MarshalJSON() ([]byte, error) { + if resource.QueryVariableKind != nil { + return json.Marshal(resource.QueryVariableKind) + } + if resource.TextVariableKind != nil { + return json.Marshal(resource.TextVariableKind) + } + if resource.ConstantVariableKind != nil { + return json.Marshal(resource.ConstantVariableKind) + } + if resource.DatasourceVariableKind != nil { + return json.Marshal(resource.DatasourceVariableKind) + } + if resource.IntervalVariableKind != nil { + return json.Marshal(resource.IntervalVariableKind) + } + if resource.CustomVariableKind != nil { + return json.Marshal(resource.CustomVariableKind) + } + if resource.GroupByVariableKind != nil { + return json.Marshal(resource.GroupByVariableKind) + } + if resource.AdhocVariableKind != nil { + return json.Marshal(resource.AdhocVariableKind) + } + + return nil, fmt.Errorf("no value for disjunction of refs") +} + +// UnmarshalJSON implements a custom JSON unmarshalling logic to decode `DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind` from JSON. +func (resource *DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind) UnmarshalJSON(raw []byte) error { + if raw == nil { + return nil + } + + // FIXME: this is wasteful, we need to find a more efficient way to unmarshal this. + parsedAsMap := make(map[string]interface{}) + if err := json.Unmarshal(raw, &parsedAsMap); err != nil { + return err + } + + discriminator, found := parsedAsMap["kind"] + if !found { + return errors.New("discriminator field 'kind' not found in payload") + } + + switch discriminator { + case "AdhocVariable": + var dashboardAdhocVariableKind DashboardAdhocVariableKind + if err := json.Unmarshal(raw, &dashboardAdhocVariableKind); err != nil { + return err + } + + resource.AdhocVariableKind = &dashboardAdhocVariableKind + return nil + case "ConstantVariable": + var dashboardConstantVariableKind DashboardConstantVariableKind + if err := json.Unmarshal(raw, &dashboardConstantVariableKind); err != nil { + return err + } + + resource.ConstantVariableKind = &dashboardConstantVariableKind + return nil + case "CustomVariable": + var dashboardCustomVariableKind DashboardCustomVariableKind + if err := json.Unmarshal(raw, &dashboardCustomVariableKind); err != nil { + return err + } + + resource.CustomVariableKind = &dashboardCustomVariableKind + return nil + case "DatasourceVariable": + var dashboardDatasourceVariableKind DashboardDatasourceVariableKind + if err := json.Unmarshal(raw, &dashboardDatasourceVariableKind); err != nil { + return err + } + + resource.DatasourceVariableKind = &dashboardDatasourceVariableKind + return nil + case "GroupByVariable": + var dashboardGroupByVariableKind DashboardGroupByVariableKind + if err := json.Unmarshal(raw, &dashboardGroupByVariableKind); err != nil { + return err + } + + resource.GroupByVariableKind = &dashboardGroupByVariableKind + return nil + case "IntervalVariable": + var dashboardIntervalVariableKind DashboardIntervalVariableKind + if err := json.Unmarshal(raw, &dashboardIntervalVariableKind); err != nil { + return err + } + + resource.IntervalVariableKind = &dashboardIntervalVariableKind + return nil + case "QueryVariable": + var dashboardQueryVariableKind DashboardQueryVariableKind + if err := json.Unmarshal(raw, &dashboardQueryVariableKind); err != nil { + return err + } + + resource.QueryVariableKind = &dashboardQueryVariableKind + return nil + case "TextVariable": + var dashboardTextVariableKind DashboardTextVariableKind + if err := json.Unmarshal(raw, &dashboardTextVariableKind); err != nil { + return err + } + + resource.TextVariableKind = &dashboardTextVariableKind + return nil + } + + return fmt.Errorf("could not unmarshal resource with `kind = %v`", discriminator) +} + +// +k8s:openapi-gen=true +type DashboardStringOrArrayOfString struct { + String *string `json:"String,omitempty"` + ArrayOfString []string `json:"ArrayOfString,omitempty"` +} + +// NewDashboardStringOrArrayOfString creates a new DashboardStringOrArrayOfString object. +func NewDashboardStringOrArrayOfString() *DashboardStringOrArrayOfString { + return &DashboardStringOrArrayOfString{} +} + +// MarshalJSON implements a custom JSON marshalling logic to encode `DashboardStringOrArrayOfString` as JSON. +func (resource DashboardStringOrArrayOfString) MarshalJSON() ([]byte, error) { + if resource.String != nil { + return json.Marshal(resource.String) + } + + if resource.ArrayOfString != nil { + return json.Marshal(resource.ArrayOfString) + } + + return nil, fmt.Errorf("no value for disjunction of scalars") +} + +// UnmarshalJSON implements a custom JSON unmarshalling logic to decode `DashboardStringOrArrayOfString` from JSON. +func (resource *DashboardStringOrArrayOfString) UnmarshalJSON(raw []byte) error { + if raw == nil { + return nil + } + + var errList []error + + // String + var String string + if err := json.Unmarshal(raw, &String); err != nil { + errList = append(errList, err) + resource.String = nil + } else { + resource.String = &String + return nil + } + + // ArrayOfString + var ArrayOfString []string + if err := json.Unmarshal(raw, &ArrayOfString); err != nil { + errList = append(errList, err) + resource.ArrayOfString = nil + } else { + resource.ArrayOfString = ArrayOfString + return nil + } + + return errors.Join(errList...) +} + +// +k8s:openapi-gen=true +type DashboardStringOrFloat64 struct { + String *string `json:"String,omitempty"` + Float64 *float64 `json:"Float64,omitempty"` +} + +// NewDashboardStringOrFloat64 creates a new DashboardStringOrFloat64 object. +func NewDashboardStringOrFloat64() *DashboardStringOrFloat64 { + return &DashboardStringOrFloat64{} +} + +// MarshalJSON implements a custom JSON marshalling logic to encode `DashboardStringOrFloat64` as JSON. +func (resource DashboardStringOrFloat64) MarshalJSON() ([]byte, error) { + if resource.String != nil { + return json.Marshal(resource.String) + } + + if resource.Float64 != nil { + return json.Marshal(resource.Float64) + } + + return nil, fmt.Errorf("no value for disjunction of scalars") +} + +// UnmarshalJSON implements a custom JSON unmarshalling logic to decode `DashboardStringOrFloat64` from JSON. +func (resource *DashboardStringOrFloat64) UnmarshalJSON(raw []byte) error { + if raw == nil { + return nil + } + + var errList []error + + // String + var String string + if err := json.Unmarshal(raw, &String); err != nil { + errList = append(errList, err) + resource.String = nil + } else { + resource.String = &String + return nil + } + + // Float64 + var Float64 float64 + if err := json.Unmarshal(raw, &Float64); err != nil { + errList = append(errList, err) + resource.Float64 = nil + } else { + resource.Float64 = &Float64 + return nil + } + + return errors.Join(errList...) +} + +// +k8s:openapi-gen=true +type DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind struct { + GridLayoutKind *DashboardGridLayoutKind `json:"GridLayoutKind,omitempty"` + RowsLayoutKind *DashboardRowsLayoutKind `json:"RowsLayoutKind,omitempty"` + ResponsiveGridLayoutKind *DashboardResponsiveGridLayoutKind `json:"ResponsiveGridLayoutKind,omitempty"` + TabsLayoutKind *DashboardTabsLayoutKind `json:"TabsLayoutKind,omitempty"` +} + +// NewDashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind creates a new DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind object. +func NewDashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind() *DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind { + return &DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind{} +} + +// MarshalJSON implements a custom JSON marshalling logic to encode `DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind` as JSON. +func (resource DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind) MarshalJSON() ([]byte, error) { + if resource.GridLayoutKind != nil { + return json.Marshal(resource.GridLayoutKind) + } + if resource.RowsLayoutKind != nil { + return json.Marshal(resource.RowsLayoutKind) + } + if resource.ResponsiveGridLayoutKind != nil { + return json.Marshal(resource.ResponsiveGridLayoutKind) + } + if resource.TabsLayoutKind != nil { + return json.Marshal(resource.TabsLayoutKind) + } + + return nil, fmt.Errorf("no value for disjunction of refs") +} + +// UnmarshalJSON implements a custom JSON unmarshalling logic to decode `DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind` from JSON. +func (resource *DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind) UnmarshalJSON(raw []byte) error { + if raw == nil { + return nil + } + + // FIXME: this is wasteful, we need to find a more efficient way to unmarshal this. + parsedAsMap := make(map[string]interface{}) + if err := json.Unmarshal(raw, &parsedAsMap); err != nil { + return err + } + + discriminator, found := parsedAsMap["kind"] + if !found { + return errors.New("discriminator field 'kind' not found in payload") + } + + switch discriminator { + case "GridLayout": + var dashboardGridLayoutKind DashboardGridLayoutKind + if err := json.Unmarshal(raw, &dashboardGridLayoutKind); err != nil { + return err + } + + resource.GridLayoutKind = &dashboardGridLayoutKind + return nil + case "ResponsiveGridLayout": + var dashboardResponsiveGridLayoutKind DashboardResponsiveGridLayoutKind + if err := json.Unmarshal(raw, &dashboardResponsiveGridLayoutKind); err != nil { + return err + } + + resource.ResponsiveGridLayoutKind = &dashboardResponsiveGridLayoutKind + return nil + case "RowsLayout": + var dashboardRowsLayoutKind DashboardRowsLayoutKind + if err := json.Unmarshal(raw, &dashboardRowsLayoutKind); err != nil { + return err + } + + resource.RowsLayoutKind = &dashboardRowsLayoutKind + return nil + case "TabsLayout": + var dashboardTabsLayoutKind DashboardTabsLayoutKind + if err := json.Unmarshal(raw, &dashboardTabsLayoutKind); err != nil { + return err + } + + resource.TabsLayoutKind = &dashboardTabsLayoutKind + return nil + } + + return fmt.Errorf("could not unmarshal resource with `kind = %v`", discriminator) +} diff --git a/pkg/apis/dashboard/v2alpha1/dashboard_status_gen.go b/pkg/apis/dashboard/v2alpha1/dashboard_status_gen.go new file mode 100644 index 00000000000..5bd84ac30cc --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/dashboard_status_gen.go @@ -0,0 +1,34 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v2alpha1 + +// ConversionStatus is the status of the conversion of the dashboard. +// +k8s:openapi-gen=true +type DashboardConversionStatus struct { + // Whether from another version has failed. + // If true, means that the dashboard is not valid, + // and the caller should instead fetch the stored version. + Failed bool `json:"failed"` + // The version which was stored when the dashboard was created / updated. + // Fetching this version should always succeed. + StoredVersion string `json:"storedVersion"` + // The error message from the conversion. + // Empty if the conversion has not failed. + Error string `json:"error"` +} + +// NewDashboardConversionStatus creates a new DashboardConversionStatus object. +func NewDashboardConversionStatus() *DashboardConversionStatus { + return &DashboardConversionStatus{} +} + +// +k8s:openapi-gen=true +type DashboardStatus struct { + // Optional conversion status. + Conversion *DashboardConversionStatus `json:"conversion,omitempty"` +} + +// NewDashboardStatus creates a new DashboardStatus object. +func NewDashboardStatus() *DashboardStatus { + return &DashboardStatus{} +} diff --git a/pkg/apis/dashboard/v2alpha1/deepcopy.go b/pkg/apis/dashboard/v2alpha1/deepcopy.go new file mode 100644 index 00000000000..621d7232a8e --- /dev/null +++ b/pkg/apis/dashboard/v2alpha1/deepcopy.go @@ -0,0 +1,63 @@ +package v2alpha1 + +import "reflect" + +// TODO: these should be automatically generated by the SDK. + +func (in *Dashboard) DeepCopyInto(out *Dashboard) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +func (in *Dashboard) DeepCopy() *Dashboard { + if in == nil { + return nil + } + out := new(Dashboard) + in.DeepCopyInto(out) + return out +} + +func (in *DashboardList) DeepCopyInto(out *DashboardList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Dashboard, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +func (in *DashboardList) DeepCopy() *DashboardList { + if in == nil { + return nil + } + out := new(DashboardList) + in.DeepCopyInto(out) + return out +} + +// TODO: we currently don't generate these methods for spec / status types. +// We probably should do that in the SDK. + +func (in *DashboardSpec) DeepCopyInto(out *DashboardSpec) { + // TODO (@radiohead): since we don't generate this, + // I've added a manual reflection-based implementation for now. + val := reflect.ValueOf(in).Elem() + cpy := reflect.New(val.Type()) + cpy.Elem().Set(val) +} + +func (in *DashboardSpec) DeepCopy() *DashboardSpec { + if in == nil { + return nil + } + out := new(DashboardSpec) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apis/dashboard/v2alpha1/doc.go b/pkg/apis/dashboard/v2alpha1/doc.go index eac83f16cf9..8866425fdce 100644 --- a/pkg/apis/dashboard/v2alpha1/doc.go +++ b/pkg/apis/dashboard/v2alpha1/doc.go @@ -1,7 +1,10 @@ -// +k8s:deepcopy-gen=package // +k8s:openapi-gen=true // +k8s:defaulter-gen=TypeMeta // +k8s:conversion-gen=github.com/grafana/grafana/pkg/apis/dashboard // +groupName=dashboard.grafana.app +// NOTE (@radiohead): we do not use package-wide deepcopy generation +// because grafana-app-sdk already provides deepcopy functions. +// Kinds which are not generated by the SDK are explicitly opted in to deepcopy generation. + package v2alpha1 // import "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1" diff --git a/pkg/apis/dashboard/v2alpha1/register.go b/pkg/apis/dashboard/v2alpha1/register.go index 8ee9e149d7a..31aa15a72dd 100644 --- a/pkg/apis/dashboard/v2alpha1/register.go +++ b/pkg/apis/dashboard/v2alpha1/register.go @@ -32,7 +32,7 @@ var DashboardResourceInfo = utils.NewResourceInfo(GROUP, VERSION, if dash != nil { return []interface{}{ dash.Name, - dash.Spec.GetNestedString("title"), + dash.Spec.Title, dash.CreationTimestamp.UTC().Format(time.RFC3339), }, nil } @@ -54,14 +54,14 @@ var LibraryPanelResourceInfo = utils.NewResourceInfo(GROUP, VERSION, {Name: "Created At", Type: "date"}, }, Reader: func(obj any) ([]interface{}, error) { - dash, ok := obj.(*LibraryPanel) + panel, ok := obj.(*LibraryPanel) if ok { - if dash != nil { + if panel != nil { return []interface{}{ - dash.Name, - dash.Spec.Title, - dash.Spec.Type, - dash.CreationTimestamp.UTC().Format(time.RFC3339), + panel.Name, + panel.Spec.Title, + panel.Spec.Type, + panel.CreationTimestamp.UTC().Format(time.RFC3339), }, nil } } diff --git a/pkg/apis/dashboard/v2alpha1/types.go b/pkg/apis/dashboard/v2alpha1/types.go index dd25b2e683b..7cc9d29d149 100644 --- a/pkg/apis/dashboard/v2alpha1/types.go +++ b/pkg/apis/dashboard/v2alpha1/types.go @@ -7,40 +7,7 @@ import ( common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" ) -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -type Dashboard struct { - metav1.TypeMeta `json:",inline"` - // Standard object's metadata - // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata - // +optional - metav1.ObjectMeta `json:"metadata,omitempty"` - - // The dashboard body (unstructured for now) - Spec common.Unstructured `json:"spec"` - - // Optional dashboard status - Status *DashboardStatus `json:"status,omitempty"` -} - -type DashboardStatus struct { - ConversionStatus *ConversionStatus `json:"conversion,omitempty"` -} - -type ConversionStatus struct { - Failed bool `json:"failed,omitempty"` - StoredVersion string `json:"storedVersion,omitempty"` - Error string `json:"error,omitempty"` -} - -// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object -type DashboardList struct { - metav1.TypeMeta `json:",inline"` - // +optional - metav1.ListMeta `json:"metadata,omitempty"` - - Items []Dashboard `json:"items,omitempty"` -} - +// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type DashboardVersionList struct { metav1.TypeMeta `json:",inline"` @@ -50,6 +17,7 @@ type DashboardVersionList struct { Items []DashboardVersionInfo `json:"items,omitempty"` } +// +k8s:deepcopy-gen=true type DashboardVersionInfo struct { // The internal ID for this version (will be replaced with resourceVersion) Version int `json:"version"` @@ -67,6 +35,7 @@ type DashboardVersionInfo struct { Message string `json:"message,omitempty"` } +// +k8s:deepcopy-gen=true // +k8s:conversion-gen:explicit-from=net/url.Values // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type VersionsQueryOptions struct { @@ -80,6 +49,7 @@ type VersionsQueryOptions struct { Version int64 `json:"version,omitempty"` } +// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type LibraryPanel struct { metav1.TypeMeta `json:",inline"` @@ -95,6 +65,7 @@ type LibraryPanel struct { Status *LibraryPanelStatus `json:"status,omitempty"` } +// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type LibraryPanelList struct { metav1.TypeMeta `json:",inline"` @@ -104,6 +75,7 @@ type LibraryPanelList struct { Items []LibraryPanel `json:"items,omitempty"` } +// +k8s:deepcopy-gen=true type LibraryPanelSpec struct { // The panel type Type string `json:"type"` @@ -131,6 +103,7 @@ type LibraryPanelSpec struct { Targets []data.DataQuery `json:"targets,omitempty"` } +// +k8s:deepcopy-gen=true type LibraryPanelStatus struct { // Translation warnings (mostly things that were in SQL columns but not found in the saved body) Warnings []string `json:"warnings,omitempty"` @@ -140,6 +113,7 @@ type LibraryPanelStatus struct { } // This is like the legacy DTO where access and metadata are all returned in a single call +// +k8s:deepcopy-gen=true // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object type DashboardWithAccessInfo struct { Dashboard `json:",inline"` @@ -148,6 +122,7 @@ type DashboardWithAccessInfo struct { } // Information about how the requesting user can use a given dashboard +// +k8s:deepcopy-gen=true type DashboardAccess struct { // Metadata fields Slug string `json:"slug,omitempty"` @@ -162,11 +137,13 @@ type DashboardAccess struct { AnnotationsPermissions *AnnotationPermission `json:"annotationsPermissions"` } +// +k8s:deepcopy-gen=true type AnnotationPermission struct { Dashboard AnnotationActions `json:"dashboard"` Organization AnnotationActions `json:"organization"` } +// +k8s:deepcopy-gen=true type AnnotationActions struct { CanAdd bool `json:"canAdd"` CanEdit bool `json:"canEdit"` diff --git a/pkg/apis/dashboard/v2alpha1/zz_generated.deepcopy.go b/pkg/apis/dashboard/v2alpha1/zz_generated.deepcopy.go index 36e22f8aeda..6ce617a1d0b 100644 --- a/pkg/apis/dashboard/v2alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/dashboard/v2alpha1/zz_generated.deepcopy.go @@ -46,54 +46,6 @@ func (in *AnnotationPermission) DeepCopy() *AnnotationPermission { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *ConversionStatus) DeepCopyInto(out *ConversionStatus) { - *out = *in - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConversionStatus. -func (in *ConversionStatus) DeepCopy() *ConversionStatus { - if in == nil { - return nil - } - out := new(ConversionStatus) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Dashboard) DeepCopyInto(out *Dashboard) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - if in.Status != nil { - in, out := &in.Status, &out.Status - *out = new(DashboardStatus) - (*in).DeepCopyInto(*out) - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Dashboard. -func (in *Dashboard) DeepCopy() *Dashboard { - if in == nil { - return nil - } - out := new(Dashboard) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *Dashboard) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DashboardAccess) DeepCopyInto(out *DashboardAccess) { *out = *in @@ -115,60 +67,6 @@ func (in *DashboardAccess) DeepCopy() *DashboardAccess { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DashboardList) DeepCopyInto(out *DashboardList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]Dashboard, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardList. -func (in *DashboardList) DeepCopy() *DashboardList { - if in == nil { - return nil - } - out := new(DashboardList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DashboardList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DashboardStatus) DeepCopyInto(out *DashboardStatus) { - *out = *in - if in.ConversionStatus != nil { - in, out := &in.ConversionStatus, &out.ConversionStatus - *out = new(ConversionStatus) - **out = **in - } - return -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardStatus. -func (in *DashboardStatus) DeepCopy() *DashboardStatus { - if in == nil { - return nil - } - out := new(DashboardStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DashboardVersionInfo) DeepCopyInto(out *DashboardVersionInfo) { *out = *in diff --git a/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go b/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go index bb6364a92ce..1025adcda86 100644 --- a/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go +++ b/pkg/apis/dashboard/v2alpha1/zz_generated.openapi.go @@ -14,21 +14,113 @@ import ( func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.AnnotationActions": schema_pkg_apis_dashboard_v2alpha1_AnnotationActions(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.AnnotationPermission": schema_pkg_apis_dashboard_v2alpha1_AnnotationPermission(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.ConversionStatus": schema_pkg_apis_dashboard_v2alpha1_ConversionStatus(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.Dashboard": schema_pkg_apis_dashboard_v2alpha1_Dashboard(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAccess": schema_pkg_apis_dashboard_v2alpha1_DashboardAccess(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardList": schema_pkg_apis_dashboard_v2alpha1_DashboardList(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStatus": schema_pkg_apis_dashboard_v2alpha1_DashboardStatus(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVersionInfo": schema_pkg_apis_dashboard_v2alpha1_DashboardVersionInfo(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVersionList": schema_pkg_apis_dashboard_v2alpha1_DashboardVersionList(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardWithAccessInfo": schema_pkg_apis_dashboard_v2alpha1_DashboardWithAccessInfo(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanel": schema_pkg_apis_dashboard_v2alpha1_LibraryPanel(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanelList": schema_pkg_apis_dashboard_v2alpha1_LibraryPanelList(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanelSpec": schema_pkg_apis_dashboard_v2alpha1_LibraryPanelSpec(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanelStatus": schema_pkg_apis_dashboard_v2alpha1_LibraryPanelStatus(ref), - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.VersionsQueryOptions": schema_pkg_apis_dashboard_v2alpha1_VersionsQueryOptions(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.AnnotationActions": schema_pkg_apis_dashboard_v2alpha1_AnnotationActions(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.AnnotationPermission": schema_pkg_apis_dashboard_v2alpha1_AnnotationPermission(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.Dashboard": schema_pkg_apis_dashboard_v2alpha1_Dashboard(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAccess": schema_pkg_apis_dashboard_v2alpha1_DashboardAccess(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAdHocFilterWithLabels": schema_pkg_apis_dashboard_v2alpha1_DashboardAdHocFilterWithLabels(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAdhocVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardAdhocVariableKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAdhocVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardAdhocVariableSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAnnotationPanelFilter": schema_pkg_apis_dashboard_v2alpha1_DashboardAnnotationPanelFilter(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAnnotationQueryKind": schema_pkg_apis_dashboard_v2alpha1_DashboardAnnotationQueryKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAnnotationQuerySpec": schema_pkg_apis_dashboard_v2alpha1_DashboardAnnotationQuerySpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardConstantVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardConstantVariableKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardConstantVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardConstantVariableSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardConversionStatus": schema_pkg_apis_dashboard_v2alpha1_DashboardConversionStatus(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardCustomVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardCustomVariableKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardCustomVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardCustomVariableSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDashboardLink": schema_pkg_apis_dashboard_v2alpha1_DashboardDashboardLink(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataLink": schema_pkg_apis_dashboard_v2alpha1_DashboardDataLink(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataQueryKind": schema_pkg_apis_dashboard_v2alpha1_DashboardDataQueryKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataSourceRef": schema_pkg_apis_dashboard_v2alpha1_DashboardDataSourceRef(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataTransformerConfig": schema_pkg_apis_dashboard_v2alpha1_DashboardDataTransformerConfig(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDatasourceVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardDatasourceVariableKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDatasourceVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardDatasourceVariableSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDynamicConfigValue": schema_pkg_apis_dashboard_v2alpha1_DashboardDynamicConfigValue(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardElementReference": schema_pkg_apis_dashboard_v2alpha1_DashboardElementReference(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardFieldColor": schema_pkg_apis_dashboard_v2alpha1_DashboardFieldColor(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardFieldConfig": schema_pkg_apis_dashboard_v2alpha1_DashboardFieldConfig(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardFieldConfigSource": schema_pkg_apis_dashboard_v2alpha1_DashboardFieldConfigSource(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutItemKind": schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutItemKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutItemKindOrGridLayoutRowKind": schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutItemKindOrGridLayoutRowKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutItemSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutItemSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKind": schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind": schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind": schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind": schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutRowKind": schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutRowKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutRowSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutRowSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGroupByVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardGroupByVariableKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGroupByVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardGroupByVariableSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardIntervalVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardIntervalVariableKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardIntervalVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardIntervalVariableSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardJSONCodec": schema_pkg_apis_dashboard_v2alpha1_DashboardJSONCodec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardLibraryPanelKind": schema_pkg_apis_dashboard_v2alpha1_DashboardLibraryPanelKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardLibraryPanelKindSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardLibraryPanelKindSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardLibraryPanelRef": schema_pkg_apis_dashboard_v2alpha1_DashboardLibraryPanelRef(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardList": schema_pkg_apis_dashboard_v2alpha1_DashboardList(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardMatcherConfig": schema_pkg_apis_dashboard_v2alpha1_DashboardMatcherConfig(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardMetadata": schema_pkg_apis_dashboard_v2alpha1_DashboardMetadata(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardMetricFindValue": schema_pkg_apis_dashboard_v2alpha1_DashboardMetricFindValue(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardPanelKind": schema_pkg_apis_dashboard_v2alpha1_DashboardPanelKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardPanelKindOrLibraryPanelKind": schema_pkg_apis_dashboard_v2alpha1_DashboardPanelKindOrLibraryPanelKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardPanelQueryKind": schema_pkg_apis_dashboard_v2alpha1_DashboardPanelQueryKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardPanelQuerySpec": schema_pkg_apis_dashboard_v2alpha1_DashboardPanelQuerySpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardPanelSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardPanelSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryGroupKind": schema_pkg_apis_dashboard_v2alpha1_DashboardQueryGroupKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryGroupSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardQueryGroupSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryOptionsSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardQueryOptionsSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardQueryVariableKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardQueryVariableSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRangeMap": schema_pkg_apis_dashboard_v2alpha1_DashboardRangeMap(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRegexMap": schema_pkg_apis_dashboard_v2alpha1_DashboardRegexMap(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRepeatOptions": schema_pkg_apis_dashboard_v2alpha1_DashboardRepeatOptions(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutItemKind": schema_pkg_apis_dashboard_v2alpha1_DashboardResponsiveGridLayoutItemKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutItemSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardResponsiveGridLayoutItemSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutKind": schema_pkg_apis_dashboard_v2alpha1_DashboardResponsiveGridLayoutKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardResponsiveGridLayoutSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridRepeatOptions": schema_pkg_apis_dashboard_v2alpha1_DashboardResponsiveGridRepeatOptions(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowRepeatOptions": schema_pkg_apis_dashboard_v2alpha1_DashboardRowRepeatOptions(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowsLayoutKind": schema_pkg_apis_dashboard_v2alpha1_DashboardRowsLayoutKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowsLayoutRowKind": schema_pkg_apis_dashboard_v2alpha1_DashboardRowsLayoutRowKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowsLayoutRowSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardRowsLayoutRowSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowsLayoutSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardRowsLayoutSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardSpecialValueMap": schema_pkg_apis_dashboard_v2alpha1_DashboardSpecialValueMap(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStatus": schema_pkg_apis_dashboard_v2alpha1_DashboardStatus(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStringOrArrayOfString": schema_pkg_apis_dashboard_v2alpha1_DashboardStringOrArrayOfString(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStringOrFloat64": schema_pkg_apis_dashboard_v2alpha1_DashboardStringOrFloat64(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTabsLayoutKind": schema_pkg_apis_dashboard_v2alpha1_DashboardTabsLayoutKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTabsLayoutSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardTabsLayoutSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTabsLayoutTabKind": schema_pkg_apis_dashboard_v2alpha1_DashboardTabsLayoutTabKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTabsLayoutTabSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardTabsLayoutTabSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTextVariableKind": schema_pkg_apis_dashboard_v2alpha1_DashboardTextVariableKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTextVariableSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardTextVariableSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardThreshold": schema_pkg_apis_dashboard_v2alpha1_DashboardThreshold(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardThresholdsConfig": schema_pkg_apis_dashboard_v2alpha1_DashboardThresholdsConfig(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTimeRangeOption": schema_pkg_apis_dashboard_v2alpha1_DashboardTimeRangeOption(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTimeSettingsSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardTimeSettingsSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTransformationKind": schema_pkg_apis_dashboard_v2alpha1_DashboardTransformationKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1FieldConfigSourceOverrides": schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1FieldConfigSourceOverrides(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1RangeMapOptions": schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1RangeMapOptions(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1RegexMapOptions": schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1RegexMapOptions(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1SpecialValueMapOptions": schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1SpecialValueMapOptions(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardValueMap": schema_pkg_apis_dashboard_v2alpha1_DashboardValueMap(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap": schema_pkg_apis_dashboard_v2alpha1_DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardValueMappingResult": schema_pkg_apis_dashboard_v2alpha1_DashboardValueMappingResult(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption": schema_pkg_apis_dashboard_v2alpha1_DashboardVariableOption(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVersionInfo": schema_pkg_apis_dashboard_v2alpha1_DashboardVersionInfo(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVersionList": schema_pkg_apis_dashboard_v2alpha1_DashboardVersionList(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVizConfigKind": schema_pkg_apis_dashboard_v2alpha1_DashboardVizConfigKind(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVizConfigSpec": schema_pkg_apis_dashboard_v2alpha1_DashboardVizConfigSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardWithAccessInfo": schema_pkg_apis_dashboard_v2alpha1_DashboardWithAccessInfo(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanel": schema_pkg_apis_dashboard_v2alpha1_LibraryPanel(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanelList": schema_pkg_apis_dashboard_v2alpha1_LibraryPanelList(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanelSpec": schema_pkg_apis_dashboard_v2alpha1_LibraryPanelSpec(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.LibraryPanelStatus": schema_pkg_apis_dashboard_v2alpha1_LibraryPanelStatus(ref), + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.VersionsQueryOptions": schema_pkg_apis_dashboard_v2alpha1_VersionsQueryOptions(ref), } } @@ -93,36 +185,6 @@ func schema_pkg_apis_dashboard_v2alpha1_AnnotationPermission(ref common.Referenc } } -func schema_pkg_apis_dashboard_v2alpha1_ConversionStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "failed": { - SchemaProps: spec.SchemaProps{ - Type: []string{"boolean"}, - Format: "", - }, - }, - "storedVersion": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - "error": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, - }, - }, - }, - } -} - func schema_pkg_apis_dashboard_v2alpha1_Dashboard(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -145,29 +207,29 @@ func schema_pkg_apis_dashboard_v2alpha1_Dashboard(ref common.ReferenceCallback) }, "metadata": { SchemaProps: spec.SchemaProps{ - Description: "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), }, }, "spec": { SchemaProps: spec.SchemaProps{ - Description: "The dashboard body (unstructured for now)", - Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"), + Description: "Spec is the spec of the Dashboard", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardSpec"), }, }, "status": { SchemaProps: spec.SchemaProps{ - Description: "Optional dashboard status", - Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStatus"), + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStatus"), }, }, }, - Required: []string{"spec"}, + Required: []string{"metadata", "spec", "status"}, }, }, Dependencies: []string{ - "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardSpec", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, } } @@ -241,6 +303,1929 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardAccess(ref common.ReferenceCall } } +func schema_pkg_apis_dashboard_v2alpha1_DashboardAdHocFilterWithLabels(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Define the AdHocFilterWithLabels type", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "key": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "operator": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "value": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "values": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "keyLabel": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "valueLabels": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "forceEdit": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + Format: "", + }, + }, + "condition": { + SchemaProps: spec.SchemaProps{ + Description: "@deprecated", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"key", "operator", "value"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardAdhocVariableKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Adhoc variable kind", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAdhocVariableSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAdhocVariableSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardAdhocVariableSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Adhoc variable specification", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "datasource": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataSourceRef"), + }, + }, + "baseFilters": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAdHocFilterWithLabels"), + }, + }, + }, + }, + }, + "filters": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAdHocFilterWithLabels"), + }, + }, + }, + }, + }, + "defaultKeys": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardMetricFindValue"), + }, + }, + }, + }, + }, + "label": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "hide": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "skipUrlSync": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name", "baseFilters", "filters", "defaultKeys", "hide", "skipUrlSync"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAdHocFilterWithLabels", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataSourceRef", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardMetricFindValue"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardAnnotationPanelFilter(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "exclude": { + SchemaProps: spec.SchemaProps{ + Description: "Should the specified panels be included or excluded", + Type: []string{"boolean"}, + Format: "", + }, + }, + "ids": { + SchemaProps: spec.SchemaProps{ + Description: "Panel IDs that should be included or excluded", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "byte", + }, + }, + }, + }, + }, + }, + Required: []string{"ids"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardAnnotationQueryKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAnnotationQuerySpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAnnotationQuerySpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardAnnotationQuerySpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "datasource": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataSourceRef"), + }, + }, + "query": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataQueryKind"), + }, + }, + "enable": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "hide": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "iconColor": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "builtIn": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + Format: "", + }, + }, + "filter": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAnnotationPanelFilter"), + }, + }, + }, + Required: []string{"enable", "hide", "iconColor", "name"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAnnotationPanelFilter", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataQueryKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataSourceRef"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardConstantVariableKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Constant variable kind", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardConstantVariableSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardConstantVariableSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardConstantVariableSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Constant variable specification", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "query": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "current": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"), + }, + }, + "label": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "hide": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "skipUrlSync": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name", "query", "current", "hide", "skipUrlSync"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardConversionStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ConversionStatus is the status of the conversion of the dashboard.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "failed": { + SchemaProps: spec.SchemaProps{ + Description: "Whether from another version has failed. If true, means that the dashboard is not valid, and the caller should instead fetch the stored version.", + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "storedVersion": { + SchemaProps: spec.SchemaProps{ + Description: "The version which was stored when the dashboard was created / updated. Fetching this version should always succeed.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "error": { + SchemaProps: spec.SchemaProps{ + Description: "The error message from the conversion. Empty if the conversion has not failed.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"failed", "storedVersion", "error"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardCustomVariableKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Custom variable kind", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardCustomVariableSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardCustomVariableSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardCustomVariableSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Custom variable specification", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "query": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "current": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"), + }, + }, + "options": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"), + }, + }, + }, + }, + }, + "multi": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "includeAll": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "allValue": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "label": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "hide": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "skipUrlSync": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name", "query", "current", "options", "multi", "includeAll", "hide", "skipUrlSync"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardDashboardLink(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Links with references to other dashboards or external resources", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "title": { + SchemaProps: spec.SchemaProps{ + Description: "Title to display with the link", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "type": { + SchemaProps: spec.SchemaProps{ + Description: "Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource) FIXME: The type is generated as `type: DashboardLinkType | dashboardLinkType.Link;` but it should be `type: DashboardLinkType`", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "icon": { + SchemaProps: spec.SchemaProps{ + Description: "Icon name to be displayed with the link", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "tooltip": { + SchemaProps: spec.SchemaProps{ + Description: "Tooltip to display when the user hovers their mouse over it", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "url": { + SchemaProps: spec.SchemaProps{ + Description: "Link URL. Only required/valid if the type is link", + Type: []string{"string"}, + Format: "", + }, + }, + "tags": { + SchemaProps: spec.SchemaProps{ + Description: "List of tags to limit the linked dashboards. If empty, all dashboards will be displayed. Only valid if the type is dashboards", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "asDropdown": { + SchemaProps: spec.SchemaProps{ + Description: "If true, all dashboards links will be displayed in a dropdown. If false, all dashboards links will be displayed side by side. Only valid if the type is dashboards", + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "targetBlank": { + SchemaProps: spec.SchemaProps{ + Description: "If true, the link will be opened in a new tab", + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "includeVars": { + SchemaProps: spec.SchemaProps{ + Description: "If true, includes current template variables values in the link as query params", + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "keepTime": { + SchemaProps: spec.SchemaProps{ + Description: "If true, includes current time range in the link as query params", + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + Required: []string{"title", "type", "icon", "tooltip", "tags", "asDropdown", "targetBlank", "includeVars", "keepTime"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardDataLink(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "title": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "url": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "targetBlank": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + Required: []string{"title", "url"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardDataQueryKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "The kind of a DataQueryKind is the datasource type", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Format: "", + }, + }, + }, + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardDataSourceRef(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "type": { + SchemaProps: spec.SchemaProps{ + Description: "The plugin type-id", + Type: []string{"string"}, + Format: "", + }, + }, + "uid": { + SchemaProps: spec.SchemaProps{ + Description: "Specific datasource instance", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardDataTransformerConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Transformations allow to manipulate data returned by a query before the system applies a visualization. Using transformations you can: rename fields, join time series data, perform mathematical operations across queries, use the output of one transformation as the input to another transformation, etc.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "id": { + SchemaProps: spec.SchemaProps{ + Description: "Unique identifier of transformer", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "disabled": { + SchemaProps: spec.SchemaProps{ + Description: "Disabled transformations are skipped", + Type: []string{"boolean"}, + Format: "", + }, + }, + "filter": { + SchemaProps: spec.SchemaProps{ + Description: "Optional frame matcher. When missing it will be applied to all results", + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardMatcherConfig"), + }, + }, + "topic": { + SchemaProps: spec.SchemaProps{ + Description: "Where to pull DataFrames from as input to transformation", + Type: []string{"string"}, + Format: "", + }, + }, + "options": { + SchemaProps: spec.SchemaProps{ + Description: "Options to be passed to the transformer Valid options depend on the transformer id", + Type: []string{"object"}, + Format: "", + }, + }, + }, + Required: []string{"id", "options"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardMatcherConfig"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardDatasourceVariableKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Datasource variable kind", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDatasourceVariableSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDatasourceVariableSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardDatasourceVariableSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Datasource variable specification", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "pluginId": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "refresh": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "regex": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "current": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"), + }, + }, + "options": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"), + }, + }, + }, + }, + }, + "multi": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "includeAll": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "allValue": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "label": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "hide": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "skipUrlSync": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name", "pluginId", "refresh", "regex", "current", "options", "multi", "includeAll", "hide", "skipUrlSync"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardDynamicConfigValue(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "id": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "value": { + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Format: "", + }, + }, + }, + Required: []string{"id"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardElementReference(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"kind", "name"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardFieldColor(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Map a field to a color.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "mode": { + SchemaProps: spec.SchemaProps{ + Description: "The main color scheme mode.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "fixedColor": { + SchemaProps: spec.SchemaProps{ + Description: "The fixed color value for fixed or shades color modes.", + Type: []string{"string"}, + Format: "", + }, + }, + "seriesBy": { + SchemaProps: spec.SchemaProps{ + Description: "Some visualizations need to know how to assign a series color from by value color schemes.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"mode"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardFieldConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results. Each column within this structure is called a field. A field can represent a single time series or table column. Field options allow you to change how the data is displayed in your visualizations.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "displayName": { + SchemaProps: spec.SchemaProps{ + Description: "The display value for this field. This supports template variables blank is auto", + Type: []string{"string"}, + Format: "", + }, + }, + "displayNameFromDS": { + SchemaProps: spec.SchemaProps{ + Description: "This can be used by data sources that return and explicit naming structure for values and labels When this property is configured, this value is used rather than the default naming strategy.", + Type: []string{"string"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Description: "Human readable field metadata", + Type: []string{"string"}, + Format: "", + }, + }, + "path": { + SchemaProps: spec.SchemaProps{ + Description: "An explicit path to the field in the datasource. When the frame meta includes a path, This will default to `${frame.meta.path}/${field.name}\n\nWhen defined, this value can be used as an identifier within the datasource scope, and may be used to update the results", + Type: []string{"string"}, + Format: "", + }, + }, + "writeable": { + SchemaProps: spec.SchemaProps{ + Description: "True if data source can write a value to the path. Auth/authz are supported separately", + Type: []string{"boolean"}, + Format: "", + }, + }, + "filterable": { + SchemaProps: spec.SchemaProps{ + Description: "True if data source field supports ad-hoc filters", + Type: []string{"boolean"}, + Format: "", + }, + }, + "unit": { + SchemaProps: spec.SchemaProps{ + Description: "Unit a field should use. The unit you select is applied to all fields except time. You can use the units ID availables in Grafana or a custom unit. Available units in Grafana: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/valueFormats/categories.ts As custom unit, you can use the following formats: `suffix:` for custom unit that should go after value. `prefix:` for custom unit that should go before value. `time:` For custom date time formats type for example `time:YYYY-MM-DD`. `si:` for custom SI units. For example: `si: mF`. This one is a bit more advanced as you can specify both a unit and the source data scale. So if your source data is represented as milli (thousands of) something prefix the unit with that SI scale character. `count:` for a custom count unit. `currency:` for custom a currency unit.", + Type: []string{"string"}, + Format: "", + }, + }, + "decimals": { + SchemaProps: spec.SchemaProps{ + Description: "Specify the number of decimals Grafana includes in the rendered value. If you leave this field blank, Grafana automatically truncates the number of decimals based on the value. For example 1.1234 will display as 1.12 and 100.456 will display as 100. To display all decimals, set the unit to `String`.", + Type: []string{"number"}, + Format: "double", + }, + }, + "min": { + SchemaProps: spec.SchemaProps{ + Description: "The minimum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.", + Type: []string{"number"}, + Format: "double", + }, + }, + "max": { + SchemaProps: spec.SchemaProps{ + Description: "The maximum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields.", + Type: []string{"number"}, + Format: "double", + }, + }, + "mappings": { + SchemaProps: spec.SchemaProps{ + Description: "Convert input values into a display string", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap"), + }, + }, + }, + }, + }, + "thresholds": { + SchemaProps: spec.SchemaProps{ + Description: "Map numeric values to states", + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardThresholdsConfig"), + }, + }, + "color": { + SchemaProps: spec.SchemaProps{ + Description: "Panel color configuration", + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardFieldColor"), + }, + }, + "links": { + SchemaProps: spec.SchemaProps{ + Description: "The behavior when clicking on a result", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Format: "", + }, + }, + }, + }, + }, + "noValue": { + SchemaProps: spec.SchemaProps{ + Description: "Alternative to empty string", + Type: []string{"string"}, + Format: "", + }, + }, + "custom": { + SchemaProps: spec.SchemaProps{ + Description: "custom is specified by the FieldConfig field in panel plugin schemas.", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardFieldColor", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardThresholdsConfig", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardFieldConfigSource(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results. Each column within this structure is called a field. A field can represent a single time series or table column. Field options allow you to change how the data is displayed in your visualizations.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "defaults": { + SchemaProps: spec.SchemaProps{ + Description: "Defaults are the options applied to all fields.", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardFieldConfig"), + }, + }, + "overrides": { + SchemaProps: spec.SchemaProps{ + Description: "Overrides are the options applied to specific fields overriding the defaults.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1FieldConfigSourceOverrides"), + }, + }, + }, + }, + }, + }, + Required: []string{"defaults", "overrides"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardFieldConfig", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1FieldConfigSourceOverrides"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutItemKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutItemSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutItemSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutItemKindOrGridLayoutRowKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "GridLayoutItemKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutItemKind"), + }, + }, + "GridLayoutRowKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutRowKind"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutItemKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutRowKind"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutItemSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "x": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "y": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "width": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "height": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "element": { + SchemaProps: spec.SchemaProps{ + Description: "reference to a PanelKind from dashboard.spec.elements Expressed as JSON Schema reference", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardElementReference"), + }, + }, + "repeat": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRepeatOptions"), + }, + }, + }, + Required: []string{"x", "y", "width", "height", "element"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardElementReference", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRepeatOptions"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "GridLayoutKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKind"), + }, + }, + "ResponsiveGridLayoutKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutKind"), + }, + }, + "TabsLayoutKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTabsLayoutKind"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTabsLayoutKind"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "GridLayoutKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKind"), + }, + }, + "RowsLayoutKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowsLayoutKind"), + }, + }, + "ResponsiveGridLayoutKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutKind"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowsLayoutKind"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "GridLayoutKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKind"), + }, + }, + "RowsLayoutKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowsLayoutKind"), + }, + }, + "ResponsiveGridLayoutKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutKind"), + }, + }, + "TabsLayoutKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTabsLayoutKind"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowsLayoutKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTabsLayoutKind"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutRowKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutRowSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutRowSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutRowSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "y": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "collapsed": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "title": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "elements": { + SchemaProps: spec.SchemaProps{ + Description: "Grid items in the row will have their Y value be relative to the rows Y value. This means a panel positioned at Y: 0 in a row with Y: 10 will be positioned at Y: 11 (row header has a heigh of 1) in the dashboard.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutItemKind"), + }, + }, + }, + }, + }, + "repeat": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowRepeatOptions"), + }, + }, + }, + Required: []string{"y", "collapsed", "title", "elements"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutItemKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowRepeatOptions"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardGridLayoutSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "items": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutItemKindOrGridLayoutRowKind"), + }, + }, + }, + }, + }, + }, + Required: []string{"items"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutItemKindOrGridLayoutRowKind"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardGroupByVariableKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Group variable kind", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGroupByVariableSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGroupByVariableSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardGroupByVariableSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "GroupBy variable specification", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "datasource": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataSourceRef"), + }, + }, + "current": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"), + }, + }, + "options": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"), + }, + }, + }, + }, + }, + "multi": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "label": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "hide": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "skipUrlSync": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name", "current", "options", "multi", "hide", "skipUrlSync"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataSourceRef", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardIntervalVariableKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Interval variable kind", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardIntervalVariableSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardIntervalVariableSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardIntervalVariableSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Interval variable specification", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "query": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "current": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"), + }, + }, + "options": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"), + }, + }, + }, + }, + }, + "auto": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "auto_min": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "auto_count": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "refresh": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "label": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "hide": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "skipUrlSync": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name", "query", "current", "options", "auto", "auto_min", "auto_count", "refresh", "hide", "skipUrlSync"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardJSONCodec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DashboardJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding", + Type: []string{"object"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardLibraryPanelKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardLibraryPanelKindSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardLibraryPanelKindSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardLibraryPanelKindSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "id": { + SchemaProps: spec.SchemaProps{ + Description: "Panel ID for the library panel in the dashboard", + Default: 0, + Type: []string{"number"}, + Format: "double", + }, + }, + "title": { + SchemaProps: spec.SchemaProps{ + Description: "Title for the library panel in the dashboard", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "libraryPanel": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardLibraryPanelRef"), + }, + }, + }, + Required: []string{"id", "title", "libraryPanel"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardLibraryPanelRef"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardLibraryPanelRef(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "A library panel is a reusable panel that you can use in any dashboard. When you make a change to a library panel, that change propagates to all instances of where the panel is used. Library panels streamline reuse of panels across multiple dashboards.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Library panel name", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "uid": { + SchemaProps: spec.SchemaProps{ + Description: "Library panel uid", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name", "uid"}, + }, + }, + } +} + func schema_pkg_apis_dashboard_v2alpha1_DashboardList(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -281,6 +2266,7 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardList(ref common.ReferenceCallba }, }, }, + Required: []string{"metadata", "items"}, }, }, Dependencies: []string{ @@ -288,6 +2274,1280 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardList(ref common.ReferenceCallba } } +func schema_pkg_apis_dashboard_v2alpha1_DashboardMatcherConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Matcher is a predicate configuration. Based on the config a set of field(s) or values is filtered in order to apply override / transformation. It comes with in id ( to resolve implementation from registry) and a configuration that’s specific to a particular matcher type.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "id": { + SchemaProps: spec.SchemaProps{ + Description: "The matcher id. This is used to find the matcher implementation from registry.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "options": { + SchemaProps: spec.SchemaProps{ + Description: "The matcher options. This is specific to the matcher implementation.", + Type: []string{"object"}, + Format: "", + }, + }, + }, + Required: []string{"id"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardMetadata(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "metadata contains embedded CommonMetadata and can be extended with custom string fields without external reference as using the CommonMetadata reference breaks thema codegen.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "updateTimestamp": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "date-time", + }, + }, + "createdBy": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "uid": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "creationTimestamp": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "date-time", + }, + }, + "deletionTimestamp": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "date-time", + }, + }, + "finalizers": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "resourceVersion": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "generation": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "updatedBy": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "labels": { + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + Required: []string{"updateTimestamp", "createdBy", "uid", "creationTimestamp", "finalizers", "resourceVersion", "generation", "updatedBy", "labels"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardMetricFindValue(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Define the MetricFindValue type", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "text": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "value": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStringOrFloat64"), + }, + }, + "group": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "expandable": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + Required: []string{"text"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStringOrFloat64"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardPanelKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardPanelSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardPanelSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardPanelKindOrLibraryPanelKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "PanelKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardPanelKind"), + }, + }, + "LibraryPanelKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardLibraryPanelKind"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardLibraryPanelKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardPanelKind"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardPanelQueryKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardPanelQuerySpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardPanelQuerySpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardPanelQuerySpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "query": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataQueryKind"), + }, + }, + "datasource": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataSourceRef"), + }, + }, + "refId": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "hidden": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + Required: []string{"query", "refId", "hidden"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataQueryKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataSourceRef"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardPanelSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "id": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"number"}, + Format: "double", + }, + }, + "title": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "links": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataLink"), + }, + }, + }, + }, + }, + "data": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryGroupKind"), + }, + }, + "vizConfig": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVizConfigKind"), + }, + }, + "transparent": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + Required: []string{"id", "title", "description", "links", "data", "vizConfig"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataLink", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryGroupKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVizConfigKind"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardQueryGroupKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryGroupSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryGroupSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardQueryGroupSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "queries": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardPanelQueryKind"), + }, + }, + }, + }, + }, + "transformations": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTransformationKind"), + }, + }, + }, + }, + }, + "queryOptions": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryOptionsSpec"), + }, + }, + }, + Required: []string{"queries", "transformations", "queryOptions"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardPanelQueryKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryOptionsSpec", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTransformationKind"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardQueryOptionsSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "timeFrom": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "maxDataPoints": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + Format: "int64", + }, + }, + "timeShift": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "queryCachingTTL": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + Format: "int64", + }, + }, + "interval": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "cacheTimeout": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "hideTimeOverride": { + SchemaProps: spec.SchemaProps{ + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardQueryVariableKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Query variable kind", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryVariableSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryVariableSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "QueryVariableKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryVariableKind"), + }, + }, + "TextVariableKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTextVariableKind"), + }, + }, + "ConstantVariableKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardConstantVariableKind"), + }, + }, + "DatasourceVariableKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDatasourceVariableKind"), + }, + }, + "IntervalVariableKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardIntervalVariableKind"), + }, + }, + "CustomVariableKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardCustomVariableKind"), + }, + }, + "GroupByVariableKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGroupByVariableKind"), + }, + }, + "AdhocVariableKind": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAdhocVariableKind"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAdhocVariableKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardConstantVariableKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardCustomVariableKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDatasourceVariableKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGroupByVariableKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardIntervalVariableKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryVariableKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTextVariableKind"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardQueryVariableSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Query variable specification", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "current": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"), + }, + }, + "label": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "hide": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "refresh": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "skipUrlSync": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "datasource": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataSourceRef"), + }, + }, + "query": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataQueryKind"), + }, + }, + "regex": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "sort": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "definition": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "options": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"), + }, + }, + }, + }, + }, + "multi": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "includeAll": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "allValue": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "placeholder": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name", "current", "hide", "refresh", "skipUrlSync", "query", "regex", "sort", "options", "multi", "includeAll"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataQueryKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataSourceRef", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardRangeMap(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Maps numerical ranges to a display text and color. For example, if a value is within a certain range, you can configure a range value mapping to display Low or High rather than the number.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "type": { + SchemaProps: spec.SchemaProps{ + Description: "And this is no longer producing valid TS / Go output type: MappingType & \"range\"", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "options": { + SchemaProps: spec.SchemaProps{ + Description: "Range to match against and the result to apply when the value is within the range", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1RangeMapOptions"), + }, + }, + }, + Required: []string{"type", "options"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1RangeMapOptions"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardRegexMap(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Maps regular expressions to replacement text and a color. For example, if a value is www.example.com, you can configure a regex value mapping so that Grafana displays www and truncates the domain.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "type": { + SchemaProps: spec.SchemaProps{ + Description: "And this is no longer producing valid TS / Go output type: MappingType & \"regex\"", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "options": { + SchemaProps: spec.SchemaProps{ + Description: "Regular expression to match against and the result to apply when the value matches the regex", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1RegexMapOptions"), + }, + }, + }, + Required: []string{"type", "options"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1RegexMapOptions"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardRepeatOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "mode": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "value": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "direction": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "maxPerRow": { + SchemaProps: spec.SchemaProps{ + Type: []string{"integer"}, + Format: "int64", + }, + }, + }, + Required: []string{"mode", "value"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardResponsiveGridLayoutItemKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutItemSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutItemSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardResponsiveGridLayoutItemSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "element": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardElementReference"), + }, + }, + "repeat": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridRepeatOptions"), + }, + }, + }, + Required: []string{"element"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardElementReference", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridRepeatOptions"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardResponsiveGridLayoutKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardResponsiveGridLayoutSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "row": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "col": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutItemKind"), + }, + }, + }, + }, + }, + }, + Required: []string{"row", "col", "items"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardResponsiveGridLayoutItemKind"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardResponsiveGridRepeatOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "mode": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "value": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"mode", "value"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardRowRepeatOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "mode": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "value": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"mode", "value"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardRowsLayoutKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowsLayoutSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowsLayoutSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardRowsLayoutRowKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowsLayoutRowSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowsLayoutRowSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardRowsLayoutRowSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "title": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "collapsed": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "repeat": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowRepeatOptions"), + }, + }, + "layout": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind"), + }, + }, + }, + Required: []string{"collapsed", "layout"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowRepeatOptions"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardRowsLayoutSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "rows": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowsLayoutRowKind"), + }, + }, + }, + }, + }, + }, + Required: []string{"rows"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRowsLayoutRowKind"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "annotations": { + SchemaProps: spec.SchemaProps{ + Description: "Title of dashboard.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAnnotationQueryKind"), + }, + }, + }, + }, + }, + "cursorSync": { + SchemaProps: spec.SchemaProps{ + Description: "Configuration of dashboard cursor sync behavior. \"Off\" for no shared crosshair or tooltip (default). \"Crosshair\" for shared crosshair. \"Tooltip\" for shared crosshair AND shared tooltip.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Description: "Description of dashboard.", + Type: []string{"string"}, + Format: "", + }, + }, + "editable": { + SchemaProps: spec.SchemaProps{ + Description: "Whether a dashboard is editable or not.", + Type: []string{"boolean"}, + Format: "", + }, + }, + "elements": { + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardPanelKindOrLibraryPanelKind"), + }, + }, + }, + }, + }, + "layout": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind"), + }, + }, + "links": { + SchemaProps: spec.SchemaProps{ + Description: "Links with references to other dashboards or external websites.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDashboardLink"), + }, + }, + }, + }, + }, + "liveNow": { + SchemaProps: spec.SchemaProps{ + Description: "When set to true, the dashboard will redraw panels at an interval matching the pixel width. This will keep data \"moving left\" regardless of the query refresh rate. This setting helps avoid dashboards presenting stale live data.", + Type: []string{"boolean"}, + Format: "", + }, + }, + "preload": { + SchemaProps: spec.SchemaProps{ + Description: "When set to true, the dashboard will load all panels in the dashboard when it's loaded.", + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "revision": { + SchemaProps: spec.SchemaProps{ + Description: "Plugins only. The version of the dashboard installed together with the plugin. This is used to determine if the dashboard should be updated when the plugin is updated.", + Type: []string{"integer"}, + Format: "int32", + }, + }, + "tags": { + SchemaProps: spec.SchemaProps{ + Description: "Tags associated with dashboard.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "timeSettings": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTimeSettingsSpec"), + }, + }, + "title": { + SchemaProps: spec.SchemaProps{ + Description: "Title of dashboard.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "variables": { + SchemaProps: spec.SchemaProps{ + Description: "Configured template variables.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind"), + }, + }, + }, + }, + }, + }, + Required: []string{"annotations", "cursorSync", "elements", "layout", "links", "preload", "tags", "timeSettings", "title", "variables"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAnnotationQueryKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDashboardLink", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardPanelKindOrLibraryPanelKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTimeSettingsSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardSpecialValueMap(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color. See SpecialValueMatch to see the list of special values. For example, you can configure a special value mapping so that null values appear as N/A.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "type": { + SchemaProps: spec.SchemaProps{ + Description: "And this is no longer producing valid TS / Go output type: MappingType & \"special\"", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "options": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1SpecialValueMapOptions"), + }, + }, + }, + Required: []string{"type", "options"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardV2alpha1SpecialValueMapOptions"}, + } +} + func schema_pkg_apis_dashboard_v2alpha1_DashboardStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -296,14 +3556,782 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardStatus(ref common.ReferenceCall Properties: map[string]spec.Schema{ "conversion": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.ConversionStatus"), + Description: "Optional conversion status.", + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardConversionStatus"), }, }, }, }, }, Dependencies: []string{ - "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.ConversionStatus"}, + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardConversionStatus"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardStringOrArrayOfString(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "String": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "ArrayOfString": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardStringOrFloat64(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "String": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "Float64": { + SchemaProps: spec.SchemaProps{ + Type: []string{"number"}, + Format: "double", + }, + }, + }, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardTabsLayoutKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTabsLayoutSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTabsLayoutSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardTabsLayoutSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "tabs": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTabsLayoutTabKind"), + }, + }, + }, + }, + }, + }, + Required: []string{"tabs"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTabsLayoutTabKind"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardTabsLayoutTabKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTabsLayoutTabSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTabsLayoutTabSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardTabsLayoutTabSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "title": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "layout": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind"), + }, + }, + }, + Required: []string{"layout"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardTextVariableKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Text variable kind", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTextVariableSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTextVariableSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardTextVariableSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Text variable specification", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "current": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"), + }, + }, + "query": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "label": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "hide": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "skipUrlSync": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name", "current", "query", "hide", "skipUrlSync"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVariableOption"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardThreshold(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "value": { + SchemaProps: spec.SchemaProps{ + Default: 0, + Type: []string{"number"}, + Format: "double", + }, + }, + "color": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"value", "color"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardThresholdsConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "mode": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "steps": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardThreshold"), + }, + }, + }, + }, + }, + }, + Required: []string{"mode", "steps"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardThreshold"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardTimeRangeOption(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "display": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "from": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "to": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"display", "from", "to"}, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardTimeSettingsSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Time configuration It defines the default time config for the time picker, the refresh picker for the specific dashboard.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "timezone": { + SchemaProps: spec.SchemaProps{ + Description: "Timezone of dashboard. Accepted values are IANA TZDB zone ID or \"browser\" or \"utc\".", + Type: []string{"string"}, + Format: "", + }, + }, + "from": { + SchemaProps: spec.SchemaProps{ + Description: "Start time range for dashboard. Accepted values are relative time strings like \"now-6h\" or absolute time strings like \"2020-07-10T08:00:00.000Z\".", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "to": { + SchemaProps: spec.SchemaProps{ + Description: "End time range for dashboard. Accepted values are relative time strings like \"now-6h\" or absolute time strings like \"2020-07-10T08:00:00.000Z\".", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "autoRefresh": { + SchemaProps: spec.SchemaProps{ + Description: "Refresh rate of dashboard. Represented via interval string, e.g. \"5s\", \"1m\", \"1h\", \"1d\". v1: refresh", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "autoRefreshIntervals": { + SchemaProps: spec.SchemaProps{ + Description: "Interval options available in the refresh picker dropdown. v1: timepicker.refresh_intervals", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "quickRanges": { + SchemaProps: spec.SchemaProps{ + Description: "Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard. v1: timepicker.quick_ranges , not exposed in the UI", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTimeRangeOption"), + }, + }, + }, + }, + }, + "hideTimepicker": { + SchemaProps: spec.SchemaProps{ + Description: "Whether timepicker is visible or not. v1: timepicker.hidden", + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "weekStart": { + SchemaProps: spec.SchemaProps{ + Description: "Day when the week starts. Expressed by the name of the day in lowercase, e.g. \"monday\".", + Type: []string{"string"}, + Format: "", + }, + }, + "fiscalYearStartMonth": { + SchemaProps: spec.SchemaProps{ + Description: "The month that the fiscal year starts on. 0 = January, 11 = December", + Default: 0, + Type: []string{"integer"}, + Format: "int64", + }, + }, + "nowDelay": { + SchemaProps: spec.SchemaProps{ + Description: "Override the now time by entering a time delay. Use this option to accommodate known delays in data aggregation to avoid null values. v1: timepicker.nowDelay", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"from", "to", "autoRefresh", "autoRefreshIntervals", "hideTimepicker", "fiscalYearStartMonth"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardTimeRangeOption"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardTransformationKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "The kind of a TransformationKind is the transformation ID", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataTransformerConfig"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDataTransformerConfig"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1FieldConfigSourceOverrides(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "matcher": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardMatcherConfig"), + }, + }, + "properties": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDynamicConfigValue"), + }, + }, + }, + }, + }, + }, + Required: []string{"matcher", "properties"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardDynamicConfigValue", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardMatcherConfig"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1RangeMapOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "from": { + SchemaProps: spec.SchemaProps{ + Description: "Min value of the range. It can be null which means -Infinity", + Type: []string{"number"}, + Format: "double", + }, + }, + "to": { + SchemaProps: spec.SchemaProps{ + Description: "Max value of the range. It can be null which means +Infinity", + Type: []string{"number"}, + Format: "double", + }, + }, + "result": { + SchemaProps: spec.SchemaProps{ + Description: "Config to apply when the value is within the range", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardValueMappingResult"), + }, + }, + }, + Required: []string{"from", "to", "result"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardValueMappingResult"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1RegexMapOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "pattern": { + SchemaProps: spec.SchemaProps{ + Description: "Regular expression to match against", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "result": { + SchemaProps: spec.SchemaProps{ + Description: "Config to apply when the value matches the regex", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardValueMappingResult"), + }, + }, + }, + Required: []string{"pattern", "result"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardValueMappingResult"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardV2alpha1SpecialValueMapOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "match": { + SchemaProps: spec.SchemaProps{ + Description: "Special value to match against", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "result": { + SchemaProps: spec.SchemaProps{ + Description: "Config to apply when the value matches the special value", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardValueMappingResult"), + }, + }, + }, + Required: []string{"match", "result"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardValueMappingResult"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardValueMap(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Maps text values to a color or different display text and color. For example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "type": { + SchemaProps: spec.SchemaProps{ + Description: "And this is no longer producing valid TS / Go output type: MappingType & \"value\"", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "options": { + SchemaProps: spec.SchemaProps{ + Description: "Map with : ValueMappingResult. For example: { \"10\": { text: \"Perfection!\", color: \"green\" } }", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardValueMappingResult"), + }, + }, + }, + }, + }, + }, + Required: []string{"type", "options"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardValueMappingResult"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "ValueMap": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardValueMap"), + }, + }, + "RangeMap": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRangeMap"), + }, + }, + "RegexMap": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRegexMap"), + }, + }, + "SpecialValueMap": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardSpecialValueMap"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRangeMap", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardRegexMap", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardSpecialValueMap", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardValueMap"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardValueMappingResult(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Result used as replacement with text and color when the value matches", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "text": { + SchemaProps: spec.SchemaProps{ + Description: "Text to display when the value matches", + Type: []string{"string"}, + Format: "", + }, + }, + "color": { + SchemaProps: spec.SchemaProps{ + Description: "Text to use when the value matches", + Type: []string{"string"}, + Format: "", + }, + }, + "icon": { + SchemaProps: spec.SchemaProps{ + Description: "Icon to display when the value matches. Only specific visualizations.", + Type: []string{"string"}, + Format: "", + }, + }, + "index": { + SchemaProps: spec.SchemaProps{ + Description: "Position in the mapping array. Only used internally.", + Type: []string{"integer"}, + Format: "int32", + }, + }, + }, + }, + }, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardVariableOption(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Variable option specification", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "selected": { + SchemaProps: spec.SchemaProps{ + Description: "Whether the option is selected or not", + Type: []string{"boolean"}, + Format: "", + }, + }, + "text": { + SchemaProps: spec.SchemaProps{ + Description: "Text to be displayed for the option", + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStringOrArrayOfString"), + }, + }, + "value": { + SchemaProps: spec.SchemaProps{ + Description: "Value of the option", + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStringOrArrayOfString"), + }, + }, + }, + Required: []string{"text", "value"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStringOrArrayOfString"}, } } @@ -404,6 +4432,78 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardVersionList(ref common.Referenc } } +func schema_pkg_apis_dashboard_v2alpha1_DashboardVizConfigKind(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "The kind of a VizConfigKind is the plugin ID", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVizConfigSpec"), + }, + }, + }, + Required: []string{"kind", "spec"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardVizConfigSpec"}, + } +} + +func schema_pkg_apis_dashboard_v2alpha1_DashboardVizConfigSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "--- Kinds ---", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "pluginVersion": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "options": { + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Format: "", + }, + }, + }, + }, + }, + "fieldConfig": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardFieldConfigSource"), + }, + }, + }, + Required: []string{"pluginVersion", "options", "fieldConfig"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardFieldConfigSource"}, + } +} + func schema_pkg_apis_dashboard_v2alpha1_DashboardWithAccessInfo(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -427,21 +4527,21 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardWithAccessInfo(ref common.Refer }, "metadata": { SchemaProps: spec.SchemaProps{ - Description: "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), }, }, "spec": { SchemaProps: spec.SchemaProps{ - Description: "The dashboard body (unstructured for now)", - Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured"), + Description: "Spec is the spec of the Dashboard", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardSpec"), }, }, "status": { SchemaProps: spec.SchemaProps{ - Description: "Optional dashboard status", - Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStatus"), + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStatus"), }, }, "access": { @@ -451,11 +4551,11 @@ func schema_pkg_apis_dashboard_v2alpha1_DashboardWithAccessInfo(ref common.Refer }, }, }, - Required: []string{"spec", "access"}, + Required: []string{"metadata", "spec", "status", "access"}, }, }, Dependencies: []string{ - "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.Unstructured", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAccess", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardAccess", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardSpec", "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1.DashboardStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, } } diff --git a/pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list b/pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list index 0683c758ce4..4914dd6343d 100644 --- a/pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list +++ b/pkg/apis/dashboard/v2alpha1/zz_generated.openapi_violation_exceptions.list @@ -1,2 +1,65 @@ +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardAdHocFilterWithLabels,ValueLabels +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardAdHocFilterWithLabels,Values +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardAdhocVariableSpec,BaseFilters +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardAdhocVariableSpec,DefaultKeys +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardAdhocVariableSpec,Filters +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardCustomVariableSpec,Options +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardDashboardLink,Tags +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardDatasourceVariableSpec,Options +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardFieldConfig,Links +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardFieldConfig,Mappings +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardFieldConfigSource,Overrides +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutRowSpec,Elements +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutSpec,Items +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardGroupByVariableSpec,Options +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardIntervalVariableSpec,Options +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardMetadata,Finalizers +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardPanelSpec,Links +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardQueryGroupSpec,Queries +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardQueryGroupSpec,Transformations +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardQueryVariableSpec,Options +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardResponsiveGridLayoutSpec,Items +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardRowsLayoutSpec,Rows +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardSpec,Annotations +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardSpec,Links +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardSpec,Tags +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardSpec,Variables +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardStringOrArrayOfString,ArrayOfString +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardTabsLayoutSpec,Tabs +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardThresholdsConfig,Steps +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardTimeSettingsSpec,AutoRefreshIntervals +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardTimeSettingsSpec,QuickRanges +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardV2alpha1FieldConfigSourceOverrides,Properties API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,LibraryPanelStatus,Warnings -API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardStatus,ConversionStatus +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutItemKindOrGridLayoutRowKind,GridLayoutItemKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutItemKindOrGridLayoutRowKind,GridLayoutRowKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind,GridLayoutKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind,ResponsiveGridLayoutKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind,TabsLayoutKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind,GridLayoutKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind,ResponsiveGridLayoutKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKind,RowsLayoutKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind,GridLayoutKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind,ResponsiveGridLayoutKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind,RowsLayoutKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardGridLayoutKindOrRowsLayoutKindOrResponsiveGridLayoutKindOrTabsLayoutKind,TabsLayoutKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardIntervalVariableSpec,AutoCount +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardIntervalVariableSpec,AutoMin +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardPanelKindOrLibraryPanelKind,LibraryPanelKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardPanelKindOrLibraryPanelKind,PanelKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind,AdhocVariableKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind,ConstantVariableKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind,CustomVariableKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind,DatasourceVariableKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind,GroupByVariableKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind,IntervalVariableKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind,QueryVariableKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardQueryVariableKindOrTextVariableKindOrConstantVariableKindOrDatasourceVariableKindOrIntervalVariableKindOrCustomVariableKindOrGroupByVariableKindOrAdhocVariableKind,TextVariableKind +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardStringOrArrayOfString,ArrayOfString +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardStringOrArrayOfString,String +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardStringOrFloat64,Float64 +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardStringOrFloat64,String +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap,RangeMap +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap,RegexMap +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap,SpecialValueMap +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1,DashboardValueMapOrRangeMapOrRegexMapOrSpecialValueMap,ValueMap diff --git a/pkg/apis/dashboard_manifest.go b/pkg/apis/dashboard_manifest.go new file mode 100644 index 00000000000..bc68fa86ca6 --- /dev/null +++ b/pkg/apis/dashboard_manifest.go @@ -0,0 +1,53 @@ +// +// This file is generated by grafana-app-sdk +// DO NOT EDIT +// + +package apis + +import ( + "encoding/json" + + "github.com/grafana/grafana-app-sdk/app" +) + +var () + +var appManifestData = app.ManifestData{ + AppName: "dashboard", + Group: "dashboard.grafana.app", + Kinds: []app.ManifestKind{ + { + Kind: "Dashboard", + Scope: "Namespaced", + Conversion: false, + Versions: []app.ManifestKindVersion{ + { + Name: "v0alpha1", + }, + + { + Name: "v1alpha1", + }, + + { + Name: "v2alpha1", + }, + }, + }, + }, +} + +func jsonToMap(j string) map[string]any { + m := make(map[string]any) + json.Unmarshal([]byte(j), &j) + return m +} + +func LocalManifest() app.Manifest { + return app.NewEmbeddedManifest(appManifestData) +} + +func RemoteManifest() app.Manifest { + return app.NewAPIServerManifest("dashboard") +} diff --git a/pkg/registry/apis/dashboard/large.go b/pkg/registry/apis/dashboard/large.go index 6594145f88d..5464d479dd6 100644 --- a/pkg/registry/apis/dashboard/large.go +++ b/pkg/registry/apis/dashboard/large.go @@ -1,6 +1,7 @@ package dashboard import ( + "encoding/json" "fmt" "k8s.io/apimachinery/pkg/runtime" @@ -35,7 +36,11 @@ func NewDashboardLargeObjectSupport(scheme *runtime.Scheme) *apistore.BasicLarge case *dashboardV1.Dashboard: reduceUnstructredSpec(&dash.Spec) case *dashboardV2.Dashboard: - reduceUnstructredSpec(&dash.Spec) + dash.Spec = dashboardV2.DashboardSpec{ + Title: dash.Spec.Title, + Description: dash.Spec.Description, + Tags: dash.Spec.Tags, + } default: return fmt.Errorf("unsupported dashboard type %T", obj) } @@ -45,23 +50,16 @@ func NewDashboardLargeObjectSupport(scheme *runtime.Scheme) *apistore.BasicLarge }, RebuildSpec: func(obj runtime.Object, blob []byte) error { - body := commonV0.Unstructured{} - err := body.UnmarshalJSON(blob) - if err != nil { - return err - } - switch dash := obj.(type) { case *dashboardV0.Dashboard: - dash.Spec = body + return dash.Spec.UnmarshalJSON(blob) case *dashboardV1.Dashboard: - dash.Spec = body + return dash.Spec.UnmarshalJSON(blob) case *dashboardV2.Dashboard: - dash.Spec = body + return json.Unmarshal(blob, &dash.Spec) default: return fmt.Errorf("unsupported dashboard type %T", obj) } - return nil }, } } diff --git a/pkg/registry/apis/dashboard/mutate.go b/pkg/registry/apis/dashboard/mutate.go index c000204744b..560dcfbedba 100644 --- a/pkg/registry/apis/dashboard/mutate.go +++ b/pkg/registry/apis/dashboard/mutate.go @@ -38,10 +38,7 @@ func (b *DashboardsAPIBuilder) Mutate(ctx context.Context, a admission.Attribute internalID = int64(id) } case *dashboardV2.Dashboard: - if id, ok := v.Spec.Object["id"].(float64); ok { - delete(v.Spec.Object, "id") - internalID = int64(id) - } + // Noop for V2 default: return fmt.Errorf("mutation error: expected to dashboard, got %T", obj) } diff --git a/pkg/registry/apis/dashboard/register.go b/pkg/registry/apis/dashboard/register.go index cedda8820ff..9c750e605a9 100644 --- a/pkg/registry/apis/dashboard/register.go +++ b/pkg/registry/apis/dashboard/register.go @@ -109,6 +109,16 @@ func RegisterAPIService( } func (b *DashboardsAPIBuilder) GetGroupVersions() []schema.GroupVersion { + if featuremgmt.AnyEnabled(b.features, featuremgmt.FlagUseV2DashboardsAPI) { + // If dashboards v2 is enabled, we want to use v2alpha1 as the default API version. + return []schema.GroupVersion{ + dashboardv2alpha1.DashboardResourceInfo.GroupVersion(), + dashboardv0alpha1.DashboardResourceInfo.GroupVersion(), + dashboardv1alpha1.DashboardResourceInfo.GroupVersion(), + } + } + + // TODO (@radiohead): should we switch to v1alpha1 by default? return []schema.GroupVersion{ dashboardv0alpha1.DashboardResourceInfo.GroupVersion(), dashboardv1alpha1.DashboardResourceInfo.GroupVersion(), diff --git a/pkg/registry/apis/dashboard/register_test.go b/pkg/registry/apis/dashboard/register_test.go index d218c0727c6..80b1dd28665 100644 --- a/pkg/registry/apis/dashboard/register_test.go +++ b/pkg/registry/apis/dashboard/register_test.go @@ -7,11 +7,15 @@ import ( common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1" "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" + "github.com/grafana/grafana/pkg/apis/dashboard/v1alpha1" + "github.com/grafana/grafana/pkg/apis/dashboard/v2alpha1" "github.com/grafana/grafana/pkg/services/dashboards" + "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/user" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/admission" ) @@ -158,3 +162,93 @@ func TestDashboardAPIBuilder_Validate(t *testing.T) { }) } } + +func TestDashboardAPIBuilder_GetGroupVersions(t *testing.T) { + tests := []struct { + name string + enabledFeatures []string + expected []schema.GroupVersion + }{ + { + name: "should return v0alpha1 by default", + enabledFeatures: []string{}, + expected: []schema.GroupVersion{ + v0alpha1.DashboardResourceInfo.GroupVersion(), + v1alpha1.DashboardResourceInfo.GroupVersion(), + v2alpha1.DashboardResourceInfo.GroupVersion(), + }, + }, + { + name: "should return v0alpha1 as the default if some other feature is enabled", + enabledFeatures: []string{ + featuremgmt.FlagKubernetesDashboards, + }, + expected: []schema.GroupVersion{ + v0alpha1.DashboardResourceInfo.GroupVersion(), + v1alpha1.DashboardResourceInfo.GroupVersion(), + v2alpha1.DashboardResourceInfo.GroupVersion(), + }, + }, + { + name: "should return v2alpha1 as the default if dashboards v2 is enabled", + enabledFeatures: []string{ + featuremgmt.FlagUseV2DashboardsAPI, + }, + expected: []schema.GroupVersion{ + v2alpha1.DashboardResourceInfo.GroupVersion(), + v0alpha1.DashboardResourceInfo.GroupVersion(), + v1alpha1.DashboardResourceInfo.GroupVersion(), + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + builder := &DashboardsAPIBuilder{ + features: newMockFeatureToggles(t, tt.enabledFeatures...), + } + + require.Equal(t, tt.expected, builder.GetGroupVersions()) + }) + } +} + +type mockFeatureToggles struct { + // We need to make a copy in `GetEnabled` anyway, + // so no need to store the original map as map[string]bool. + enabledFeatures map[string]struct{} +} + +func newMockFeatureToggles(t *testing.T, enabledFeatures ...string) featuremgmt.FeatureToggles { + t.Helper() + + res := &mockFeatureToggles{ + enabledFeatures: make(map[string]struct{}, len(enabledFeatures)), + } + + for _, f := range enabledFeatures { + res.enabledFeatures[f] = struct{}{} + } + + return res +} + +func (m *mockFeatureToggles) IsEnabledGlobally(feature string) bool { + _, ok := m.enabledFeatures[feature] + return ok +} + +func (m *mockFeatureToggles) IsEnabled(ctx context.Context, feature string) bool { + _, ok := m.enabledFeatures[feature] + return ok +} + +func (m *mockFeatureToggles) GetEnabled(ctx context.Context) map[string]bool { + res := make(map[string]bool, len(m.enabledFeatures)) + + for f := range m.enabledFeatures { + res[f] = true + } + + return res +} diff --git a/pkg/storage/unified/apistore/go.mod b/pkg/storage/unified/apistore/go.mod index 68d9aceafbc..6c377348ee0 100644 --- a/pkg/storage/unified/apistore/go.mod +++ b/pkg/storage/unified/apistore/go.mod @@ -207,6 +207,7 @@ require ( github.com/grafana/authlib v0.0.0-20250305132846-37f49eb947fa // indirect github.com/grafana/dataplane/sdata v0.0.9 // indirect github.com/grafana/dskit v0.0.0-20241105154643-a6b453a88040 // indirect + github.com/grafana/grafana-app-sdk v0.31.0 // indirect github.com/grafana/grafana-app-sdk/logging v0.30.0 // indirect github.com/grafana/grafana-aws-sdk v0.31.5 // indirect github.com/grafana/grafana-azure-sdk-go/v2 v2.1.6 // indirect diff --git a/pkg/storage/unified/apistore/go.sum b/pkg/storage/unified/apistore/go.sum index 2a54e8f0a54..1b5e473ad53 100644 --- a/pkg/storage/unified/apistore/go.sum +++ b/pkg/storage/unified/apistore/go.sum @@ -1265,6 +1265,8 @@ github.com/grafana/dataplane/sdata v0.0.9 h1:AGL1LZnCUG4MnQtnWpBPbQ8ZpptaZs14w6k github.com/grafana/dataplane/sdata v0.0.9/go.mod h1:Jvs5ddpGmn6vcxT7tCTWAZ1mgi4sbcdFt9utQx5uMAU= github.com/grafana/dskit v0.0.0-20241105154643-a6b453a88040 h1:IR+UNYHqaU31t8/TArJk8K/GlDwOyxMpGNkWCXeZ28g= github.com/grafana/dskit v0.0.0-20241105154643-a6b453a88040/go.mod h1:SPLNCARd4xdjCkue0O6hvuoveuS1dGJjDnfxYe405YQ= +github.com/grafana/grafana-app-sdk v0.31.0 h1:/mFCcx+YqG8cWAi9hePDJQxIdtXDClDIDRgZwHkksFk= +github.com/grafana/grafana-app-sdk v0.31.0/go.mod h1:Xw00NL7qpRLo5r3Gn48Bl1Xn2n4eUDI5pYf/wMufKWs= github.com/grafana/grafana-app-sdk/logging v0.30.0 h1:K/P/bm7Cp7Di4tqIJ3EQz2+842JozQGRaz62r95ApME= github.com/grafana/grafana-app-sdk/logging v0.30.0/go.mod h1:xy6ZyVXl50Z3DBDLybvBPphbykPhuVNed/VNmen9DQM= github.com/grafana/grafana-aws-sdk v0.31.5 h1:4HpMQx7n4Qqoi7Bgu8KHQ2QKT9fYYdHilX/Gh3FZKBE= diff --git a/pkg/storage/unified/resource/go.mod b/pkg/storage/unified/resource/go.mod index 0a5d4a68146..bc891b4aa28 100644 --- a/pkg/storage/unified/resource/go.mod +++ b/pkg/storage/unified/resource/go.mod @@ -133,6 +133,7 @@ require ( github.com/gorilla/mux v1.8.1 // indirect github.com/grafana/alerting v0.0.0-20250310104713-16b885f1c79e // indirect github.com/grafana/dataplane/sdata v0.0.9 // indirect + github.com/grafana/grafana-app-sdk v0.31.0 // indirect github.com/grafana/grafana-app-sdk/logging v0.30.0 // indirect github.com/grafana/grafana-aws-sdk v0.31.5 // indirect github.com/grafana/grafana-azure-sdk-go/v2 v2.1.6 // indirect @@ -214,7 +215,6 @@ require ( github.com/tjhop/slog-gokit v0.1.3 // indirect github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect - github.com/ugorji/go/codec v1.2.11 // indirect github.com/unknwon/bra v0.0.0-20200517080246-1e3013ecaff8 // indirect github.com/unknwon/com v1.0.1 // indirect github.com/unknwon/log v0.0.0-20200308114134-929b1006e34a // indirect diff --git a/pkg/storage/unified/resource/go.sum b/pkg/storage/unified/resource/go.sum index aef2f25aee9..b7a7baddf76 100644 --- a/pkg/storage/unified/resource/go.sum +++ b/pkg/storage/unified/resource/go.sum @@ -1160,6 +1160,8 @@ github.com/grafana/dataplane/sdata v0.0.9 h1:AGL1LZnCUG4MnQtnWpBPbQ8ZpptaZs14w6k github.com/grafana/dataplane/sdata v0.0.9/go.mod h1:Jvs5ddpGmn6vcxT7tCTWAZ1mgi4sbcdFt9utQx5uMAU= github.com/grafana/dskit v0.0.0-20241105154643-a6b453a88040 h1:IR+UNYHqaU31t8/TArJk8K/GlDwOyxMpGNkWCXeZ28g= github.com/grafana/dskit v0.0.0-20241105154643-a6b453a88040/go.mod h1:SPLNCARd4xdjCkue0O6hvuoveuS1dGJjDnfxYe405YQ= +github.com/grafana/grafana-app-sdk v0.31.0 h1:/mFCcx+YqG8cWAi9hePDJQxIdtXDClDIDRgZwHkksFk= +github.com/grafana/grafana-app-sdk v0.31.0/go.mod h1:Xw00NL7qpRLo5r3Gn48Bl1Xn2n4eUDI5pYf/wMufKWs= github.com/grafana/grafana-app-sdk/logging v0.30.0 h1:K/P/bm7Cp7Di4tqIJ3EQz2+842JozQGRaz62r95ApME= github.com/grafana/grafana-app-sdk/logging v0.30.0/go.mod h1:xy6ZyVXl50Z3DBDLybvBPphbykPhuVNed/VNmen9DQM= github.com/grafana/grafana-aws-sdk v0.31.5 h1:4HpMQx7n4Qqoi7Bgu8KHQ2QKT9fYYdHilX/Gh3FZKBE= diff --git a/pkg/tests/apis/dashboard/testdata/dashboard-test-v2.yaml b/pkg/tests/apis/dashboard/testdata/dashboard-test-v2.yaml index 1f9efaa0579..540b9dcc919 100644 --- a/pkg/tests/apis/dashboard/testdata/dashboard-test-v2.yaml +++ b/pkg/tests/apis/dashboard/testdata/dashboard-test-v2.yaml @@ -4,3 +4,7 @@ metadata: name: test-v2 spec: title: Test dashboard. Created at v2 + layout: + kind: GridLayout + spec: + items: [] diff --git a/pkg/tests/apis/openapi_snapshots/dashboard.grafana.app-v0alpha1.json b/pkg/tests/apis/openapi_snapshots/dashboard.grafana.app-v0alpha1.json index b0f2258cb24..eec30bc3008 100644 --- a/pkg/tests/apis/openapi_snapshots/dashboard.grafana.app-v0alpha1.json +++ b/pkg/tests/apis/openapi_snapshots/dashboard.grafana.app-v0alpha1.json @@ -1490,24 +1490,12 @@ } } }, - "com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.ConversionStatus": { - "type": "object", - "properties": { - "error": { - "type": "string" - }, - "failed": { - "type": "boolean" - }, - "storedVersion": { - "type": "string" - } - } - }, "com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.Dashboard": { "type": "object", "required": [ - "spec" + "metadata", + "spec", + "status" ], "properties": { "apiVersion": { @@ -1519,7 +1507,6 @@ "type": "string" }, "metadata": { - "description": "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", "default": {}, "allOf": [ { @@ -1528,7 +1515,7 @@ ] }, "spec": { - "description": "The dashboard body (unstructured for now)", + "description": "Spec is the spec of the Dashboard", "allOf": [ { "$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apimachinery.apis.common.v0alpha1.Unstructured" @@ -1536,7 +1523,7 @@ ] }, "status": { - "description": "Optional dashboard status", + "default": {}, "allOf": [ { "$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.DashboardStatus" @@ -1553,7 +1540,6 @@ ] }, "com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.DashboardAccess": { - "description": "Information about how the requesting user can use a given dashboard", "type": "object", "required": [ "canSave", @@ -1597,8 +1583,38 @@ } } }, + "com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.DashboardConversionStatus": { + "description": "ConversionStatus is the status of the conversion of the dashboard.", + "type": "object", + "required": [ + "failed", + "storedVersion", + "error" + ], + "properties": { + "error": { + "description": "The error message from the conversion. Empty if the conversion has not failed.", + "type": "string", + "default": "" + }, + "failed": { + "description": "Whether from another version has failed. If true, means that the dashboard is not valid, and the caller should instead fetch the stored version.", + "type": "boolean", + "default": false + }, + "storedVersion": { + "description": "The version which was stored when the dashboard was created / updated. Fetching this version should always succeed.", + "type": "string", + "default": "" + } + } + }, "com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.DashboardList": { "type": "object", + "required": [ + "metadata", + "items" + ], "properties": { "apiVersion": { "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", @@ -1640,7 +1656,12 @@ "type": "object", "properties": { "conversion": { - "$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.ConversionStatus" + "description": "Optional conversion status.", + "allOf": [ + { + "$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.DashboardConversionStatus" + } + ] } } }, @@ -1648,7 +1669,9 @@ "description": "This is like the legacy DTO where access and metadata are all returned in a single call", "type": "object", "required": [ + "metadata", "spec", + "status", "access" ], "properties": { @@ -1669,7 +1692,6 @@ "type": "string" }, "metadata": { - "description": "Standard object's metadata More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata", "default": {}, "allOf": [ { @@ -1678,7 +1700,7 @@ ] }, "spec": { - "description": "The dashboard body (unstructured for now)", + "description": "Spec is the spec of the Dashboard", "allOf": [ { "$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apimachinery.apis.common.v0alpha1.Unstructured" @@ -1686,7 +1708,7 @@ ] }, "status": { - "description": "Optional dashboard status", + "default": {}, "allOf": [ { "$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apis.dashboard.v0alpha1.DashboardStatus" diff --git a/public/api-merged.json b/public/api-merged.json index 130059510ae..873200a1fb7 100644 --- a/public/api-merged.json +++ b/public/api-merged.json @@ -13055,6 +13055,7 @@ } }, "AnnotationActions": { + "description": "+k8s:deepcopy-gen=true", "type": "object", "properties": { "canAdd": { @@ -13129,6 +13130,7 @@ } }, "AnnotationPermission": { + "description": "+k8s:deepcopy-gen=true", "type": "object", "properties": { "dashboard": { diff --git a/public/openapi3.json b/public/openapi3.json index d791ee2bb10..9d4c63135c3 100644 --- a/public/openapi3.json +++ b/public/openapi3.json @@ -3118,6 +3118,7 @@ "type": "object" }, "AnnotationActions": { + "description": "+k8s:deepcopy-gen=true", "properties": { "canAdd": { "type": "boolean" @@ -3192,6 +3193,7 @@ "type": "object" }, "AnnotationPermission": { + "description": "+k8s:deepcopy-gen=true", "properties": { "dashboard": { "$ref": "#/components/schemas/AnnotationActions" From b4366db1f13271a58f09f02a08c2150ef123017b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torkel=20=C3=96degaard?= Date: Tue, 11 Mar 2025 12:03:10 +0100 Subject: [PATCH 35/63] ThemeDrawer: Change theme from anywhere and preview them (#100405) * ThemeDrawer: Change theme from anywhere and preview them * Update * added subtitle * Use new component * Fixes * Fix runtime ony wrong prop * Fixed saving issue * update lang file * Fixed circular dep * fix import --- packages/grafana-data/src/types/config.ts | 1 + pkg/api/dtos/frontend_settings.go | 1 + pkg/api/frontendsettings.go | 1 + pkg/services/navtree/navtreeimpl/navtree.go | 12 -- .../components/AppChrome/MegaMenu/utils.ts | 2 +- .../AppChrome/TopBar/ProfileButton.tsx | 24 +++- .../AppChrome/TopBar/SingleTopBar.tsx | 3 +- .../SharedPreferences/SharedPreferences.tsx | 21 +-- .../ThemeSelector/ThemeSelectorDrawer.tsx | 121 ++++++++++++++++++ .../ThemeSelector/getSelectableThemes.ts | 20 +++ public/app/core/constants.ts | 1 + public/app/core/services/theme.ts | 2 +- public/locales/en-US/grafana.json | 3 +- 13 files changed, 175 insertions(+), 37 deletions(-) create mode 100644 public/app/core/components/ThemeSelector/ThemeSelectorDrawer.tsx create mode 100644 public/app/core/components/ThemeSelector/getSelectableThemes.ts diff --git a/packages/grafana-data/src/types/config.ts b/packages/grafana-data/src/types/config.ts index 4e57dd61656..6cec302e4b4 100644 --- a/packages/grafana-data/src/types/config.ts +++ b/packages/grafana-data/src/types/config.ts @@ -284,4 +284,5 @@ export interface AuthSettings { disableLogin?: boolean; passwordlessEnabled?: boolean; basicAuthStrongPasswordPolicy?: boolean; + disableSignoutMenu?: boolean; } diff --git a/pkg/api/dtos/frontend_settings.go b/pkg/api/dtos/frontend_settings.go index a9581366b13..9ed646941d6 100644 --- a/pkg/api/dtos/frontend_settings.go +++ b/pkg/api/dtos/frontend_settings.go @@ -34,6 +34,7 @@ type FrontendSettingsAuthDTO struct { DisableLogin bool `json:"disableLogin"` BasicAuthStrongPasswordPolicy bool `json:"basicAuthStrongPasswordPolicy"` PasswordlessEnabled bool `json:"passwordlessEnabled"` + DisableSignoutMenu bool `json:"disableSignoutMenu"` } type FrontendSettingsBuildInfoDTO struct { diff --git a/pkg/api/frontendsettings.go b/pkg/api/frontendsettings.go index ba0f2f436bd..0993e086edb 100644 --- a/pkg/api/frontendsettings.go +++ b/pkg/api/frontendsettings.go @@ -367,6 +367,7 @@ func (hs *HTTPServer) getFrontendSettings(c *contextmodel.ReqContext) (*dtos.Fro OktaSkipOrgRoleSync: parseSkipOrgRoleSyncEnabled(oauthProviders[social.OktaProviderName]), DisableLogin: hs.Cfg.DisableLogin, BasicAuthStrongPasswordPolicy: hs.Cfg.BasicAuthStrongPasswordPolicy, + DisableSignoutMenu: hs.Cfg.DisableSignoutMenu, } if hs.Cfg.PasswordlessMagicLinkAuth.Enabled && hs.Features.IsEnabled(c.Req.Context(), featuremgmt.FlagPasswordlessMagicLinkAuthentication) { diff --git a/pkg/services/navtree/navtreeimpl/navtree.go b/pkg/services/navtree/navtreeimpl/navtree.go index d84240556f8..facf246f171 100644 --- a/pkg/services/navtree/navtreeimpl/navtree.go +++ b/pkg/services/navtree/navtreeimpl/navtree.go @@ -296,18 +296,6 @@ func (s *ServiceImpl) getProfileNode(c *contextmodel.ReqContext) *navtree.NavLin }) } - if !s.cfg.DisableSignoutMenu { - // add sign out first - children = append(children, &navtree.NavLink{ - Text: "Sign out", - Id: "sign-out", - Url: s.cfg.AppSubURL + "/logout", - Icon: "arrow-from-right", - Target: "_self", - HideFromTabs: true, - }) - } - return &navtree.NavLink{ Text: c.SignedInUser.GetName(), SubTitle: login, diff --git a/public/app/core/components/AppChrome/MegaMenu/utils.ts b/public/app/core/components/AppChrome/MegaMenu/utils.ts index 2afb61f8cc4..178d6604dca 100644 --- a/public/app/core/components/AppChrome/MegaMenu/utils.ts +++ b/public/app/core/components/AppChrome/MegaMenu/utils.ts @@ -2,6 +2,7 @@ import { useEffect } from 'react'; import { NavModelItem } from '@grafana/data'; import { config, reportInteraction } from '@grafana/runtime'; +import { MEGA_MENU_TOGGLE_ID } from 'app/core/constants'; import { t } from 'app/core/internationalization'; import { HOME_NAV_ID } from 'app/core/reducers/navModel'; @@ -9,7 +10,6 @@ import { ShowModalReactEvent } from '../../../../types/events'; import appEvents from '../../../app_events'; import { getFooterLinks } from '../../Footer/Footer'; import { HelpModal } from '../../help/HelpModal'; -import { MEGA_MENU_TOGGLE_ID } from '../TopBar/SingleTopBar'; import { DOCK_MENU_BUTTON_ID, MEGA_MENU_HEADER_TOGGLE_ID } from './MegaMenuHeader'; diff --git a/public/app/core/components/AppChrome/TopBar/ProfileButton.tsx b/public/app/core/components/AppChrome/TopBar/ProfileButton.tsx index 3faa5f24876..937a1fd0f2c 100644 --- a/public/app/core/components/AppChrome/TopBar/ProfileButton.tsx +++ b/public/app/core/components/AppChrome/TopBar/ProfileButton.tsx @@ -8,6 +8,7 @@ import { Dropdown, Menu, MenuItem, ToolbarButton, useStyles2 } from '@grafana/ui import { contextSrv } from 'app/core/core'; import { t } from 'app/core/internationalization'; +import { ThemeSelectorDrawer } from '../../ThemeSelector/ThemeSelectorDrawer'; import { enrichWithInteractionTracking } from '../MegaMenu/utils'; import { NewsContainer } from '../News/NewsDrawer'; @@ -21,6 +22,7 @@ export function ProfileButton({ profileNode }: Props) { const styles = useStyles2(getStyles); const node = enrichWithInteractionTracking(cloneDeep(profileNode), false); const [showNewsDrawer, onToggleShowNewsDrawer] = useToggle(false); + const [showThemeDrawer, onToggleThemeDrawer] = useToggle(false); if (!node) { return null; @@ -28,16 +30,27 @@ export function ProfileButton({ profileNode }: Props) { const renderMenu = () => ( - {config.newsFeedEnabled && ( - <> - + <> + {config.featureToggles.grafanaconThemes && ( + + )} + {config.newsFeedEnabled && ( - - )} + )} + + {!config.auth.disableSignoutMenu && ( + + )} + ); @@ -52,6 +65,7 @@ export function ProfileButton({ profileNode }: Props) { /> {showNewsDrawer && } + {showThemeDrawer && } ); } diff --git a/public/app/core/components/AppChrome/TopBar/SingleTopBar.tsx b/public/app/core/components/AppChrome/TopBar/SingleTopBar.tsx index 64d67fa326d..01ba7281c20 100644 --- a/public/app/core/components/AppChrome/TopBar/SingleTopBar.tsx +++ b/public/app/core/components/AppChrome/TopBar/SingleTopBar.tsx @@ -5,6 +5,7 @@ import { memo } from 'react'; import { GrafanaTheme2, NavModelItem } from '@grafana/data'; import { Dropdown, Icon, Stack, ToolbarButton, useStyles2 } from '@grafana/ui'; import { config } from 'app/core/config'; +import { MEGA_MENU_TOGGLE_ID } from 'app/core/constants'; import { useGrafana } from 'app/core/context/GrafanaContext'; import { contextSrv } from 'app/core/core'; import { t } from 'app/core/internationalization'; @@ -25,8 +26,6 @@ import { SignInLink } from './SignInLink'; import { TopNavBarMenu } from './TopNavBarMenu'; import { TopSearchBarCommandPaletteTrigger } from './TopSearchBarCommandPaletteTrigger'; -export const MEGA_MENU_TOGGLE_ID = 'mega-menu-toggle'; - interface Props { sectionNav: NavModelItem; pageNav?: NavModelItem; diff --git a/public/app/core/components/SharedPreferences/SharedPreferences.tsx b/public/app/core/components/SharedPreferences/SharedPreferences.tsx index dcc1a250133..fcac1bdeefb 100644 --- a/public/app/core/components/SharedPreferences/SharedPreferences.tsx +++ b/public/app/core/components/SharedPreferences/SharedPreferences.tsx @@ -2,7 +2,7 @@ import { css } from '@emotion/css'; import { PureComponent } from 'react'; import * as React from 'react'; -import { FeatureState, getBuiltInThemes, ThemeRegistryItem } from '@grafana/data'; +import { FeatureState, ThemeRegistryItem } from '@grafana/data'; import { selectors } from '@grafana/e2e-selectors'; import { config, reportInteraction } from '@grafana/runtime'; import { Preferences as UserPreferencesDTO } from '@grafana/schema/src/raw/preferences/x/preferences_types.gen'; @@ -26,6 +26,9 @@ import { t, Trans } from 'app/core/internationalization'; import { LANGUAGES, PSEUDO_LOCALE } from 'app/core/internationalization/constants'; import { PreferencesService } from 'app/core/services/PreferencesService'; import { changeTheme } from 'app/core/services/theme'; + +import { getSelectableThemes } from '../ThemeSelector/getSelectableThemes'; + export interface Props { resourceUri: string; disabled?: boolean; @@ -82,21 +85,9 @@ export class SharedPreferences extends PureComponent { navbar: { bookmarkUrls: [] }, }; - const allowedExtraThemes = []; + const themes = getSelectableThemes(); - if (config.featureToggles.extraThemes) { - allowedExtraThemes.push('debug'); - } - - if (config.featureToggles.grafanaconThemes) { - allowedExtraThemes.push('desertbloom'); - allowedExtraThemes.push('gildedgrove'); - allowedExtraThemes.push('sapphiredusk'); - allowedExtraThemes.push('tron'); - allowedExtraThemes.push('gloom'); - } - - this.themeOptions = getBuiltInThemes(allowedExtraThemes).map((theme) => ({ + this.themeOptions = themes.map((theme) => ({ value: theme.id, label: getTranslatedThemeName(theme), })); diff --git a/public/app/core/components/ThemeSelector/ThemeSelectorDrawer.tsx b/public/app/core/components/ThemeSelector/ThemeSelectorDrawer.tsx new file mode 100644 index 00000000000..bc3de6ce4d7 --- /dev/null +++ b/public/app/core/components/ThemeSelector/ThemeSelectorDrawer.tsx @@ -0,0 +1,121 @@ +import { css } from '@emotion/css'; + +import { GrafanaTheme2, ThemeRegistryItem } from '@grafana/data'; +import { Drawer, RadioButtonDot, TextLink, useStyles2, useTheme2 } from '@grafana/ui'; +import { t, Trans } from 'app/core/internationalization'; +import { changeTheme } from 'app/core/services/theme'; + +import { ThemePreview } from '../Theme/ThemePreview'; + +import { getSelectableThemes } from './getSelectableThemes'; + +interface Props { + onClose: () => void; +} + +export function ThemeSelectorDrawer({ onClose }: Props) { + const styles = useStyles2(getStyles); + const themes = getSelectableThemes(); + const currentTheme = useTheme2(); + + const onChange = (theme: ThemeRegistryItem) => { + changeTheme(theme.id, false); + }; + + const subTitle = ( + + Enjoying the limited edition themes? Tell us what you'd like to see{' '} + + here. + + + ); + + return ( + +
+ {themes.map((themeOption) => ( + onChange(themeOption)} + isSelected={currentTheme.name === themeOption.name} + /> + ))} +
+
+ ); +} + +interface ThemeCardProps { + themeOption: ThemeRegistryItem; + isSelected?: boolean; + onSelect: () => void; +} + +function ThemeCard({ themeOption, isSelected, onSelect }: ThemeCardProps) { + const theme = themeOption.build(); + const label = getTranslatedThemeName(themeOption); + const styles = useStyles2(getStyles); + + return ( +
+
+ +
+ +
+ ); +} + +const getStyles = (theme: GrafanaTheme2) => { + return { + grid: css({ + display: 'grid', + gridTemplateColumns: 'repeat(auto-fit, minmax(300px, 1fr))', + gridAutoRows: `250px`, + gap: theme.spacing(2), + }), + card: css({ + border: `1px solid ${theme.colors.border.weak}`, + borderRadius: theme.shape.radius.default, + display: 'flex', + flexDirection: 'column', + cursor: 'pointer', + '&:hover': { + border: `1px solid ${theme.colors.border.medium}`, + }, + }), + header: css({ + borderBottom: `1px solid ${theme.colors.border.weak}`, + padding: theme.spacing(1), + // The RadioButtonDot is not correctly implemented at the moment, missing cursor (And click ability for the label and input) + '> label': { + cursor: 'pointer', + }, + }), + }; +}; + +function getTranslatedThemeName(theme: ThemeRegistryItem) { + switch (theme.id) { + case 'dark': + return t('shared.preferences.theme.dark-label', 'Dark'); + case 'light': + return t('shared.preferences.theme.light-label', 'Light'); + case 'system': + return t('shared.preferences.theme.system-label', 'System preference'); + default: + return theme.name; + } +} diff --git a/public/app/core/components/ThemeSelector/getSelectableThemes.ts b/public/app/core/components/ThemeSelector/getSelectableThemes.ts new file mode 100644 index 00000000000..7dc749d9793 --- /dev/null +++ b/public/app/core/components/ThemeSelector/getSelectableThemes.ts @@ -0,0 +1,20 @@ +import { getBuiltInThemes } from '@grafana/data'; +import { config } from '@grafana/runtime'; + +export function getSelectableThemes() { + const allowedExtraThemes = []; + + if (config.featureToggles.extraThemes) { + allowedExtraThemes.push('debug'); + } + + if (config.featureToggles.grafanaconThemes) { + allowedExtraThemes.push('desertbloom'); + allowedExtraThemes.push('gildedgrove'); + allowedExtraThemes.push('sapphiredusk'); + allowedExtraThemes.push('tron'); + allowedExtraThemes.push('gloom'); + } + + return getBuiltInThemes(allowedExtraThemes); +} diff --git a/public/app/core/constants.ts b/public/app/core/constants.ts index 66417d663af..1de5d88801b 100644 --- a/public/app/core/constants.ts +++ b/public/app/core/constants.ts @@ -17,3 +17,4 @@ export const EDIT_PANEL_ID = 23763571993; export const DEFAULT_PER_PAGE_PAGINATION = 40; export const LS_VISUALIZATION_SELECT_TAB_KEY = 'VisualizationSelectPane.ListMode'; +export const MEGA_MENU_TOGGLE_ID = 'mega-menu-toggle'; diff --git a/public/app/core/services/theme.ts b/public/app/core/services/theme.ts index 6368aa07f76..b244b95e012 100644 --- a/public/app/core/services/theme.ts +++ b/public/app/core/services/theme.ts @@ -50,7 +50,7 @@ export async function changeTheme(themeId: string, runtimeOnly?: boolean) { await service.update({ ...currentPref, - theme: newTheme.colors.mode, + theme: themeId, }); } diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index a2dd8f62e0d..ee429b59821 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -3123,7 +3123,8 @@ "old-password-required": "Old password is required", "passwords-must-match": "Passwords must match", "strong-password-validation-register": "Password does not comply with the strong password policy" - } + }, + "change-theme": "Change theme" }, "public-dashboard": { "acknowledgment-checkboxes": { From c8f810b422d4a7213fbf64990a5e2ef9faac7ffd Mon Sep 17 00:00:00 2001 From: Gabriel MABILLE Date: Tue, 11 Mar 2025 12:04:33 +0100 Subject: [PATCH 36/63] Authz: Check namespace is set in the context (#101723) * Authz: Test List * Anonymous case * Cover rendering * Authz: Check namespace is set in the context * Explicitly request a namespace check in the storage functions * Revert logic --- pkg/services/authz/rbac/service_test.go | 47 +++++++++++++++++-------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/pkg/services/authz/rbac/service_test.go b/pkg/services/authz/rbac/service_test.go index dce4b79da76..b9df0d92322 100644 --- a/pkg/services/authz/rbac/service_test.go +++ b/pkg/services/authz/rbac/service_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "golang.org/x/sync/singleflight" + "k8s.io/apiserver/pkg/endpoints/request" "github.com/grafana/authlib/authn" authzv1 "github.com/grafana/authlib/authz/proto/v1" @@ -225,11 +226,10 @@ func TestService_getUserTeams(t *testing.T) { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() s := setupService() - ns := types.NamespaceInfo{Value: "stacks-12", OrgID: 1, StackID: 12} userIdentifiers := &store.UserIdentifiers{UID: "test-uid"} - identityStore := &fakeIdentityStore{teams: tc.teams, err: tc.expectedError} + identityStore := &fakeIdentityStore{teams: tc.teams, err: tc.expectedError, disableNsCheck: true} s.identityStore = identityStore if tc.cacheHit { @@ -305,7 +305,7 @@ func TestService_getUserBasicRole(t *testing.T) { ns := types.NamespaceInfo{Value: "stacks-12", OrgID: 1, StackID: 12} userIdentifiers := &store.UserIdentifiers{UID: "test-uid", ID: 1} - store := &fakeStore{basicRole: &tc.basicRole, err: tc.expectedError} + store := &fakeStore{basicRole: &tc.basicRole, err: tc.expectedError, disableNsCheck: true} s.store = store s.permissionStore = store @@ -367,9 +367,9 @@ func TestService_getUserPermissions(t *testing.T) { t.Run(tc.name, func(t *testing.T) { ctx := context.Background() s := setupService() + ns := types.NamespaceInfo{Value: "stacks-12", OrgID: 1, StackID: 12} userID := &store.UserIdentifiers{UID: "test-uid", ID: 112} - ns := types.NamespaceInfo{Value: "stacks-12", OrgID: 1, StackID: 12} action := "dashboards:read" if tc.cacheHit { @@ -380,10 +380,11 @@ func TestService_getUserPermissions(t *testing.T) { userID: userID, basicRole: &store.BasicRole{Role: "viewer", IsAdmin: false}, userPermissions: tc.permissions, + disableNsCheck: true, } s.store = store s.permissionStore = store - s.identityStore = &fakeIdentityStore{teams: []int64{1, 2}} + s.identityStore = &fakeIdentityStore{teams: []int64{1, 2}, disableNsCheck: true} perms, err := s.getIdentityPermissions(ctx, ns, types.TypeUser, userID.UID, action) require.NoError(t, err) @@ -737,7 +738,7 @@ func TestService_Check(t *testing.T) { } s.store = store s.permissionStore = store - s.identityStore = &fakeIdentityStore{teams: []int64{1, 2}} + s.identityStore = &fakeIdentityStore{} _, err := s.Check(ctx, tc.req) require.Error(t, err) @@ -785,7 +786,7 @@ func TestService_Check(t *testing.T) { } s.store = store s.permissionStore = store - s.identityStore = &fakeIdentityStore{teams: []int64{1, 2}} + s.identityStore = &fakeIdentityStore{} resp, err := s.Check(ctx, tc.req) require.NoError(t, err) @@ -838,7 +839,7 @@ func TestService_Check(t *testing.T) { store := &fakeStore{userPermissions: tc.permissions} s.store = store s.permissionStore = store - s.identityStore = &fakeIdentityStore{teams: []int64{1, 2}} + s.identityStore = &fakeIdentityStore{} resp, err := s.Check(ctx, tc.req) require.NoError(t, err) @@ -1019,7 +1020,7 @@ func TestService_List(t *testing.T) { } s.store = store s.permissionStore = store - s.identityStore = &fakeIdentityStore{teams: []int64{1, 2}} + s.identityStore = &fakeIdentityStore{} _, err := s.List(ctx, tc.req) require.Error(t, err) @@ -1072,7 +1073,7 @@ func TestService_List(t *testing.T) { } s.store = store s.permissionStore = store - s.identityStore = &fakeIdentityStore{teams: []int64{1, 2}} + s.identityStore = &fakeIdentityStore{} resp, err := s.List(ctx, tc.req) require.NoError(t, err) @@ -1131,7 +1132,7 @@ func TestService_List(t *testing.T) { store := &fakeStore{userPermissions: tc.permissions} s.store = store s.permissionStore = store - s.identityStore = &fakeIdentityStore{teams: []int64{1, 2}} + s.identityStore = &fakeIdentityStore{} resp, err := s.List(ctx, tc.req) require.NoError(t, err) @@ -1218,6 +1219,8 @@ func strPtr(s string) *string { type fakeStore struct { store.Store + // The namespace has to be set in the handlers for the correct organization to be picked up. + disableNsCheck bool folders []store.Folder basicRole *store.BasicRole userID *store.UserIdentifiers @@ -1227,6 +1230,9 @@ type fakeStore struct { } func (f *fakeStore) GetBasicRoles(ctx context.Context, namespace types.NamespaceInfo, query store.BasicRoleQuery) (*store.BasicRole, error) { + if ns, ok := request.NamespaceFrom(ctx); !f.disableNsCheck && (!ok || ns != namespace.Value) { + return nil, fmt.Errorf("namespace mismatch") + } f.calls++ if f.err { return nil, fmt.Errorf("store error") @@ -1235,6 +1241,9 @@ func (f *fakeStore) GetBasicRoles(ctx context.Context, namespace types.Namespace } func (f *fakeStore) GetUserIdentifiers(ctx context.Context, query store.UserIdentifierQuery) (*store.UserIdentifiers, error) { + if _, ok := request.NamespaceFrom(ctx); !f.disableNsCheck && !ok { + return nil, fmt.Errorf("namespace not found") + } f.calls++ if f.err { return nil, fmt.Errorf("store error") @@ -1243,6 +1252,9 @@ func (f *fakeStore) GetUserIdentifiers(ctx context.Context, query store.UserIden } func (f *fakeStore) GetUserPermissions(ctx context.Context, namespace types.NamespaceInfo, query store.PermissionsQuery) ([]accesscontrol.Permission, error) { + if ns, ok := request.NamespaceFrom(ctx); !f.disableNsCheck && (!ok || ns != namespace.Value) { + return nil, fmt.Errorf("namespace mismatch") + } f.calls++ if f.err { return nil, fmt.Errorf("store error") @@ -1251,6 +1263,9 @@ func (f *fakeStore) GetUserPermissions(ctx context.Context, namespace types.Name } func (f *fakeStore) ListFolders(ctx context.Context, namespace types.NamespaceInfo) ([]store.Folder, error) { + if ns, ok := request.NamespaceFrom(ctx); !f.disableNsCheck && (!ok || ns != namespace.Value) { + return nil, fmt.Errorf("namespace mismatch") + } f.calls++ if f.err { return nil, fmt.Errorf("store error") @@ -1260,12 +1275,16 @@ func (f *fakeStore) ListFolders(ctx context.Context, namespace types.NamespaceIn type fakeIdentityStore struct { legacy.LegacyIdentityStore - teams []int64 - err bool - calls int + teams []int64 + disableNsCheck bool + err bool + calls int } func (f *fakeIdentityStore) ListUserTeams(ctx context.Context, namespace types.NamespaceInfo, query legacy.ListUserTeamsQuery) (*legacy.ListUserTeamsResult, error) { + if ns, ok := request.NamespaceFrom(ctx); !f.disableNsCheck && (!ok || ns != namespace.Value) { + return nil, fmt.Errorf("namespace mismatch") + } f.calls++ if f.err { return nil, fmt.Errorf("identity store error") From 3adb12fb56f684a462817d8690268f43421755ef Mon Sep 17 00:00:00 2001 From: Victor Marin <36818606+mdvictor@users.noreply.github.com> Date: Tue, 11 Mar 2025 13:19:46 +0200 Subject: [PATCH 37/63] Dashboards: Fix timezone change issue in dashboards (#101880) * fix timezone change issue in dashboards * update dashboard initial state after saving --- public/app/features/dashboard-scene/scene/DashboardScene.tsx | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/public/app/features/dashboard-scene/scene/DashboardScene.tsx b/public/app/features/dashboard-scene/scene/DashboardScene.tsx index 0ffc53520c4..41559cd975a 100644 --- a/public/app/features/dashboard-scene/scene/DashboardScene.tsx +++ b/public/app/features/dashboard-scene/scene/DashboardScene.tsx @@ -286,9 +286,14 @@ export class DashboardScene extends SceneObjectBase impleme folderUid: folderUid, version: result.version, }, + overlay: undefined, }); this.state.editPanel?.dashboardSaved(); + + this._initialState = sceneUtils.cloneSceneObjectState(this.state); + this._initialUrlState = locationService.getLocation(); + this._changeTracker.startTrackingChanges(); } From 79d079b638f7c31f12d51718ec5ac6afb53fe11c Mon Sep 17 00:00:00 2001 From: Mike Nolta Date: Tue, 11 Mar 2025 07:24:33 -0400 Subject: [PATCH 38/63] Docs: fix missing `@` in `GF_PLUGINS_PREINSTALL` example (#101908) Docs: fix missing `@` in `GF_PLUGINS_PREINSTALL` --- docs/sources/setup-grafana/installation/docker/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/setup-grafana/installation/docker/index.md b/docs/sources/setup-grafana/installation/docker/index.md index 7a7bd091cb9..da578681fca 100644 --- a/docs/sources/setup-grafana/installation/docker/index.md +++ b/docs/sources/setup-grafana/installation/docker/index.md @@ -150,7 +150,7 @@ To install plugins in the Docker container, complete the following steps: ```bash docker run -d -p 3000:3000 --name=grafana \ - -e "GF_PLUGINS_PREINSTALL=grafana-clock-panel 1.0.1" \ + -e "GF_PLUGINS_PREINSTALL=grafana-clock-panel@1.0.1" \ grafana/grafana-enterprise ``` From 927f7befd6a256bbfa5d513f12f874f318ed3b9b Mon Sep 17 00:00:00 2001 From: maicon Date: Tue, 11 Mar 2025 08:33:08 -0300 Subject: [PATCH 39/63] Unistore: Create default permissions through Folder APIServer (#101420) * Unistore: Declare a new storage to set default folder permissions Signed-off-by: Maicon Costa * Remove the setting of default permissions from folder legacy storage Signed-off-by: Maicon Costa * Disable setting of folder permissions when Api Server is enabled Signed-off-by: Maicon Costa * Reverts grafana/grafana#100019 Signed-off-by: Maicon Costa * Add unit test Signed-off-by: Maicon Costa * check error on unit test Signed-off-by: Maicon Costa * Add unit test Signed-off-by: Maicon Costa * Remove unused fields Signed-off-by: Maicon Costa * Add unit tests for folder_storage Signed-off-by: Maicon Costa * Remove duplicated import Signed-off-by: Maicon Costa * Fix unit test Signed-off-by: Maicon Costa --------- Signed-off-by: Maicon Costa --- pkg/api/folder.go | 7 +- pkg/api/folder_test.go | 91 ++++++++++ pkg/registry/apis/folders/folder_storage.go | 161 ++++++++++++++++++ .../apis/folders/folder_storage_test.go | 132 ++++++++++++++ pkg/registry/apis/folders/legacy_storage.go | 48 +----- pkg/registry/apis/folders/register.go | 24 ++- .../accesscontrol/ossaccesscontrol/folder.go | 12 -- .../dashboards/service/dashboard_service.go | 5 +- .../service/dashboard_service_test.go | 70 ++++++++ 9 files changed, 485 insertions(+), 65 deletions(-) create mode 100644 pkg/registry/apis/folders/folder_storage.go create mode 100644 pkg/registry/apis/folders/folder_storage_test.go diff --git a/pkg/api/folder.go b/pkg/api/folder.go index b18db9c7850..682b650cc7b 100644 --- a/pkg/api/folder.go +++ b/pkg/api/folder.go @@ -199,8 +199,11 @@ func (hs *HTTPServer) CreateFolder(c *contextmodel.ReqContext) response.Response return apierrors.ToFolderErrorResponse(err) } - if err := hs.setDefaultFolderPermissions(c.Req.Context(), cmd.OrgID, cmd.SignedInUser, folder); err != nil { - hs.log.Error("Could not set the default folder permissions", "folder", folder.Title, "user", cmd.SignedInUser, "error", err) + // Only set default permissions if the Folder API Server is disabled. + if !hs.Features.IsEnabledGlobally(featuremgmt.FlagKubernetesClientDashboardsFolders) { + if err := hs.setDefaultFolderPermissions(c.Req.Context(), cmd.OrgID, cmd.SignedInUser, folder); err != nil { + hs.log.Error("Could not set the default folder permissions", "folder", folder.Title, "user", cmd.SignedInUser, "error", err) + } } // Clear permission cache for the user who's created the folder, so that new permissions are fetched for their next call diff --git a/pkg/api/folder_test.go b/pkg/api/folder_test.go index 97701e0f4f0..840ae125594 100644 --- a/pkg/api/folder_test.go +++ b/pkg/api/folder_test.go @@ -677,3 +677,94 @@ func TestGetFolderLegacyAndUnifiedStorage(t *testing.T) { } }) } + +func TestSetDefaultPermissionsWhenCreatingFolder(t *testing.T) { + folderService := &foldertest.FakeService{} + setUpRBACGuardian(t) + folderWithoutParentInput := "{ \"uid\": \"uid\", \"title\": \"Folder\"}" + + type testCase struct { + description string + expectedCallsToSetPermissions int + expectedCode int + expectedFolder *folder.Folder + permissions []accesscontrol.Permission + featuresArr []any + input string + } + + tcs := []testCase{ + { + description: "folder creation succeeds, via legacy storage", + expectedCallsToSetPermissions: 1, + input: folderWithoutParentInput, + expectedCode: http.StatusOK, + expectedFolder: &folder.Folder{UID: "uid", Title: "Folder"}, + permissions: []accesscontrol.Permission{{Action: dashboards.ActionFoldersCreate}}, + }, + { + description: "folder creation succeeds, via API Server", + expectedCallsToSetPermissions: 0, + input: folderWithoutParentInput, + expectedCode: http.StatusOK, + expectedFolder: &folder.Folder{UID: "uid", Title: "Folder"}, + permissions: []accesscontrol.Permission{{Action: dashboards.ActionFoldersCreate}}, + featuresArr: []any{featuremgmt.FlagKubernetesClientDashboardsFolders}, + }, + } + + // we need to save these values because they are defined at `setting` package level + // and modified when we invoke setting.NewCfgFromINIFile + prevCookieSameSiteDisabled := setting.CookieSameSiteDisabled + prevCookieSameSiteMode := setting.CookieSameSiteMode + + cfg := setting.NewCfg() + cfg.Raw.Section("rbac").Key("resources_with_managed_permissions_on_creation").SetValue("folder") + tmpCfg, err := setting.NewCfgFromINIFile(cfg.Raw) + require.NoError(t, err) + cfg.RBAC = tmpCfg.RBAC + + // restore previous values so other tests don't break + // ex: TestHTTPServer_RotateUserAuthToken + setting.CookieSameSiteDisabled = prevCookieSameSiteDisabled + setting.CookieSameSiteMode = prevCookieSameSiteMode + + for _, tc := range tcs { + t.Run(tc.description, func(t *testing.T) { + folderService.ExpectedFolder = tc.expectedFolder + folderPermService := acmock.NewMockedPermissionsService() + folderPermService.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil) + + srv := SetupAPITestServer(t, func(hs *HTTPServer) { + hs.Cfg = cfg + + featuresArr := append(tc.featuresArr, featuremgmt.FlagNestedFolders) + hs.Features = featuremgmt.WithFeatures( + featuresArr..., + ) + hs.folderService = folderService + hs.folderPermissionsService = folderPermService + hs.accesscontrolService = actest.FakeService{} + }) + + input := strings.NewReader(tc.input) + req := srv.NewPostRequest("/api/folders", input) + req = webtest.RequestWithSignedInUser(req, userWithPermissions(1, tc.permissions)) + resp, err := srv.SendJSON(req) + require.NoError(t, err) + require.Equal(t, tc.expectedCode, resp.StatusCode) + + folder := dtos.Folder{} + err = json.NewDecoder(resp.Body).Decode(&folder) + require.NoError(t, err) + require.NoError(t, resp.Body.Close()) + + folderPermService.AssertNumberOfCalls(t, "SetPermissions", tc.expectedCallsToSetPermissions) + + if tc.expectedCode == http.StatusOK { + assert.Equal(t, "uid", folder.UID) + assert.Equal(t, "Folder", folder.Title) + } + }) + } +} diff --git a/pkg/registry/apis/folders/folder_storage.go b/pkg/registry/apis/folders/folder_storage.go new file mode 100644 index 00000000000..92156643354 --- /dev/null +++ b/pkg/registry/apis/folders/folder_storage.go @@ -0,0 +1,161 @@ +package folders + +import ( + "context" + "fmt" + + "k8s.io/apimachinery/pkg/apis/meta/internalversion" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/registry/rest" + + claims "github.com/grafana/authlib/types" + "github.com/grafana/grafana/pkg/apimachinery/identity" + "github.com/grafana/grafana/pkg/apimachinery/utils" + "github.com/grafana/grafana/pkg/apis/folder/v0alpha1" + grafanarest "github.com/grafana/grafana/pkg/apiserver/rest" + "github.com/grafana/grafana/pkg/services/accesscontrol" + "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" + "github.com/grafana/grafana/pkg/services/dashboards/dashboardaccess" + "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/services/org" + "github.com/grafana/grafana/pkg/setting" +) + +var ( + _ rest.Scoper = (*folderStorage)(nil) + _ rest.SingularNameProvider = (*folderStorage)(nil) + _ rest.Getter = (*folderStorage)(nil) + _ rest.Lister = (*folderStorage)(nil) + _ rest.Storage = (*folderStorage)(nil) + _ rest.Creater = (*folderStorage)(nil) + _ rest.Updater = (*folderStorage)(nil) + _ rest.GracefulDeleter = (*folderStorage)(nil) +) + +type folderStorage struct { + tableConverter rest.TableConvertor + cfg *setting.Cfg + features featuremgmt.FeatureToggles + folderPermissionsSvc accesscontrol.FolderPermissionsService + store grafanarest.Storage +} + +func (s *folderStorage) New() runtime.Object { + return resourceInfo.NewFunc() +} + +func (s *folderStorage) Destroy() {} + +func (s *folderStorage) NamespaceScoped() bool { + return true // namespace == org +} + +func (s *folderStorage) GetSingularName() string { + return resourceInfo.GetSingularName() +} + +func (s *folderStorage) NewList() runtime.Object { + return resourceInfo.NewListFunc() +} + +func (s *folderStorage) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) { + return s.tableConverter.ConvertToTable(ctx, object, tableOptions) +} + +func (s *folderStorage) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) { + return s.store.List(ctx, options) +} + +func (s *folderStorage) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { + return s.store.Get(ctx, name, options) +} + +func (s *folderStorage) Create(ctx context.Context, + obj runtime.Object, + createValidation rest.ValidateObjectFunc, + options *metav1.CreateOptions, +) (runtime.Object, error) { + obj, err := s.store.Create(ctx, obj, createValidation, options) + if err != nil { + return nil, err + } + + info, err := request.NamespaceInfoFrom(ctx, true) + if err != nil { + return nil, err + } + + user, err := identity.GetRequester(ctx) + if err != nil { + return nil, err + } + + p, ok := obj.(*v0alpha1.Folder) + if !ok { + return nil, fmt.Errorf("expected folder?") + } + + accessor, err := utils.MetaAccessor(p) + if err != nil { + return nil, err + } + + parentUid := accessor.GetFolder() + + err = s.setDefaultFolderPermissions(ctx, info.OrgID, user, p.ObjectMeta.Name, parentUid) + if err != nil { + return nil, err + } + + return obj, nil +} + +func (s *folderStorage) Update(ctx context.Context, + name string, + objInfo rest.UpdatedObjectInfo, + createValidation rest.ValidateObjectFunc, + updateValidation rest.ValidateObjectUpdateFunc, + forceAllowCreate bool, + options *metav1.UpdateOptions, +) (runtime.Object, bool, error) { + return s.store.Update(ctx, name, objInfo, createValidation, updateValidation, forceAllowCreate, options) +} + +// GracefulDeleter +func (s *folderStorage) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { + return s.store.Delete(ctx, name, deleteValidation, options) +} + +// GracefulDeleter +func (s *folderStorage) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *internalversion.ListOptions) (runtime.Object, error) { + return nil, fmt.Errorf("DeleteCollection for folders not implemented") +} + +func (s *folderStorage) setDefaultFolderPermissions(ctx context.Context, orgID int64, user identity.Requester, uid string, parentUID string) error { + if !s.cfg.RBAC.PermissionsOnCreation("folder") { + return nil + } + + var permissions []accesscontrol.SetResourcePermissionCommand + + if user.IsIdentityType(claims.TypeUser) { + userID, err := user.GetInternalID() + if err != nil { + return err + } + + permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{ + UserID: userID, Permission: dashboardaccess.PERMISSION_ADMIN.String(), + }) + } + isNested := parentUID != "" + if !isNested || !s.features.IsEnabled(ctx, featuremgmt.FlagNestedFolders) { + permissions = append(permissions, []accesscontrol.SetResourcePermissionCommand{ + {BuiltinRole: string(org.RoleEditor), Permission: dashboardaccess.PERMISSION_EDIT.String()}, + {BuiltinRole: string(org.RoleViewer), Permission: dashboardaccess.PERMISSION_VIEW.String()}, + }...) + } + _, err := s.folderPermissionsSvc.SetPermissions(ctx, orgID, uid, permissions...) + return err +} diff --git a/pkg/registry/apis/folders/folder_storage_test.go b/pkg/registry/apis/folders/folder_storage_test.go new file mode 100644 index 00000000000..31cc755b6f3 --- /dev/null +++ b/pkg/registry/apis/folders/folder_storage_test.go @@ -0,0 +1,132 @@ +package folders + +import ( + "context" + "testing" + + "github.com/grafana/grafana/pkg/apimachinery/identity" + "github.com/grafana/grafana/pkg/apis/folder/v0alpha1" + "github.com/grafana/grafana/pkg/services/accesscontrol" + acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" + "github.com/grafana/grafana/pkg/services/user" + "github.com/grafana/grafana/pkg/setting" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "gopkg.in/ini.v1" + "k8s.io/apimachinery/pkg/apis/meta/internalversion" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apiserver/pkg/endpoints/request" + "k8s.io/apiserver/pkg/registry/rest" +) + +func TestSetDefaultPermissionsWhenCreatingFolder(t *testing.T) { + type testCase struct { + description string + expectedCallsToSetPermissions int + } + + tcs := []testCase{ + { + description: "folder creation succeeds, via legacy storage", + expectedCallsToSetPermissions: 1, + }, + } + + for _, tc := range tcs { + t.Run(tc.description, func(t *testing.T) { + folderPermService := acmock.NewMockedPermissionsService() + folderPermService.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil) + + cfg := setting.NewCfg() + f := ini.Empty() + f.Section("rbac").Key("resources_with_managed_permissions_on_creation").SetValue("folder") + tempCfg, err := setting.NewCfgFromINIFile(f) + require.NoError(t, err) + cfg.RBAC = tempCfg.RBAC + + fs := folderStorage{ + folderPermissionsSvc: folderPermService, + store: &fakeStorage{}, + cfg: cfg, + } + obj := &v0alpha1.Folder{} + + ctx := request.WithNamespace(context.Background(), "org-2") + ctx = identity.WithRequester(ctx, &user.SignedInUser{ + UserID: 1, + }) + + out, err := fs.Create(ctx, obj, func(ctx context.Context, + obj runtime.Object) error { + return nil + }, + &metav1.CreateOptions{}) + + require.NoError(t, err) + require.NotNil(t, out) + + folderPermService.AssertNumberOfCalls(t, "SetPermissions", tc.expectedCallsToSetPermissions) + }) + } +} + +var ( + _ rest.Scoper = (*fakeStorage)(nil) + _ rest.SingularNameProvider = (*fakeStorage)(nil) + _ rest.Getter = (*fakeStorage)(nil) + _ rest.Lister = (*fakeStorage)(nil) + _ rest.Storage = (*fakeStorage)(nil) + _ rest.Creater = (*fakeStorage)(nil) + _ rest.Updater = (*fakeStorage)(nil) + _ rest.GracefulDeleter = (*fakeStorage)(nil) +) + +type fakeStorage struct{} + +func (s *fakeStorage) New() runtime.Object { + return nil +} + +func (s *fakeStorage) Destroy() {} + +func (s *fakeStorage) NamespaceScoped() bool { + return true +} + +func (s *fakeStorage) GetSingularName() string { + return "" +} + +func (s *fakeStorage) NewList() runtime.Object { + return nil +} + +func (s *fakeStorage) ConvertToTable(ctx context.Context, object runtime.Object, tableOptions runtime.Object) (*metav1.Table, error) { + return nil, nil +} + +func (s *fakeStorage) List(ctx context.Context, options *internalversion.ListOptions) (runtime.Object, error) { + return nil, nil +} + +func (s *fakeStorage) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) { + return nil, nil +} + +func (s *fakeStorage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) { + return obj, nil +} + +func (s *fakeStorage) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, createValidation rest.ValidateObjectFunc, + updateValidation rest.ValidateObjectUpdateFunc, forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) { + return nil, false, nil +} + +func (s *fakeStorage) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) { + return nil, false, nil +} + +func (s *fakeStorage) DeleteCollection(ctx context.Context, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions, listOptions *internalversion.ListOptions) (runtime.Object, error) { + return nil, nil +} diff --git a/pkg/registry/apis/folders/legacy_storage.go b/pkg/registry/apis/folders/legacy_storage.go index 550331c855e..9ec2d7c98b8 100644 --- a/pkg/registry/apis/folders/legacy_storage.go +++ b/pkg/registry/apis/folders/legacy_storage.go @@ -10,18 +10,14 @@ import ( "k8s.io/apimachinery/pkg/runtime" "k8s.io/apiserver/pkg/registry/rest" - claims "github.com/grafana/authlib/types" "github.com/grafana/grafana/pkg/api/apierrors" "github.com/grafana/grafana/pkg/apimachinery/identity" "github.com/grafana/grafana/pkg/apimachinery/utils" "github.com/grafana/grafana/pkg/apis/folder/v0alpha1" - "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/apiserver/endpoints/request" "github.com/grafana/grafana/pkg/services/dashboards" - "github.com/grafana/grafana/pkg/services/dashboards/dashboardaccess" "github.com/grafana/grafana/pkg/services/featuremgmt" "github.com/grafana/grafana/pkg/services/folder" - "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" ) @@ -38,12 +34,11 @@ var ( ) type legacyStorage struct { - service folder.Service - namespacer request.NamespaceMapper - tableConverter rest.TableConvertor - cfg *setting.Cfg - features featuremgmt.FeatureToggles - folderPermissionsSvc accesscontrol.FolderPermissionsService + service folder.Service + namespacer request.NamespaceMapper + tableConverter rest.TableConvertor + cfg *setting.Cfg + features featuremgmt.FeatureToggles } func (s *legacyStorage) New() runtime.Object { @@ -200,11 +195,6 @@ func (s *legacyStorage) Create(ctx context.Context, return nil, &statusErr } - err = s.setDefaultFolderPermissions(ctx, info.OrgID, user, out) - if err != nil { - return nil, err - } - // #TODO can we directly convert instead of doing a Get? the result of the Create // has more data than the one of Get so there is more we can include in the k8s resource // this way @@ -216,34 +206,6 @@ func (s *legacyStorage) Create(ctx context.Context, return r, nil } -func (s *legacyStorage) setDefaultFolderPermissions(ctx context.Context, orgID int64, user identity.Requester, folder *folder.Folder) error { - if !s.cfg.RBAC.PermissionsOnCreation("folder") { - return nil - } - - var permissions []accesscontrol.SetResourcePermissionCommand - - if user.IsIdentityType(claims.TypeUser) { - userID, err := user.GetInternalID() - if err != nil { - return err - } - - permissions = append(permissions, accesscontrol.SetResourcePermissionCommand{ - UserID: userID, Permission: dashboardaccess.PERMISSION_ADMIN.String(), - }) - } - isNested := folder.ParentUID != "" - if !isNested || !s.features.IsEnabled(ctx, featuremgmt.FlagNestedFolders) { - permissions = append(permissions, []accesscontrol.SetResourcePermissionCommand{ - {BuiltinRole: string(org.RoleEditor), Permission: dashboardaccess.PERMISSION_EDIT.String()}, - {BuiltinRole: string(org.RoleViewer), Permission: dashboardaccess.PERMISSION_VIEW.String()}, - }...) - } - _, err := s.folderPermissionsSvc.SetPermissions(ctx, orgID, folder.UID, permissions...) - return err -} - func (s *legacyStorage) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo, diff --git a/pkg/registry/apis/folders/register.go b/pkg/registry/apis/folders/register.go index 6d4d64f1d9a..ca3d492815d 100644 --- a/pkg/registry/apis/folders/register.go +++ b/pkg/registry/apis/folders/register.go @@ -148,28 +148,38 @@ func (b *FolderAPIBuilder) UpdateAPIGroupInfo(apiGroupInfo *genericapiserver.API } legacyStore := &legacyStorage{ - service: b.folderSvc, - namespacer: b.namespacer, + service: b.folderSvc, + namespacer: b.namespacer, + tableConverter: resourceInfo.TableConverter(), + features: b.features, + cfg: b.cfg, + } + + opts.StorageOptions(resourceInfo.GroupResource(), apistore.StorageOptions{ + RequireDeprecatedInternalID: true}) + + folderStore := &folderStorage{ tableConverter: resourceInfo.TableConverter(), folderPermissionsSvc: b.folderPermissionsSvc, features: b.features, cfg: b.cfg, } - opts.StorageOptions(resourceInfo.GroupResource(), apistore.StorageOptions{ - RequireDeprecatedInternalID: true}) - - storage[resourceInfo.StoragePath()] = legacyStore if optsGetter != nil && dualWriteBuilder != nil { store, err := grafanaregistry.NewRegistryStore(scheme, resourceInfo, optsGetter) if err != nil { return err } - storage[resourceInfo.StoragePath()], err = dualWriteBuilder(resourceInfo.GroupResource(), legacyStore, store) + + dw, err := dualWriteBuilder(resourceInfo.GroupResource(), legacyStore, store) if err != nil { return err } + + folderStore.store = dw } + storage[resourceInfo.StoragePath()] = folderStore + storage[resourceInfo.StoragePath("parents")] = &subParentsREST{ getter: storage[resourceInfo.StoragePath()].(rest.Getter), // Get the parents } diff --git a/pkg/services/accesscontrol/ossaccesscontrol/folder.go b/pkg/services/accesscontrol/ossaccesscontrol/folder.go index ee41326c878..67b73ebe764 100644 --- a/pkg/services/accesscontrol/ossaccesscontrol/folder.go +++ b/pkg/services/accesscontrol/ossaccesscontrol/folder.go @@ -2,7 +2,6 @@ package ossaccesscontrol import ( "context" - "errors" "github.com/grafana/grafana/pkg/api/routing" "github.com/grafana/grafana/pkg/apimachinery/identity" @@ -107,17 +106,6 @@ func ProvideFolderPermissions( }) if err != nil { - // if the folder is not found, this may be on the create path, - // where the write path to legacy will then go through the read - // path and try to read from both legacy & unified before it exists on both - if features.IsEnabledGlobally(featuremgmt.FlagKubernetesClientDashboardsFolders) && errors.Is(err, dashboards.ErrFolderNotFound) { - _, err = folderService.GetLegacy(ctx, &folder.GetFolderQuery{ - UID: &resourceID, - OrgID: orgID, - SignedInUser: ident, - }) - return err - } return err } diff --git a/pkg/services/dashboards/service/dashboard_service.go b/pkg/services/dashboards/service/dashboard_service.go index 68b49623bd3..31fbfcb428d 100644 --- a/pkg/services/dashboards/service/dashboard_service.go +++ b/pkg/services/dashboards/service/dashboard_service.go @@ -719,7 +719,10 @@ func (dr *DashboardServiceImpl) SaveFolderForProvisionedDashboards(ctx context.C return nil, err } - dr.setDefaultFolderPermissions(ctx, dto, f, true) + // Only set default permissions if the Folder API Server is disabled. + if !dr.features.IsEnabledGlobally(featuremgmt.FlagKubernetesClientDashboardsFolders) { + dr.setDefaultFolderPermissions(ctx, dto, f, true) + } return f, nil } diff --git a/pkg/services/dashboards/service/dashboard_service_test.go b/pkg/services/dashboards/service/dashboard_service_test.go index 105f3bcfe23..c3593db643c 100644 --- a/pkg/services/dashboards/service/dashboard_service_test.go +++ b/pkg/services/dashboards/service/dashboard_service_test.go @@ -10,6 +10,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "gopkg.in/ini.v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" @@ -18,6 +20,8 @@ import ( dashboardv0alpha1 "github.com/grafana/grafana/pkg/apis/dashboard/v0alpha1" "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana/pkg/services/accesscontrol" + acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" "github.com/grafana/grafana/pkg/services/apiserver/client" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -1112,6 +1116,72 @@ func TestGetDashboardsByPluginID(t *testing.T) { }) } +func TestSetDefaultPermissionsWhenSavingFolderForProvisionedDashboards(t *testing.T) { + fakeStore := dashboards.FakeDashboardStore{} + defer fakeStore.AssertExpectations(t) + + type testCase struct { + description string + expectedCallsToSetPermissions int + featuresArr []any + } + + tcs := []testCase{ + { + description: "folder creation succeeds, via legacy storage", + expectedCallsToSetPermissions: 1, + }, + { + description: "folder creation succeeds, via API Server", + expectedCallsToSetPermissions: 0, + featuresArr: []any{featuremgmt.FlagKubernetesClientDashboardsFolders}, + }, + } + + for _, tc := range tcs { + t.Run(tc.description, func(t *testing.T) { + folderPermService := acmock.NewMockedPermissionsService() + folderPermService.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil) + + cfg := setting.NewCfg() + f := ini.Empty() + f.Section("rbac").Key("resources_with_managed_permissions_on_creation").SetValue("folder") + tempCfg, err := setting.NewCfgFromINIFile(f) + require.NoError(t, err) + cfg.RBAC = tempCfg.RBAC + + service := &DashboardServiceImpl{ + cfg: cfg, + dashboardStore: &fakeStore, + folderPermissions: folderPermService, + folderService: &foldertest.FakeService{ + ExpectedFolder: &folder.Folder{ + ID: 0, + UID: "general", + }, + }, + log: log.NewNopLogger(), + } + + origNewDashboardGuardian := guardian.New + defer func() { guardian.New = origNewDashboardGuardian }() + guardian.MockDashboardGuardian(&guardian.FakeDashboardGuardian{CanSaveValue: true}) + + cmd := &folder.CreateFolderCommand{ + Title: "foo", + OrgID: 1, + } + + service.features = featuremgmt.WithFeatures(tc.featuresArr...) + folder, err := service.SaveFolderForProvisionedDashboards(context.Background(), cmd) + require.NoError(t, err) + require.NotNil(t, folder) + + folderPermService.AssertNumberOfCalls(t, "SetPermissions", tc.expectedCallsToSetPermissions) + }) + } +} + func TestSaveProvisionedDashboard(t *testing.T) { fakeStore := dashboards.FakeDashboardStore{} defer fakeStore.AssertExpectations(t) From adbc5b2b8813c1ae2b888fe2b726acf72991e935 Mon Sep 17 00:00:00 2001 From: Gilles De Mey Date: Tue, 11 Mar 2025 12:51:48 +0100 Subject: [PATCH 40/63] Alerting: Hide "unauthorized" warning for anonymous users (#101811) * remove nav analytics * revert * Remove new user check for alerting navigation tracking * Delete Analytics.test.ts --- .../alerting/unified/Analytics.test.ts | 41 ------------------- .../features/alerting/unified/Analytics.ts | 24 +---------- 2 files changed, 1 insertion(+), 64 deletions(-) delete mode 100644 public/app/features/alerting/unified/Analytics.test.ts diff --git a/public/app/features/alerting/unified/Analytics.test.ts b/public/app/features/alerting/unified/Analytics.test.ts deleted file mode 100644 index 47575f755df..00000000000 --- a/public/app/features/alerting/unified/Analytics.test.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { dateTime } from '@grafana/data'; -import { getBackendSrv } from '@grafana/runtime'; - -import { USER_CREATION_MIN_DAYS, isNewUser } from './Analytics'; - -jest.mock('@grafana/runtime', () => ({ - ...jest.requireActual('@grafana/runtime'), - getBackendSrv: jest.fn().mockReturnValue({ - get: jest.fn(), - }), -})); - -describe('isNewUser', function () { - it('should return true if the user has been created within the last week', async () => { - const newUser = { - id: 1, - createdAt: dateTime().subtract(6, 'days'), - }; - - getBackendSrv().get = jest.fn().mockResolvedValue(newUser); - - const isNew = await isNewUser(); - expect(isNew).toBe(true); - expect(getBackendSrv().get).toHaveBeenCalledTimes(1); - expect(getBackendSrv().get).toHaveBeenCalledWith('/api/user'); - }); - - it('should return false if the user has been created prior to the last two weeks', async () => { - const oldUser = { - id: 2, - createdAt: dateTime().subtract(USER_CREATION_MIN_DAYS, 'days'), - }; - - getBackendSrv().get = jest.fn().mockResolvedValue(oldUser); - - const isNew = await isNewUser(); - expect(isNew).toBe(false); - expect(getBackendSrv().get).toHaveBeenCalledTimes(1); - expect(getBackendSrv().get).toHaveBeenCalledWith('/api/user'); - }); -}); diff --git a/public/app/features/alerting/unified/Analytics.ts b/public/app/features/alerting/unified/Analytics.ts index e546d215574..559e7808d96 100644 --- a/public/app/features/alerting/unified/Analytics.ts +++ b/public/app/features/alerting/unified/Analytics.ts @@ -1,7 +1,6 @@ import { isEmpty } from 'lodash'; -import { dateTime } from '@grafana/data'; -import { createMonitoringLogger, getBackendSrv } from '@grafana/runtime'; +import { createMonitoringLogger } from '@grafana/runtime'; import { config, reportInteraction } from '@grafana/runtime/src'; import { contextSrv } from 'app/core/core'; @@ -13,8 +12,6 @@ import { FilterType } from './components/rules/central-state-history/EventListSc import { RulesFilter, getSearchFilterFromQuery } from './search/rulesSearchParser'; import { RuleFormType } from './types/rule-form'; -export const USER_CREATION_MIN_DAYS = 7; - export const LogMessages = { filterByLabel: 'filtering alert instances by label', loadedList: 'loaded Alert Rules list', @@ -152,21 +149,6 @@ function getRulerRulesMetadata(rulerRules: RulerRulesConfigDTO) { }; } -export async function isNewUser() { - try { - const { createdAt } = await getBackendSrv().get(`/api/user`); - - const limitDateForNewUser = dateTime().subtract(USER_CREATION_MIN_DAYS, 'days'); - const userCreationDate = dateTime(createdAt); - - const isNew = limitDateForNewUser.isBefore(userCreationDate); - - return isNew; - } catch { - return true; //if no date is returned, we assume the user is new to prevent tracking actions - } -} - export const trackRuleListNavigation = async ( props: AlertRuleTrackingProps = { grafana_version: config.buildInfo.version, @@ -174,10 +156,6 @@ export const trackRuleListNavigation = async ( user_id: contextSrv.user.id, } ) => { - const isNew = await isNewUser(); - if (isNew) { - return; - } reportInteraction('grafana_alerting_navigation', props); }; From 842d91d0b63b2424a55d196e414a770727be9ef0 Mon Sep 17 00:00:00 2001 From: Alex Khomenko Date: Tue, 11 Mar 2025 13:20:47 +0100 Subject: [PATCH 41/63] POC/Provisioning: Create folder from root (#101921) * Enable creating folder at the root * Fix test * Add interceptor --- .../BrowseDashboardsPage.test.tsx | 5 ++ .../components/CreateNewButton.tsx | 4 +- .../NewProvisionedFolderForm.test.tsx | 79 ++++++++++--------- .../components/NewProvisionedFolderForm.tsx | 27 ++++--- .../hooks/useIsProvisionedInstance.ts | 10 +++ public/app/features/provisioning/utils.ts | 2 +- 6 files changed, 74 insertions(+), 53 deletions(-) create mode 100644 public/app/features/provisioning/hooks/useIsProvisionedInstance.ts diff --git a/public/app/features/browse-dashboards/BrowseDashboardsPage.test.tsx b/public/app/features/browse-dashboards/BrowseDashboardsPage.test.tsx index ae25e7a6eb9..9410f66b3c5 100644 --- a/public/app/features/browse-dashboards/BrowseDashboardsPage.test.tsx +++ b/public/app/features/browse-dashboards/BrowseDashboardsPage.test.tsx @@ -141,6 +141,11 @@ describe('browse-dashboards BrowseDashboardsPage', () => { return HttpResponse.json({ sortOptions: [], }); + }), + http.get('/apis/provisioning.grafana.app/v0alpha1/namespaces/default/settings', () => { + return HttpResponse.json({ + items: [], + }); }) ); server.listen(); diff --git a/public/app/features/browse-dashboards/components/CreateNewButton.tsx b/public/app/features/browse-dashboards/components/CreateNewButton.tsx index d2b6203b768..86e3a1a4a42 100644 --- a/public/app/features/browse-dashboards/components/CreateNewButton.tsx +++ b/public/app/features/browse-dashboards/components/CreateNewButton.tsx @@ -5,6 +5,7 @@ import { locationUtil } from '@grafana/data'; import { config, locationService, reportInteraction } from '@grafana/runtime'; import { Button, Drawer, Dropdown, Icon, Menu, MenuItem } from '@grafana/ui'; import { useAppNotification } from 'app/core/copy/appNotification'; +import { useIsProvisionedInstance } from 'app/features/provisioning/hooks/useIsProvisionedInstance'; import { getImportPhrase, getNewDashboardPhrase, @@ -30,6 +31,7 @@ export default function CreateNewButton({ parentFolder, canCreateDashboard, canC const [newFolder] = useNewFolderMutation(); const [showNewFolderDrawer, setShowNewFolderDrawer] = useState(false); const notifyApp = useAppNotification(); + const isProvisionedInstance = useIsProvisionedInstance(); const onCreateFolder = async (folderName: string) => { try { @@ -103,7 +105,7 @@ export default function CreateNewButton({ parentFolder, canCreateDashboard, canC onClose={() => setShowNewFolderDrawer(false)} size="sm" > - {parentFolder?.repository ? ( + {parentFolder?.repository || isProvisionedInstance ? ( setShowNewFolderDrawer(false)} onCancel={() => setShowNewFolderDrawer(false)} diff --git a/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.test.tsx b/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.test.tsx index 94d38244d96..87f464b877c 100644 --- a/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.test.tsx +++ b/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.test.tsx @@ -4,8 +4,8 @@ import userEvent from '@testing-library/user-event'; import { AppEvents } from '@grafana/data'; import { getAppEvents } from '@grafana/runtime'; import { validationSrv } from 'app/features/manage-dashboards/services/ValidationSrv'; -import { useCreateRepositoryFilesWithPathMutation, useGetRepositoryQuery } from 'app/features/provisioning/api'; -import { usePullRequestParam } from 'app/features/provisioning/hooks'; +import { useCreateRepositoryFilesWithPathMutation } from 'app/features/provisioning/api'; +import { usePullRequestParam, useRepositoryList } from 'app/features/provisioning/hooks'; import { FolderDTO } from '../../../types'; import { useGetFolderQuery } from '../../folders/api'; @@ -37,7 +37,6 @@ jest.mock('app/features/manage-dashboards/services/ValidationSrv', () => { jest.mock('app/features/provisioning/api', () => { return { useCreateRepositoryFilesWithPathMutation: jest.fn(), - useGetRepositoryQuery: jest.fn(), }; }); @@ -50,6 +49,7 @@ jest.mock('../../folders/api', () => { jest.mock('app/features/provisioning/hooks', () => { return { usePullRequestParam: jest.fn(), + useRepositoryList: jest.fn(), }; }); @@ -127,21 +127,25 @@ describe('NewProvisionedFolderForm', () => { }; (getAppEvents as jest.Mock).mockReturnValue(mockAppEvents); - // Mock useGetRepositoryQuery - (useGetRepositoryQuery as jest.Mock).mockReturnValue({ - data: { - spec: { - type: 'github', - github: { - url: 'https://github.com/grafana/grafana', - branch: 'main', + (useRepositoryList as jest.Mock).mockReturnValue([ + [ + { + metadata: { + name: 'test-repo', + }, + spec: { + title: 'Test Repository', + type: 'github', + github: { + url: 'https://github.com/grafana/grafana', + branch: 'main', + }, + workflows: [{ name: 'default', path: 'workflows/default.yaml' }], }, - workflows: ['write', 'branch'], }, - }, - isLoading: false, - isError: false, - }); + ], + false, + ]); // Mock useGetFolderQuery (useGetFolderQuery as jest.Mock).mockReturnValue({ @@ -179,11 +183,7 @@ describe('NewProvisionedFolderForm', () => { }); it('should show loading state when repository data is loading', () => { - (useGetRepositoryQuery as jest.Mock).mockReturnValue({ - data: null, - isLoading: true, - isError: false, - }); + (useRepositoryList as jest.Mock).mockReturnValue([[], true]); setup(); @@ -191,11 +191,7 @@ describe('NewProvisionedFolderForm', () => { }); it('should show error when repository is not found', () => { - (useGetRepositoryQuery as jest.Mock).mockReturnValue({ - data: null, - isLoading: false, - isError: true, - }); + (useRepositoryList as jest.Mock).mockReturnValue([null, false]); setup(); @@ -426,24 +422,29 @@ describe('NewProvisionedFolderForm', () => { }); it('should show read-only alert when repository has no workflows', () => { - (useGetRepositoryQuery as jest.Mock).mockReturnValue({ - data: { - spec: { - type: 'github', - github: { - url: 'https://github.com/grafana/grafana', - branch: 'main', + // Mock repository with empty workflows array + (useRepositoryList as jest.Mock).mockReturnValue([ + [ + { + metadata: { + name: 'test-repo', + }, + spec: { + type: 'github', + github: { + url: 'https://github.com/grafana/grafana', + branch: 'main', + }, + workflows: [], // Empty workflows array }, - workflows: [], // Empty workflows array }, - }, - isLoading: false, - isError: false, - }); + ], + false, + ]); setup(); - // Read-only alert should be visible - use text content instead of role + // Read-only alert should be visible expect(screen.getByText('This repository is read only')).toBeInTheDocument(); }); }); diff --git a/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.tsx b/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.tsx index bc1c23043b6..8a3e0d959a0 100644 --- a/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.tsx +++ b/public/app/features/browse-dashboards/components/NewProvisionedFolderForm.tsx @@ -7,9 +7,9 @@ import { AppEvents } from '@grafana/data'; import { getAppEvents } from '@grafana/runtime'; import { Alert, Button, Field, Input, RadioButtonGroup, Spinner, Stack, TextArea } from '@grafana/ui'; import { validationSrv } from 'app/features/manage-dashboards/services/ValidationSrv'; -import { useCreateRepositoryFilesWithPathMutation, useGetRepositoryQuery } from 'app/features/provisioning/api'; +import { useCreateRepositoryFilesWithPathMutation } from 'app/features/provisioning/api'; import { PROVISIONING_URL } from 'app/features/provisioning/constants'; -import { usePullRequestParam } from 'app/features/provisioning/hooks'; +import { usePullRequestParam, useRepositoryList } from 'app/features/provisioning/hooks'; import { WorkflowOption } from 'app/features/provisioning/types'; import { validateBranchName } from 'app/features/provisioning/utils/git'; @@ -30,7 +30,7 @@ type FormData = { interface Props { onSubmit: () => void; onCancel: () => void; - parentFolder: FolderDTO; + parentFolder?: FolderDTO; } const initialFormValues: Partial = { @@ -40,20 +40,21 @@ const initialFormValues: Partial = { }; export function NewProvisionedFolderForm({ onSubmit, onCancel, parentFolder }: Props) { - const repositoryName = parentFolder.repository?.name; - const query = useGetRepositoryQuery(repositoryName ? { name: repositoryName } : skipToken); + const repositoryName = parentFolder?.repository?.name; + const [items, isLoading] = useRepositoryList(); const prURL = usePullRequestParam(); const navigate = useNavigate(); const [create, request] = useCreateRepositoryFilesWithPathMutation(); // Get k8s folder data, necessary to get parent folder path - const folderQuery = useGetFolderQuery({ name: parentFolder.uid }); + const folderQuery = useGetFolderQuery(parentFolder ? { name: parentFolder.uid } : skipToken); - if (!query.data && !query.isLoading) { + if (!items && !isLoading) { return ; } - const repositoryConfig = query.data?.spec; + const repository = repositoryName ? items?.find((item) => item?.metadata?.name === repositoryName) : items?.[0]; + const repositoryConfig = repository?.spec; const isGitHub = Boolean(repositoryConfig?.github); const { @@ -110,7 +111,7 @@ export function NewProvisionedFolderForm({ onSubmit, onCancel, parentFolder }: P repositoryName, ]); - if (query.isLoading || folderQuery.isLoading) { + if (isLoading || folderQuery.isLoading) { return ; } @@ -127,7 +128,8 @@ export function NewProvisionedFolderForm({ onSubmit, onCancel, parentFolder }: P }; const doSave = async ({ ref, title, workflow, comment }: FormData) => { - if (!title) { + const repoName = repository?.metadata?.name; + if (!title || !repoName) { return; } const basePath = folderQuery.data?.metadata?.annotations?.[AnnoKeySourcePath] ?? ''; @@ -138,7 +140,8 @@ export function NewProvisionedFolderForm({ onSubmit, onCancel, parentFolder }: P .replace(/\s+/g, '-') .replace(/[^a-z0-9-]/g, ''); - const path = `${basePath}/${titleInFilenameFormat}/`; + const prefix = basePath ? `${basePath}/` : ''; + const path = `${prefix}${titleInFilenameFormat}/`; const folderModel = { title, @@ -151,7 +154,7 @@ export function NewProvisionedFolderForm({ onSubmit, onCancel, parentFolder }: P create({ ref, - name: repositoryName ?? '', + name: repoName, path, message: comment || `Create folder: ${title}`, body: folderModel, diff --git a/public/app/features/provisioning/hooks/useIsProvisionedInstance.ts b/public/app/features/provisioning/hooks/useIsProvisionedInstance.ts new file mode 100644 index 00000000000..1d637ac6fed --- /dev/null +++ b/public/app/features/provisioning/hooks/useIsProvisionedInstance.ts @@ -0,0 +1,10 @@ +import { skipToken } from '@reduxjs/toolkit/query'; + +import { RepositoryViewList, useGetFrontendSettingsQuery } from '../api'; +import { checkSyncSettings } from '../utils'; + +export function useIsProvisionedInstance(settings?: RepositoryViewList) { + const settingsQuery = useGetFrontendSettingsQuery(settings ? skipToken : undefined); + const [instanceConnected] = checkSyncSettings(settings || settingsQuery.data); + return instanceConnected; +} diff --git a/public/app/features/provisioning/utils.ts b/public/app/features/provisioning/utils.ts index 56023012ea7..44bc096e8c2 100644 --- a/public/app/features/provisioning/utils.ts +++ b/public/app/features/provisioning/utils.ts @@ -1,6 +1,6 @@ import { RepositoryViewList } from './api'; -export function checkSyncSettings(settings: RepositoryViewList | undefined): [boolean, boolean] { +export function checkSyncSettings(settings?: RepositoryViewList): [boolean, boolean] { if (!settings?.items?.length) { return [false, false]; } From 062a0e7212f495330408359fee7c42e2c6839abc Mon Sep 17 00:00:00 2001 From: Joey <90795735+joey-grafana@users.noreply.github.com> Date: Tue, 11 Mar 2025 12:43:02 +0000 Subject: [PATCH 42/63] Tempo: fallback for intrinsic tags (#101677) * Add intrinsics fallback * Add test * Update tests * Prettier * Remove extra uniq --- .../tempo/SearchTraceQLEditor/utils.test.ts | 11 +++++++++-- .../tempo/SearchTraceQLEditor/utils.ts | 18 +++++++++++------- .../datasource/tempo/language_provider.test.ts | 9 +++++++-- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.test.ts b/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.test.ts index e76cdf168e6..57c2dadc2b1 100644 --- a/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.test.ts +++ b/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.test.ts @@ -3,12 +3,14 @@ import { uniq } from 'lodash'; import { TraceqlFilter, TraceqlSearchScope } from '../dataquery.gen'; import { TempoDatasource } from '../datasource'; import TempoLanguageProvider from '../language_provider'; +import { intrinsics } from '../traceql/traceql'; import { filterToQuerySection, generateQueryFromAdHocFilters, getAllTags, getFilteredTags, + getIntrinsicTags, getTagsByScope, getUnscopedTags, } from './utils'; @@ -94,7 +96,7 @@ describe('gets correct tags', () => { it('for all tags', () => { const tags = getAllTags(v2Tags); - expect(tags).toEqual(['cluster', 'container', 'db', 'duration', 'kind', 'name', 'status']); + expect(tags).toEqual(uniq(['cluster', 'container', 'db', 'duration', 'kind', 'name', 'status'].concat(intrinsics))); }); it('for tags by resource scope', () => { @@ -106,6 +108,11 @@ describe('gets correct tags', () => { const tags = getTagsByScope(v2Tags, TraceqlSearchScope.Span); expect(tags).toEqual(['db']); }); + + it('for intrinsic tags', () => { + const tags = getIntrinsicTags(v2Tags); + expect(tags).toEqual(testIntrinsics); + }); }); describe('filterToQuerySection returns the correct query section for a filter', () => { @@ -179,7 +186,7 @@ describe('filterToQuerySection returns the correct query section for a filter', }); export const emptyTags = []; -export const testIntrinsics = ['duration', 'kind', 'name', 'status']; +export const testIntrinsics = uniq(['duration', 'kind', 'name', 'status'].concat(intrinsics)); export const v1Tags = ['bar', 'foo']; export const v2Tags = [ { diff --git a/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.ts b/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.ts index e1a599e99b3..5b4313ce6f2 100644 --- a/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.ts +++ b/public/app/plugins/datasource/tempo/SearchTraceQLEditor/utils.ts @@ -7,6 +7,7 @@ import { VariableFormatID } from '@grafana/schema'; import { TraceqlFilter, TraceqlSearchScope } from '../dataquery.gen'; import { getEscapedSpanNames } from '../datasource'; import TempoLanguageProvider from '../language_provider'; +import { intrinsics } from '../traceql/traceql'; import { Scope } from '../types'; export const interpolateFilters = (filters: TraceqlFilter[], scopedVars?: ScopedVars) => { @@ -132,13 +133,16 @@ export const getUnscopedTags = (scopes: Scope[]) => { }; export const getIntrinsicTags = (scopes: Scope[]) => { - return uniq( - scopes - .map((scope: Scope) => - scope.name && scope.name === TraceqlSearchScope.Intrinsic && scope.tags ? scope.tags : [] - ) - .flat() - ); + let tags = scopes + .map((scope: Scope) => (scope.name && scope.name === TraceqlSearchScope.Intrinsic && scope.tags ? scope.tags : [])) + .flat(); + + // Add the default intrinsic tags to the list of tags. + // This is needed because the /api/v2/search/tags API + // may not always return all the default intrinsic tags + // but generally has the most up to date list. + tags = uniq(tags.concat(intrinsics)); + return tags; }; export const getAllTags = (scopes: Scope[]) => { diff --git a/public/app/plugins/datasource/tempo/language_provider.test.ts b/public/app/plugins/datasource/tempo/language_provider.test.ts index 9bd44f33bed..7aff5eb7b18 100644 --- a/public/app/plugins/datasource/tempo/language_provider.test.ts +++ b/public/app/plugins/datasource/tempo/language_provider.test.ts @@ -1,7 +1,10 @@ +import { uniq } from 'lodash'; + import { v1Tags, v2Tags } from './SearchTraceQLEditor/utils.test'; import { TraceqlSearchScope } from './dataquery.gen'; import { TempoDatasource } from './datasource'; import TempoLanguageProvider from './language_provider'; +import { intrinsics } from './traceql/traceql'; import { Scope } from './types'; describe('Language_provider', () => { @@ -15,7 +18,7 @@ describe('Language_provider', () => { it('for API v2 intrinsic tags', async () => { const lp = setup(undefined, v2Tags); const tags = lp.getMetricsSummaryTags(TraceqlSearchScope.Intrinsic); - expect(tags).toEqual(['duration', 'kind', 'name', 'status']); + expect(tags).toEqual(uniq(['duration', 'kind', 'name', 'status'].concat(intrinsics))); }); it('for API v2 resource tags', async () => { @@ -105,7 +108,9 @@ describe('Language_provider', () => { it('for API v2 tags', async () => { const lp = setup(undefined, v2Tags); const tags = lp.getAutocompleteTags(); - expect(tags).toEqual(['cluster', 'container', 'db', 'duration', 'kind', 'name', 'status']); + expect(tags).toEqual( + uniq(['cluster', 'container', 'db', 'duration', 'kind', 'name', 'status'].concat(intrinsics)) + ); }); }); From bbab62ce399c349e314148fd9603f15830a7ecd1 Mon Sep 17 00:00:00 2001 From: Steve Simpson Date: Tue, 11 Mar 2025 13:45:16 +0100 Subject: [PATCH 43/63] Alerting: Select remote write path dependent on metrics backend type. (#101891) The remote write path differs based on whether the data source is actually Prometheus, Mimir, Cortex, or an older version of Cortex. We do not want users to have to specify the path, so this change determines the path as best it can. It may be in the future we have to make this configurable per-datasource to cater for setups where it's impossible to determine the correct path. --- conf/defaults.ini | 3 - conf/sample.ini | 3 - .../fakes/fake_datasource_service.go | 11 ++- pkg/services/ngalert/ngalert.go | 8 +- .../ngalert/schedule/recording_rule_test.go | 11 ++- .../ngalert/writer/datasourcewriter.go | 85 +++++++++++++++-- .../ngalert/writer/datasourcewriter_test.go | 95 +++++++++++++++++-- pkg/services/ngalert/writer/testing.go | 12 +-- pkg/setting/setting_unified_alerting.go | 28 +++--- 9 files changed, 199 insertions(+), 57 deletions(-) diff --git a/conf/defaults.ini b/conf/defaults.ini index a216bb0792a..ee703f76d2a 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -1527,9 +1527,6 @@ timeout = 10s # Only has effect if the grafanaManagedRecordRulesDatasources feature toggle is enabled. default_datasource_uid = -# Suffix to apply to the data source URL for remote write requests. -remote_write_path_suffix = /push - # Optional custom headers to include in recording rule write requests. [recording_rules.custom_headers] # exampleHeader = exampleValue diff --git a/conf/sample.ini b/conf/sample.ini index 21ef0ad88c6..207fa535410 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -1509,9 +1509,6 @@ timeout = 30s # Only has effect if the grafanaManagedRecordRulesDatasources feature toggle is enabled. default_datasource_uid = -# Suffix to apply to the data source URL for remote write requests. -remote_write_path_suffix = /push - # Optional custom headers to include in recording rule write requests. [recording_rules.custom_headers] # exampleHeader = exampleValue diff --git a/pkg/services/datasources/fakes/fake_datasource_service.go b/pkg/services/datasources/fakes/fake_datasource_service.go index f117f7b4af8..43a71852c43 100644 --- a/pkg/services/datasources/fakes/fake_datasource_service.go +++ b/pkg/services/datasources/fakes/fake_datasource_service.go @@ -74,11 +74,12 @@ func (s *FakeDataSourceService) AddDataSource(ctx context.Context, cmd *datasour s.lastID = int64(len(s.DataSources) - 1) } dataSource := &datasources.DataSource{ - ID: s.lastID + 1, - Name: cmd.Name, - Type: cmd.Type, - UID: cmd.UID, - OrgID: cmd.OrgID, + ID: s.lastID + 1, + Name: cmd.Name, + Type: cmd.Type, + UID: cmd.UID, + OrgID: cmd.OrgID, + JsonData: cmd.JsonData, } s.DataSources = append(s.DataSources, dataSource) return dataSource, nil diff --git a/pkg/services/ngalert/ngalert.go b/pkg/services/ngalert/ngalert.go index 9f4a62656f6..690c58c291b 100644 --- a/pkg/services/ngalert/ngalert.go +++ b/pkg/services/ngalert/ngalert.go @@ -760,14 +760,12 @@ func createRecordingWriter(featureToggles featuremgmt.FeatureToggles, settings s if settings.Enabled { if featureToggles.IsEnabledGlobally(featuremgmt.FlagGrafanaManagedRecordingRulesDatasources) { cfg := writer.DatasourceWriterConfig{ - Timeout: settings.Timeout, - DefaultDatasourceUID: settings.DefaultDatasourceUID, - RemoteWritePathSuffix: settings.RemoteWritePathSuffix, + Timeout: settings.Timeout, + DefaultDatasourceUID: settings.DefaultDatasourceUID, } logger.Info("Setting up remote write using data sources", - "timeout", cfg.Timeout, "default_datasource_uid", cfg.DefaultDatasourceUID, - "remote_write_path_suffix", cfg.RemoteWritePathSuffix) + "timeout", cfg.Timeout, "default_datasource_uid", cfg.DefaultDatasourceUID) return writer.NewDatasourceWriter(cfg, datasourceService, httpClientProvider, clock, logger, m), nil } else { diff --git a/pkg/services/ngalert/schedule/recording_rule_test.go b/pkg/services/ngalert/schedule/recording_rule_test.go index 6979d8469b7..a3f2a90cbae 100644 --- a/pkg/services/ngalert/schedule/recording_rule_test.go +++ b/pkg/services/ngalert/schedule/recording_rule_test.go @@ -18,6 +18,7 @@ import ( "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient" + "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/expr" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/datasources" @@ -574,15 +575,15 @@ func setupDatasourceWriter(t *testing.T, target *writer.TestRemoteWriteTarget, r dss := &dsfakes.FakeDataSourceService{} p1, _ := dss.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{ - UID: dsUID, - Type: datasources.DS_PROMETHEUS, + UID: dsUID, + Type: datasources.DS_PROMETHEUS, + JsonData: simplejson.MustJson([]byte(`{"prometheusType":"Prometheus"}`)), }) p1.URL = target.DatasourceURL() cfg := writer.DatasourceWriterConfig{ - Timeout: time.Second * 5, - DefaultDatasourceUID: "", - RemoteWritePathSuffix: writer.RemoteWriteSuffix, + Timeout: time.Second * 5, + DefaultDatasourceUID: "", } return writer.NewDatasourceWriter(cfg, dss, provider, clock.NewMock(), diff --git a/pkg/services/ngalert/writer/datasourcewriter.go b/pkg/services/ngalert/writer/datasourcewriter.go index a69b157c80b..9be600ae157 100644 --- a/pkg/services/ngalert/writer/datasourcewriter.go +++ b/pkg/services/ngalert/writer/datasourcewriter.go @@ -5,6 +5,8 @@ import ( "errors" "fmt" "net/url" + "path" + "strings" "time" "github.com/benbjohnson/clock" @@ -35,9 +37,6 @@ type DatasourceWriterConfig struct { // This exists to cater for upgrading from old versions of Grafana, where rule // definitions may not have a target data source specified. DefaultDatasourceUID string - - // RemoteWritePathSuffix is the path suffix for remote write, normally /push. - RemoteWritePathSuffix string } type DatasourceWriter struct { @@ -78,6 +77,73 @@ func (w *DatasourceWriter) decrypt(ds *datasources.DataSource) (map[string]strin return decryptedJsonData, err } +func getPrometheusType(ds *datasources.DataSource) string { + if ds.JsonData == nil { + return "" + } + jsonData := ds.JsonData.Get("prometheusType") + if jsonData == nil { + return "" + } + str, err := jsonData.String() + if err != nil { + return "" + } + return str +} + +func getRemoteWriteURL(ds *datasources.DataSource) (*url.URL, error) { + u, err := url.Parse(ds.URL) + if err != nil { + return nil, err + } + + if getPrometheusType(ds) == "Prometheus" { + return u.JoinPath("/api/v1/write"), nil + } + + // All other cases assume Mimir/Cortex, as these systems are much more likely to be + // used as a remote write target, where as Prometheus does not recommend it. + + // Mimir/Cortex are more complicated, as Grafana has to be configured with the + // base URL for where the Prometheus API is located, e.g. /api/prom or /prometheus. + // + // - For "legacy" routes, /push is located on the same level as /api/v1/query. + // + // For example: + // Grafana will be configured with /api/prom + // The query API is at /api/prom/api/v1/query + // The push API is at /api/prom/push + // + // - For "new" routes, /push is located at the Mimir root, not Prometheus root. + // + // For example: + // Grafana will be configured with e.g. /prometheus + // The query API is at /prometheus/api/v1/query + // But push API is at /push + // + // Unfortunately, the prefixes can also be configured, + + cleanPath := path.Clean(u.Path) + + // If the suffix is /api/prom, assume Mimir/Cortex with legacy routes. + if strings.HasSuffix(cleanPath, "/api/prom") { + u.Path = path.Join(u.Path, "/push") + return u, nil + } + + // If the suffix is /prometheus, assume Mimir/Cortex with new routes. + if strings.HasSuffix(cleanPath, "/prometheus") { + u.Path = path.Join(path.Dir(u.Path), "/api/v1/push") + return u, nil + } + + // The user has configured an unknown prefix, so fall back to taking + // the host as the Mimir root. This is less than ideal. + u.Path = "/api/v1/push" + return u, nil +} + func (w *DatasourceWriter) makeWriter(ctx context.Context, orgID int64, dsUID string) (*PrometheusWriter, error) { ds, err := w.datasources.GetDataSource(ctx, &datasources.GetDataSourceQuery{ UID: dsUID, @@ -101,13 +167,11 @@ func (w *DatasourceWriter) makeWriter(ctx context.Context, orgID int64, dsUID st return nil, err } - u, err := url.Parse(is.URL) + u, err := getRemoteWriteURL(ds) if err != nil { return nil, err } - u = u.JoinPath(w.cfg.RemoteWritePathSuffix) - cfg := PrometheusWriterConfig{ URL: u.String(), HTTPOptions: httpclient.Options{ @@ -121,6 +185,15 @@ func (w *DatasourceWriter) makeWriter(ctx context.Context, orgID int64, dsUID st return nil, err } + w.l.Debug("Created Prometheus remote writer", + "datasource_uid", dsUID, + "type", ds.Type, + "prometheusType", getPrometheusType(ds), + "url", cfg.URL, + "tls", cfg.HTTPOptions.TLS != nil, + "basic_auth", cfg.HTTPOptions.BasicAuth != nil, + "timeout", cfg.Timeout) + return NewPrometheusWriter( cfg, w.httpClientProvider, diff --git a/pkg/services/ngalert/writer/datasourcewriter_test.go b/pkg/services/ngalert/writer/datasourcewriter_test.go index 6727d352997..165f735d10d 100644 --- a/pkg/services/ngalert/writer/datasourcewriter_test.go +++ b/pkg/services/ngalert/writer/datasourcewriter_test.go @@ -11,6 +11,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/infra/httpclient" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/services/datasources" @@ -43,16 +44,20 @@ func setupDataSources(t *testing.T) *testDataSources { }) p1, _ := res.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{ - UID: "prom-1", - Type: datasources.DS_PROMETHEUS, + UID: "prom-1", + Type: datasources.DS_PROMETHEUS, + JsonData: simplejson.MustJson([]byte(`{"prometheusType":"Prometheus"}`)), }) - p1.URL = res.prom1.srv.URL + "/api/v1" + p1.URL = res.prom1.srv.URL + res.prom1.ExpectedPath = "/api/v1/write" p2, _ := res.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{ - UID: "prom-2", - Type: datasources.DS_PROMETHEUS, + UID: "prom-2", + Type: datasources.DS_PROMETHEUS, + JsonData: simplejson.MustJson([]byte(`{"prometheusType":"Mimir"}`)), }) - p2.URL = res.prom2.srv.URL + "/api/v1" + p2.URL = res.prom2.srv.URL + "/api/prom" + res.prom2.ExpectedPath = "/api/prom/push" // Add a non-Prometheus datasource. _, _ = res.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{ @@ -70,9 +75,8 @@ func TestDatasourceWriter(t *testing.T) { datasources := setupDataSources(t) cfg := DatasourceWriterConfig{ - Timeout: time.Second * 5, - DefaultDatasourceUID: "prom-2", - RemoteWritePathSuffix: "/write", + Timeout: time.Second * 5, + DefaultDatasourceUID: "prom-2", } met := metrics.NewRemoteWriterMetrics(prometheus.NewRegistry()) @@ -117,3 +121,76 @@ func TestDatasourceWriter(t *testing.T) { require.NoError(t, err) }) } + +func TestDatasourceWriterGetRemoteWriteURL(t *testing.T) { + tc := []struct { + name string + ds datasources.DataSource + url string + }{ + { + "prometheus", + datasources.DataSource{ + JsonData: simplejson.MustJson([]byte(`{"prometheusType":"Prometheus"}`)), + URL: "http://example.com", + }, + "http://example.com/api/v1/write", + }, + { + "prometheus with prefix", + datasources.DataSource{ + JsonData: simplejson.MustJson([]byte(`{"prometheusType":"Prometheus"}`)), + URL: "http://example.com/myprom", + }, + "http://example.com/myprom/api/v1/write", + }, + { + "mimir/cortex legacy routes", + datasources.DataSource{ + JsonData: simplejson.MustJson([]byte(`{"prometheusType":"Anything"}`)), + URL: "http://example.com/api/prom", + }, + "http://example.com/api/prom/push", + }, + { + "mimir/cortex legacy routes with prefix", + datasources.DataSource{ + JsonData: simplejson.MustJson([]byte(`{"prometheusType":"Anything"}`)), + URL: "http://example.com/myprom/api/prom", + }, + "http://example.com/myprom/api/prom/push", + }, + { + "mimir/cortex new routes", + datasources.DataSource{ + JsonData: simplejson.MustJson([]byte(`{"prometheusType":"Anything"}`)), + URL: "http://example.com/prometheus", + }, + "http://example.com/api/v1/push", + }, + { + "mimir/cortex new routes with prefix", + datasources.DataSource{ + JsonData: simplejson.MustJson([]byte(`{"prometheusType":"Anything"}`)), + URL: "http://example.com/mymimir/prometheus", + }, + "http://example.com/mymimir/api/v1/push", + }, + { + "mimir/cortex with unknown suffix", + datasources.DataSource{ + JsonData: simplejson.MustJson([]byte(`{"prometheusType":"Anything"}`)), + URL: "http://example.com/foo/bar", + }, + "http://example.com/api/v1/push", + }, + } + + for _, tt := range tc { + t.Run(tt.name, func(t *testing.T) { + res, err := getRemoteWriteURL(&tt.ds) + require.NoError(t, err) + require.Equal(t, tt.url, res.String()) + }) + } +} diff --git a/pkg/services/ngalert/writer/testing.go b/pkg/services/ngalert/writer/testing.go index 1996e712247..2100c9cfc7a 100644 --- a/pkg/services/ngalert/writer/testing.go +++ b/pkg/services/ngalert/writer/testing.go @@ -12,10 +12,7 @@ import ( "github.com/stretchr/testify/require" ) -const RemoteWritePrefix = "/api/v1" -const RemoteWriteSuffix = "/write" - -const RemoteWriteEndpoint = RemoteWritePrefix + RemoteWriteSuffix +const RemoteWriteEndpoint = "/api/v1/write" type TestRemoteWriteTarget struct { srv *httptest.Server @@ -23,6 +20,8 @@ type TestRemoteWriteTarget struct { mtx sync.Mutex RequestsCount int LastRequestBody string + + ExpectedPath string } func NewTestRemoteWriteTarget(t *testing.T) *TestRemoteWriteTarget { @@ -31,10 +30,11 @@ func NewTestRemoteWriteTarget(t *testing.T) *TestRemoteWriteTarget { target := &TestRemoteWriteTarget{ RequestsCount: 0, LastRequestBody: "", + ExpectedPath: RemoteWriteEndpoint, } handler := func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path != RemoteWriteEndpoint { + if r.URL.Path != target.ExpectedPath { require.Fail(t, "Received unexpected request for endpoint %s", r.URL.Path) } @@ -63,7 +63,7 @@ func (s *TestRemoteWriteTarget) Close() { } func (s *TestRemoteWriteTarget) DatasourceURL() string { - return s.srv.URL + RemoteWritePrefix + return s.srv.URL } func (s *TestRemoteWriteTarget) ClientSettings() setting.RecordingRuleSettings { diff --git a/pkg/setting/setting_unified_alerting.go b/pkg/setting/setting_unified_alerting.go index bf359c34855..33f002cb571 100644 --- a/pkg/setting/setting_unified_alerting.go +++ b/pkg/setting/setting_unified_alerting.go @@ -132,14 +132,13 @@ type UnifiedAlertingSettings struct { } type RecordingRuleSettings struct { - Enabled bool - URL string - BasicAuthUsername string - BasicAuthPassword string - CustomHeaders map[string]string - Timeout time.Duration - DefaultDatasourceUID string - RemoteWritePathSuffix string + Enabled bool + URL string + BasicAuthUsername string + BasicAuthPassword string + CustomHeaders map[string]string + Timeout time.Duration + DefaultDatasourceUID string } // RemoteAlertmanagerSettings contains the configuration needed @@ -437,13 +436,12 @@ func (cfg *Cfg) ReadUnifiedAlertingSettings(iniFile *ini.File) error { rr := iniFile.Section("recording_rules") uaCfgRecordingRules := RecordingRuleSettings{ - Enabled: rr.Key("enabled").MustBool(false), - URL: rr.Key("url").MustString(""), - BasicAuthUsername: rr.Key("basic_auth_username").MustString(""), - BasicAuthPassword: rr.Key("basic_auth_password").MustString(""), - Timeout: rr.Key("timeout").MustDuration(defaultRecordingRequestTimeout), - DefaultDatasourceUID: rr.Key("default_datasource_uid").MustString(""), - RemoteWritePathSuffix: rr.Key("remote_write_path_suffix").MustString("/push"), + Enabled: rr.Key("enabled").MustBool(false), + URL: rr.Key("url").MustString(""), + BasicAuthUsername: rr.Key("basic_auth_username").MustString(""), + BasicAuthPassword: rr.Key("basic_auth_password").MustString(""), + Timeout: rr.Key("timeout").MustDuration(defaultRecordingRequestTimeout), + DefaultDatasourceUID: rr.Key("default_datasource_uid").MustString(""), } rrHeaders := iniFile.Section("recording_rules.custom_headers") From 2712686a368a18ec788e601d38c9235ac6e658bd Mon Sep 17 00:00:00 2001 From: Alex Bikfalvi Date: Tue, 11 Mar 2025 13:45:26 +0100 Subject: [PATCH 44/63] feat(datasource/Tempo): Instrument Tempo query latency measurements (#101285) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Instrument Tempo query latency measurements Add comprehensive latency tracking and reporting for Tempo queries using reportInteraction: - Add latency measurements for TraceQL metrics queries - Add latency measurements for TraceID queries - Add latency measurements for TraceQL search queries - Track both streaming and non-streaming query performance - Include success/error states and relevant metadata in reports - Measure latency in milliseconds for more precise tracking This instrumentation will help monitor query performance and identify potential bottlenecks in trace queries. Signed-off-by: Alex Bikfalvi * fixup! feat: Instrument Tempo query latency measurements Signed-off-by: Alex Bikfalvi * prettier fix --------- Signed-off-by: Alex Bikfalvi Co-authored-by: André Pereira --- .../plugins/datasource/tempo/datasource.ts | 216 +++++++++++++++++- 1 file changed, 210 insertions(+), 6 deletions(-) diff --git a/public/app/plugins/datasource/tempo/datasource.ts b/public/app/plugins/datasource/tempo/datasource.ts index ee8727ce74f..de07cc54e45 100644 --- a/public/app/plugins/datasource/tempo/datasource.ts +++ b/public/app/plugins/datasource/tempo/datasource.ts @@ -1,6 +1,6 @@ import { groupBy } from 'lodash'; import { EMPTY, forkJoin, from, lastValueFrom, merge, Observable, of } from 'rxjs'; -import { catchError, concatMap, map, mergeMap, toArray } from 'rxjs/operators'; +import { catchError, concatMap, finalize, map, mergeMap, toArray } from 'rxjs/operators'; import semver from 'semver'; import { @@ -97,6 +97,16 @@ interface ServiceMapQueryResponseWithRates { edges: DataFrame; } +interface TempoQueryMetrics { + success: boolean; + streaming?: boolean; + latencyMs: number; + query?: string; + error?: string; + statusCode?: number; + statusText?: string; +} + export class TempoDatasource extends DataSourceWithBackend { tracesToLogs?: TraceToLogsOptions; serviceMap?: { @@ -363,8 +373,7 @@ export class TempoDatasource extends DataSourceWithBackend { + reportTempoQueryMetrics('grafana_traces_traceql_response', options, { + success: true, + streaming: false, + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + query: queryFromFilters ?? '', + }); return { data: formatTraceQLResponse( response.data.traces, @@ -442,6 +458,15 @@ export class TempoDatasource extends DataSourceWithBackend { + reportTempoQueryMetrics('grafana_traces_traceql_response', options, { + success: false, + streaming: false, + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + query: queryFromFilters ?? '', + error: getErrorMessage(err.message), + statusCode: err.status, + statusText: err.statusText, + }); return of({ error: { message: getErrorMessage(err.data.message) }, data: [] }); }) ) @@ -569,7 +594,11 @@ export class TempoDatasource extends DataSourceWithBackend, targets: TempoQuery[]): Observable { + handleTraceIdQuery( + options: DataQueryRequest, + targets: TempoQuery[], + query: string + ): Observable { const validTargets = targets .filter((t) => t.query) .map((t): TempoQuery => ({ ...t, query: t.query?.trim(), queryType: 'traceId' })); @@ -577,13 +606,41 @@ export class TempoDatasource extends DataSourceWithBackend { if (response.error) { + reportTempoQueryMetrics('grafana_traces_traceID_response', options, { + success: false, + streaming: false, + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + query: query ?? '', + error: getErrorMessage(response.error.message), + statusCode: response.error.status, + statusText: response.error.statusText, + }); return response; } + reportTempoQueryMetrics('grafana_traces_traceID_response', options, { + success: true, + streaming: false, + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + query: query ?? '', + }); return transformTrace(response, this.instanceSettings, this.nodeGraph?.enabled); + }), + catchError((error) => { + reportTempoQueryMetrics('grafana_traces_traceID_response', options, { + success: false, + streaming: false, + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + query: query ?? '', + error: getErrorMessage(error.message), + statusCode: error.status, + statusText: error.statusText, + }); + throw error; }) ); } @@ -595,6 +652,7 @@ export class TempoDatasource extends DataSourceWithBackend => { + const startTime = performance.now(); if (this.isStreamingSearchEnabled()) { return this.handleStreamingQuery(options, targets.traceql, queryValue); } else { @@ -606,11 +664,26 @@ export class TempoDatasource extends DataSourceWithBackend { + reportTempoQueryMetrics('grafana_traces_traceql_response', options, { + success: true, + streaming: false, + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + query: queryValue ?? '', + }); return { data: formatTraceQLResponse(response.data.traces, this.instanceSettings, targets.traceql[0].tableType), }; }), catchError((err) => { + reportTempoQueryMetrics('grafana_traces_traceql_response', options, { + success: false, + streaming: false, + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + query: queryValue ?? '', + error: getErrorMessage(err.message), + statusCode: err.status, + statusText: err.statusText, + }); return of({ error: { message: getErrorMessage(err.data.message) }, data: [] }); }) ); @@ -619,7 +692,8 @@ export class TempoDatasource extends DataSourceWithBackend, - targets: TempoQuery[] + targets: TempoQuery[], + query: string ): Observable { const validTargets = targets .filter((t) => t.query) @@ -630,12 +704,28 @@ export class TempoDatasource extends DataSourceWithBackend { + reportTempoQueryMetrics('grafana_traces_traceql_metrics_response', options, { + success: true, + streaming: false, + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + query: query ?? '', + }); return enhanceTraceQlMetricsResponse(response, this.instanceSettings); }), catchError((err) => { + reportTempoQueryMetrics('grafana_traces_traceql_metrics_response', options, { + success: false, + streaming: false, + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + query: query ?? '', + error: getErrorMessage(err.data.message), + statusCode: err.status, + statusText: err.statusText, + }); return of({ error: { message: getErrorMessage(err.data.message) }, data: [] }); }) ); @@ -659,6 +749,7 @@ export class TempoDatasource extends DataSourceWithBackend { if (!response.data.summaries) { + reportTempoQueryMetrics('grafana_traces_metrics_summary_response', options, { + success: false, + streaming: false, + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + query: query ?? '', + error: getErrorMessage(`No summary data for '${groupBy}'.`), + }); return { error: { message: getErrorMessage(`No summary data for '${groupBy}'.`), @@ -678,6 +776,13 @@ export class TempoDatasource extends DataSourceWithBackend summary.series.length > 0); if (!hasSeries) { + reportTempoQueryMetrics('grafana_traces_metrics_summary_response', options, { + success: false, + streaming: false, + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + query: query ?? '', + error: getErrorMessage(`No series data. Ensure you are using an up to date version of Tempo`), + }); return { error: { message: getErrorMessage(`No series data. Ensure you are using an up to date version of Tempo`), @@ -685,11 +790,26 @@ export class TempoDatasource extends DataSourceWithBackend { + reportTempoQueryMetrics('grafana_traces_metrics_summary_response', options, { + success: false, + streaming: false, + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + query: query ?? '', + error: getErrorMessage(error.data.message), + statusCode: error.status, + statusText: error.statusText, + }); return of({ error: { message: getErrorMessage(error.data.message) }, data: emptyResponse, @@ -709,6 +829,7 @@ export class TempoDatasource extends DataSourceWithBackend doTempoSearchStreaming( @@ -718,6 +839,28 @@ export class TempoDatasource extends DataSourceWithBackend { + reportTempoQueryMetrics('grafana_traces_traceql_response', options, { + success: false, + streaming: true, + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + query: query ?? '', + error: getErrorMessage(error.data.message), + statusCode: error.status, + statusText: error.statusText, + }); + // Re-throw the error to maintain the error chain + throw error; + }), + finalize(() => { + reportTempoQueryMetrics('grafana_traces_traceql_response', options, { + success: true, + streaming: true, + query: query ?? '', + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + }); + }) ); } @@ -732,6 +875,7 @@ export class TempoDatasource extends DataSourceWithBackend doTempoMetricsStreaming( @@ -740,6 +884,28 @@ export class TempoDatasource extends DataSourceWithBackend { + reportTempoQueryMetrics('grafana_traces_traceql_metrics_response', options, { + success: false, + streaming: true, + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + query: query ?? '', + error: getErrorMessage(error.data.message), + statusCode: error.status, + statusText: error.statusText, + }); + // Re-throw the error to maintain the error chain + throw error; + }), + finalize(() => { + reportTempoQueryMetrics('grafana_traces_traceql_metrics_response', options, { + success: true, + streaming: true, + query: query ?? '', + latencyMs: Math.round(performance.now() - startTime), // rounded to nearest millisecond + }); + }) ); } @@ -1442,6 +1608,44 @@ function getServiceGraphViewDataFrames( return df; } +/** + * Reports metrics for Tempo query interactions. + * + * @param options - The data query request options containing app and other context + * @param metrics - Object containing metrics to report: + * - success: Whether the query was successful + * - streaming: (optional) Whether streaming was used + * - latencyMs: Query execution time in milliseconds + * - query: (optional) The query string that was executed + * - error: (optional) Error message if query failed + * - statusCode: (optional) HTTP status code if query failed + * - statusText: (optional) HTTP status text if query failed + * @param interactionName - (optional) Name of the interaction to report. + * Defaults to 'grafana_traces_traceql_response' + * + * @example + * ```typescript + * reportTempoQueryMetrics(options, { + * success: true, + * streaming: true, + * latencyMs: Math.round(performance.now() - startTime), + * query: 'my query' + * }); + * ``` + */ +function reportTempoQueryMetrics( + interactionName: string, + options: DataQueryRequest, + metrics: TempoQueryMetrics +) { + reportInteraction(interactionName, { + datasourceType: 'tempo', + app: options.app ?? '', + grafana_version: config.buildInfo.version, + ...metrics, + }); +} + export function buildExpr( metric: { expr: string; params: string[]; topk?: number }, extraParams: string, From 0519cfa66d6697aa9cc12a0063a01aefb9918423 Mon Sep 17 00:00:00 2001 From: Ed Poole Date: Tue, 11 Mar 2025 13:09:08 +0000 Subject: [PATCH 45/63] Fix/theme gradients (#101934) * Brighten the DesertBloom gradient * Adjust gradient values so they're consistently rgba --- .../grafana-data/src/themes/themeDefinitions/desertbloom.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/grafana-data/src/themes/themeDefinitions/desertbloom.ts b/packages/grafana-data/src/themes/themeDefinitions/desertbloom.ts index 0d8ce37e045..8c08ca75da1 100644 --- a/packages/grafana-data/src/themes/themeDefinitions/desertbloom.ts +++ b/packages/grafana-data/src/themes/themeDefinitions/desertbloom.ts @@ -61,9 +61,10 @@ const desertBloomTheme: NewThemeOptions = { disabledBackground: 'rgba(168, 156, 134, 0.06)', disabledOpacity: 0.38, }, + gradients: { - brandHorizontal: 'linear-gradient(270deg, #FF6F61 0%, #ece0d1 100%)', - brandVertical: 'linear-gradient(0.01deg, #FF6F61 0.01%, #ece0d1 99.99%)', + brandHorizontal: 'linear-gradient(270deg,rgba(255, 111, 97, 1) 0%, rgba(255, 167, 58, 1) 100%)', + brandVertical: 'linear-gradient(0deg, rgba(255, 111, 97, 1) 0%, rgba(255, 167, 58, 1) 100%)', }, contrastThreshold: 3, hoverFactor: 0.03, From 6b2c73141df74430eb72f1e6b6c166f5f896e715 Mon Sep 17 00:00:00 2001 From: Tom Ratcliffe Date: Tue, 11 Mar 2025 13:13:00 +0000 Subject: [PATCH 46/63] Alerting: Improve clarity of recording rule creation (#100700) * Add description below group and namespace fields to make creation clearer * Make DS managed recording rules clearer * Change link for recording rule on empty state to Grafana managed * Tweak empty state * Tidy up logic for display of recording rule buttons * Update .betterer.results --- .betterer.results | 6 +- .../rule-editor/GroupAndNamespaceFields.tsx | 15 +++- .../unified/components/rules/CloudRules.tsx | 5 +- .../unified/components/rules/NoRulesCTA.tsx | 69 ++++++++++++++++--- public/locales/en-US/grafana.json | 2 + 5 files changed, 82 insertions(+), 15 deletions(-) diff --git a/.betterer.results b/.betterer.results index b03dac144aa..4df170e7dc1 100644 --- a/.betterer.results +++ b/.betterer.results @@ -2387,10 +2387,8 @@ exports[`better eslint`] = { ], "public/app/features/alerting/unified/components/rules/CloudRules.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "3"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "4"] + [0, 0, 0, "No untranslated strings. Wrap text with ", "1"], + [0, 0, 0, "No untranslated strings. Wrap text with ", "2"] ], "public/app/features/alerting/unified/components/rules/EditRuleGroupModal.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], diff --git a/public/app/features/alerting/unified/components/rule-editor/GroupAndNamespaceFields.tsx b/public/app/features/alerting/unified/components/rule-editor/GroupAndNamespaceFields.tsx index dee970cf598..6bbac094cbb 100644 --- a/public/app/features/alerting/unified/components/rule-editor/GroupAndNamespaceFields.tsx +++ b/public/app/features/alerting/unified/components/rule-editor/GroupAndNamespaceFields.tsx @@ -45,6 +45,10 @@ export const GroupAndNamespaceFields = ({ rulesSourceName }: Props) => { @@ -71,7 +75,16 @@ export const GroupAndNamespaceFields = ({ rulesSourceName }: Props) => { }} /> - + ( - New recording rule + + New data source-managed recording rule + ); } diff --git a/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx b/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx index 38a4da4ce30..f33db5d9962 100644 --- a/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx +++ b/public/app/features/alerting/unified/components/rules/NoRulesCTA.tsx @@ -1,8 +1,65 @@ -import { EmptyState, LinkButton, Stack, TextLink } from '@grafana/ui'; -import { Trans } from 'app/core/internationalization'; +import { config } from '@grafana/runtime'; +import { Dropdown, EmptyState, LinkButton, Menu, MenuItem, Stack, TextLink } from '@grafana/ui'; +import { Trans, t } from 'app/core/internationalization'; import { useRulesAccess } from '../../utils/accessControlHooks'; +const RecordingRulesButtons = () => { + const { canCreateGrafanaRules, canCreateCloudRules } = useRulesAccess(); + const grafanaRecordingRulesEnabled = config.featureToggles.grafanaManagedRecordingRules; + const canCreateAll = canCreateGrafanaRules && canCreateCloudRules && grafanaRecordingRulesEnabled; + + // User can create Grafana and DS-managed recording rules, show a dropdown + if (canCreateAll) { + return ( + + + + + } + > + + New recording rule + + + ); + } + + // ...Otherwise, just show the buttons for each type of recording rule + // (this will just be one or the other) + return ( + <> + {canCreateGrafanaRules && grafanaRecordingRulesEnabled && ( + + + New Grafana-managed recording rule + + + )} + {canCreateCloudRules && ( + + + New data source-managed recording rule + + + )} + + ); +}; + export const NoRulesSplash = () => { const { canCreateGrafanaRules, canCreateCloudRules } = useRulesAccess(); const canCreateAnything = canCreateGrafanaRules || canCreateCloudRules; @@ -14,17 +71,13 @@ export const NoRulesSplash = () => { variant="call-to-action" button={ canCreateAnything ? ( - + {canCreateAnything && ( New alert rule )} - {canCreateCloudRules && ( - - New recording rule - - )} + ) : null } diff --git a/public/locales/en-US/grafana.json b/public/locales/en-US/grafana.json index ee429b59821..2deedc01267 100644 --- a/public/locales/en-US/grafana.json +++ b/public/locales/en-US/grafana.json @@ -379,6 +379,8 @@ "list-view": { "empty": { "new-alert-rule": "New alert rule", + "new-ds-managed-recording-rule": "New data source-managed recording rule", + "new-grafana-recording-rule": "New Grafana-managed recording rule", "new-recording-rule": "New recording rule", "provisioning": "You can also define rules through file provisioning or Terraform. <2>Learn more" }, From c74a5fcbedba9d0c4717ce0348065da3cb487d4f Mon Sep 17 00:00:00 2001 From: Will Browne Date: Tue, 11 Mar 2025 14:24:20 +0000 Subject: [PATCH 47/63] Chore: Avoid simplejson usage in `xorm` module (#101943) avoid simplejson usage --- pkg/util/xorm/go.mod | 2 -- pkg/util/xorm/go.sum | 4 ---- pkg/util/xorm/xorm_test.go | 7 +++---- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/pkg/util/xorm/go.mod b/pkg/util/xorm/go.mod index 310a1bbc263..fb55683da79 100644 --- a/pkg/util/xorm/go.mod +++ b/pkg/util/xorm/go.mod @@ -5,7 +5,6 @@ go 1.23.7 require ( cloud.google.com/go/spanner v1.75.0 github.com/googleapis/go-sql-spanner v1.11.1 - github.com/grafana/grafana v5.4.5+incompatible github.com/mattn/go-sqlite3 v1.14.22 github.com/stretchr/testify v1.10.0 xorm.io/builder v0.3.6 @@ -23,7 +22,6 @@ require ( cloud.google.com/go/monitoring v1.23.0 // indirect github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.2 // indirect github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.25.0 // indirect - github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect diff --git a/pkg/util/xorm/go.sum b/pkg/util/xorm/go.sum index 7febbb40654..f93449ff49b 100644 --- a/pkg/util/xorm/go.sum +++ b/pkg/util/xorm/go.sum @@ -632,8 +632,6 @@ github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kd github.com/apache/arrow/go/v10 v10.0.1/go.mod h1:YvhnlEePVnBS4+0z3fhPfUy7W1Ikj0Ih0vcRo/gZ1M0= github.com/apache/arrow/go/v11 v11.0.0/go.mod h1:Eg5OsL5H+e299f7u5ssuXsuHQVEGC4xei5aX110hRiI= github.com/apache/thrift v0.16.0/go.mod h1:PHK3hniurgQaNMZYaCLEqXKsYK8upmhPbmdP2FXSqgU= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -834,8 +832,6 @@ github.com/googleapis/go-sql-spanner v1.11.1 h1:z3ThtKV5HFvaNv9UGc26+ggS+lS0dsCA github.com/googleapis/go-sql-spanner v1.11.1/go.mod h1:fuA5q4yMS3SZiVfRr5bvksPNk7zUn/irbQW62H/ffZw= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/grafana/grafana v5.4.5+incompatible h1:xNuhSBxLgwDwesuQIAhQu1QCk6tD0TAghKHE36/hxrs= -github.com/grafana/grafana v5.4.5+incompatible/go.mod h1:U8QyUclJHj254BFcuw45p6sg7eeGYX44qn1ShYo5rGE= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w= diff --git a/pkg/util/xorm/xorm_test.go b/pkg/util/xorm/xorm_test.go index 4dee7eb8294..8b8d5aeb03b 100644 --- a/pkg/util/xorm/xorm_test.go +++ b/pkg/util/xorm/xorm_test.go @@ -1,12 +1,11 @@ package xorm import ( + "encoding/json" "testing" _ "github.com/mattn/go-sqlite3" "github.com/stretchr/testify/require" - - "github.com/grafana/grafana/pkg/components/simplejson" ) func TestBasicOperationsWithSqlite(t *testing.T) { @@ -38,7 +37,7 @@ func testBasicOperations(t *testing.T, eng *Engine) { require.NoError(t, err) require.NotZero(t, obj.Id) - obj.Json = simplejson.MustJson([]byte(`{"test": "test", "key": null}`)) + obj.Json = json.RawMessage(`{"test": "test", "key": null}`) _, err = sess.Update(obj) require.NoError(t, err) }) @@ -47,5 +46,5 @@ func testBasicOperations(t *testing.T, eng *Engine) { type TestStruct struct { Id int64 Comment string - Json *simplejson.Json + Json json.RawMessage } From d9cb6e632dfb9c36e9e72ce65959f260a60c69d5 Mon Sep 17 00:00:00 2001 From: Matthew Thorning Date: Tue, 11 Mar 2025 14:31:43 +0000 Subject: [PATCH 48/63] Navigation: Add the `IsNew` badge to the IRM menu item (#101926) add the `IsNew` badge to the IRM menu item --- pkg/services/navtree/navtreeimpl/applinks.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/services/navtree/navtreeimpl/applinks.go b/pkg/services/navtree/navtreeimpl/applinks.go index 4c71eb150ed..c3a385fd67d 100644 --- a/pkg/services/navtree/navtreeimpl/applinks.go +++ b/pkg/services/navtree/navtreeimpl/applinks.go @@ -239,6 +239,9 @@ func (s *ServiceImpl) addPluginToSection(c *contextmodel.ReqContext, treeRoot *n alertsAndIncidentsChildren = append(alertsAndIncidentsChildren, alertingNode) treeRoot.RemoveSection(alertingNode) } + if appLink.Id == "plugin-page-grafana-irm-app" { + appLink.IsNew = true + } alertsAndIncidentsChildren = append(alertsAndIncidentsChildren, appLink) treeRoot.AddSection(&navtree.NavLink{ Text: "Alerts & IRM", From 82610288b1170c0c7565c8e4b9134b8f6593c1eb Mon Sep 17 00:00:00 2001 From: Yulia Shanyrova Date: Tue, 11 Mar 2025 15:51:25 +0100 Subject: [PATCH 49/63] Plugins: Move raiseanissueurl from plugin object to plugin details (#101428) * move raiseanissueurl from plugin object to plugin details * updated the test for PluginDetailsPane; --- public/app/features/plugins/admin/api.ts | 1 + .../components/PluginDetailsPanel.test.tsx | 32 +++++++++++++++++++ .../admin/components/PluginDetailsPanel.tsx | 10 ++++-- public/app/features/plugins/admin/helpers.ts | 5 --- public/app/features/plugins/admin/types.ts | 3 +- 5 files changed, 42 insertions(+), 9 deletions(-) diff --git a/public/app/features/plugins/admin/api.ts b/public/app/features/plugins/admin/api.ts index f79968d47ae..4520989603f 100644 --- a/public/app/features/plugins/admin/api.ts +++ b/public/app/features/plugins/admin/api.ts @@ -39,6 +39,7 @@ export async function getPluginDetails(id: string): Promise=9.0.0', statusContext: 'stable', @@ -118,4 +134,20 @@ describe('PluginDetailsPanel', () => { const panel = screen.getByTestId('plugin-details-panel'); expect(panel).toHaveStyle({ width: '300px' }); }); + + it('should render license, documentation, repository, raise issue links', () => { + render(); + const repositoryLink = screen.getByText('Repository'); + const licenseLink = screen.getByText('License'); + const documentationLink = screen.getByText('Documentation'); + const raiseIssueLink = screen.getByText('Raise issue'); + expect(repositoryLink).toBeInTheDocument(); + expect(repositoryLink).toHaveAttribute('href', 'https://github.com/grafana/test-plugin'); + expect(licenseLink).toBeInTheDocument(); + expect(licenseLink).toHaveAttribute('href', 'https://github.com/grafana/test-plugin/blob/main/LICENSE'); + expect(documentationLink).toBeInTheDocument(); + expect(documentationLink).toHaveAttribute('href', 'https://test-plugin.com/docs'); + expect(raiseIssueLink).toBeInTheDocument(); + expect(raiseIssueLink).toHaveAttribute('href', 'https://github.com/grafana/test-plugin/issues/new'); + }); }); diff --git a/public/app/features/plugins/admin/components/PluginDetailsPanel.tsx b/public/app/features/plugins/admin/components/PluginDetailsPanel.tsx index 7d7612dc814..8440b37c76d 100644 --- a/public/app/features/plugins/admin/components/PluginDetailsPanel.tsx +++ b/public/app/features/plugins/admin/components/PluginDetailsPanel.tsx @@ -99,8 +99,14 @@ export function PluginDetailsPanel(props: Props): React.ReactElement | null { Repository )} - {plugin.raiseAnIssueUrl && ( - + {plugin.details?.raiseAnIssueUrl && ( + Raise an issue )} diff --git a/public/app/features/plugins/admin/helpers.ts b/public/app/features/plugins/admin/helpers.ts index 28386a73cbd..8b0bfe80cfd 100644 --- a/public/app/features/plugins/admin/helpers.ts +++ b/public/app/features/plugins/admin/helpers.ts @@ -122,7 +122,6 @@ export function mapRemoteToCatalog(plugin: RemotePlugin, error?: PluginError): C versionSignatureType, versionSignedByOrgName, url, - raiseAnIssueUrl, } = plugin; const isDisabled = !!error || isDisabledSecretsPlugin(typeCode); @@ -161,7 +160,6 @@ export function mapRemoteToCatalog(plugin: RemotePlugin, error?: PluginError): C isFullyInstalled: isDisabled, latestVersion: plugin.version, url, - raiseAnIssueUrl, }; } @@ -178,7 +176,6 @@ export function mapLocalToCatalog(plugin: LocalPlugin, error?: PluginError): Cat hasUpdate, accessControl, angularDetected, - raiseAnIssueUrl, } = plugin; const isDisabled = !!error || isDisabledSecretsPlugin(type); @@ -213,7 +210,6 @@ export function mapLocalToCatalog(plugin: LocalPlugin, error?: PluginError): Cat isFullyInstalled: true, iam: plugin.iam, latestVersion: plugin.latestVersion, - raiseAnIssueUrl, }; } @@ -278,7 +274,6 @@ export function mapToCatalogPlugin(local?: LocalPlugin, remote?: RemotePlugin, e iam: local?.iam, latestVersion: local?.latestVersion || remote?.version || '', url: remote?.url || '', - raiseAnIssueUrl: remote?.raiseAnIssueUrl || local?.raiseAnIssueUrl, }; } diff --git a/public/app/features/plugins/admin/types.ts b/public/app/features/plugins/admin/types.ts index 96e1d2451d2..4476c824216 100644 --- a/public/app/features/plugins/admin/types.ts +++ b/public/app/features/plugins/admin/types.ts @@ -65,7 +65,6 @@ export interface CatalogPlugin extends WithAccessControlMetadata { iam?: IdentityAccessManagement; isProvisioned?: boolean; url?: string; - raiseAnIssueUrl?: string; } export interface CatalogPluginDetails { @@ -83,6 +82,7 @@ export interface CatalogPluginDetails { lastCommitDate?: string; licenseUrl?: string; documentationUrl?: string; + raiseAnIssueUrl?: string; signatureType?: PluginSignatureType; signature?: PluginSignatureStatus; } @@ -197,7 +197,6 @@ export type LocalPlugin = WithAccessControlMetadata & { dependencies: PluginDependencies; angularDetected: boolean; iam?: IdentityAccessManagement; - raiseAnIssueUrl?: string; }; interface IdentityAccessManagement { From c8c17683ed9fdca0270086504db3258edd1b2998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Fern=C3=A1ndez?= Date: Tue, 11 Mar 2025 15:55:30 +0100 Subject: [PATCH 50/63] ThemeDemo: Use `Combobox` instead of `Select` (#101947) --- packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.tsx b/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.tsx index ba7146bcf23..0e6315899df 100644 --- a/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.tsx +++ b/packages/grafana-ui/src/components/ThemeDemos/ThemeDemo.tsx @@ -9,6 +9,7 @@ import { useTheme2 } from '../../themes/ThemeContext'; import { allButtonVariants, Button } from '../Button'; import { Card } from '../Card/Card'; import { CollapsableSection } from '../Collapse/CollapsableSection'; +import { Combobox } from '../Combobox/Combobox'; import { Field } from '../Forms/Field'; import { InlineField } from '../Forms/InlineField'; import { InlineFieldRow } from '../Forms/InlineFieldRow'; @@ -17,7 +18,6 @@ import { Icon } from '../Icon/Icon'; import { Input } from '../Input/Input'; import { BackgroundColor, BorderColor, Box, BoxShadow } from '../Layout/Box/Box'; import { Stack } from '../Layout/Stack/Stack'; -import { Select } from '../Select/Select'; import { Switch } from '../Switch/Switch'; import { Text, TextProps } from '../Text/Text'; @@ -150,8 +150,8 @@ export const ThemeDemo = () => { - - {}} /> + {}} /> ); From 5bfe046da957d32cfd57f0dd50d27c7eb28befef Mon Sep 17 00:00:00 2001 From: Pepe Cano <825430+ppcano@users.noreply.github.com> Date: Tue, 11 Mar 2025 15:58:25 +0100 Subject: [PATCH 53/63] docs(alerting): clarify behaviour when provisioning the policy tree (#101937) --- .../export-alerting-resources/index.md | 6 +----- .../file-provisioning/index.md | 6 +----- .../terraform-provisioning/index.md | 6 +----- docs/sources/shared/alerts/alerting_provisioning.md | 2 ++ docs/sources/shared/alerts/warning-provisioning-tree.md | 9 +++++++++ 5 files changed, 14 insertions(+), 15 deletions(-) create mode 100644 docs/sources/shared/alerts/warning-provisioning-tree.md diff --git a/docs/sources/alerting/set-up/provision-alerting-resources/export-alerting-resources/index.md b/docs/sources/alerting/set-up/provision-alerting-resources/export-alerting-resources/index.md index 3a6f3576452..a7fac56ebe9 100644 --- a/docs/sources/alerting/set-up/provision-alerting-resources/export-alerting-resources/index.md +++ b/docs/sources/alerting/set-up/provision-alerting-resources/export-alerting-resources/index.md @@ -197,11 +197,7 @@ However, you can export it by manually copying the content and name of the notif All notification policies are provisioned through a single resource: the root of the notification policy tree. -{{% admonition type="warning" %}} - -Since the policy tree is a single resource, provisioning it overwrites a policy tree created through any other means. - -{{< /admonition >}} +{{< docs/shared lookup="alerts/warning-provisioning-tree.md" source="grafana" version="" >}} To export the notification policy tree from the Grafana UI, complete the following steps. diff --git a/docs/sources/alerting/set-up/provision-alerting-resources/file-provisioning/index.md b/docs/sources/alerting/set-up/provision-alerting-resources/file-provisioning/index.md index 850600cc074..f7cb4a0e174 100644 --- a/docs/sources/alerting/set-up/provision-alerting-resources/file-provisioning/index.md +++ b/docs/sources/alerting/set-up/provision-alerting-resources/file-provisioning/index.md @@ -702,11 +702,7 @@ Create or reset the notification policy tree using provisioning files in your Gr In Grafana, the entire notification policy tree is considered a single, large resource. Add new specific policies as sub-policies under the root policy. Since specific policies may depend on each other, you cannot provision subsets of the policy tree; the entire tree must be defined in a single place. -{{% admonition type="warning" %}} - -Since the policy tree is a single resource, provisioning it will overwrite a policy tree created through any other means. - -{{< /admonition >}} +{{< docs/shared lookup="alerts/warning-provisioning-tree.md" source="grafana" version="" >}} 1. Find the notification policy tree in Grafana. 1. [Export](ref:export_policies) and download a provisioning file for your notification policy tree. diff --git a/docs/sources/alerting/set-up/provision-alerting-resources/terraform-provisioning/index.md b/docs/sources/alerting/set-up/provision-alerting-resources/terraform-provisioning/index.md index 0821f5ec0b4..2a5f5d97211 100644 --- a/docs/sources/alerting/set-up/provision-alerting-resources/terraform-provisioning/index.md +++ b/docs/sources/alerting/set-up/provision-alerting-resources/terraform-provisioning/index.md @@ -341,11 +341,7 @@ In this section, we'll create Terraform configurations for each alerting resourc [Notification policies](ref:notification-policy) defines how to route alert instances to your contact points. -{{% admonition type="warning" %}} - -Since the policy tree is a single resource, provisioning the `grafana_notification_policy` resource will overwrite a policy tree created through any other means. - -{{< /admonition >}} +{{< docs/shared lookup="alerts/warning-provisioning-tree.md" source="grafana" version="" >}} 1. Find the default notification policy tree. Alternatively, consider writing the resource in code as demonstrated in the example below. diff --git a/docs/sources/shared/alerts/alerting_provisioning.md b/docs/sources/shared/alerts/alerting_provisioning.md index 134bd086f97..40d3c72622d 100644 --- a/docs/sources/shared/alerts/alerting_provisioning.md +++ b/docs/sources/shared/alerts/alerting_provisioning.md @@ -1386,6 +1386,8 @@ Status: Conflict ### Sets the notification policy tree. (_RoutePutPolicyTree_) +{{< docs/shared lookup="alerts/warning-provisioning-tree.md" source="grafana" version="" >}} + ``` PUT /api/v1/provisioning/policies ``` diff --git a/docs/sources/shared/alerts/warning-provisioning-tree.md b/docs/sources/shared/alerts/warning-provisioning-tree.md new file mode 100644 index 00000000000..36ecf9b0fa6 --- /dev/null +++ b/docs/sources/shared/alerts/warning-provisioning-tree.md @@ -0,0 +1,9 @@ +--- +title: 'Warning Provisioning Tree' +--- + +{{% admonition type="warning" %}} + +Since the policy tree is a single resource, provisioning it will overwrite all policies in the notification policy tree. However, it does not affect internal policies created when alert rules directly select a contact point. + +{{< /admonition >}} From f6f6ae449615cfb866aed4afe53dc4a0cde83f25 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Tue, 11 Mar 2025 16:27:17 +0100 Subject: [PATCH 54/63] Zanzana: Update docs with subresources description (#101948) * Zanzana: Update docs with subresources description * clarify resource name --- pkg/services/authz/zanzana/schema/README.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/pkg/services/authz/zanzana/schema/README.md b/pkg/services/authz/zanzana/schema/README.md index 4462e0f18e0..3a41e96a11a 100644 --- a/pkg/services/authz/zanzana/schema/README.md +++ b/pkg/services/authz/zanzana/schema/README.md @@ -5,8 +5,8 @@ Here's some notes about [OpenFGA authorization model](https://openfga.dev/docs/m ## GroupResource level permissions A relation to a group_resource object grants access to all objects of the GroupResource. -They take the form of `{ “user”: “user:1”, relation: “read”, object:”group_resource:dashboard.grafana.app/dashboard” }`. This -example would grant `user:1` access to all `dashboard.grafana.app/dashboard` in the namespace. +They take the form of `{ “user”: “user:1”, relation: “read”, object:”group_resource:dashboard.grafana.app/dashboards” }`. This +example would grant `user:1` access to all `dashboard.grafana.app/dashboards` in the namespace. ## Folder level permissions @@ -20,11 +20,19 @@ This context holds all GroupResources in a list e.g. `{ "group_resources": ["das ## Resource level permissions -Most of our resource should use the generic resource type. +Most of our resource should use the generic resource type. -To grant a user direct access to a specific resource we store `{ “user”: “user:1”, relation: “read”, object:”resource:dashboard.grafana.app/dashboard/” }` with additional context. +To grant a user direct access to a specific resource we store `{ “user”: “user:1”, relation: “read”, object:”resource:dashboard.grafana.app/dashboards/” }` with additional context. This context store the GroupResource. `{ "group_resource": "dashboard.grafana.app/dashboards" }`. This is required so we can filter them out for list requests. +## Subresources + +Subresources enable more granular permissions for the resources. Example might be access to public dashboards or access to dashboard settings. + +To grant a user access to the subresource of the specific resource we store following tuple: `{ “user”: “user:1”, relation: “read”, object:”resource:dashboard.grafana.app/dashboards//” }` with additional context `{ "group_resource": "dashboard.grafana.app/dashboards/" }` + +It's also possible to grant user access to all subresources for specific resource type. It can be done with following tuple: `{ “user”: “user:1”, relation: “read”, object:”resource:dashboard.grafana.app/dashboards/” }`. + ## Managed permissions In the RBAC model managed permissions stored as a special "managed" role permissions. OpenFGA model allows to assign permissions directly to users, so it produces following tuples: @@ -58,4 +66,3 @@ type folder ``` According to the schema, user can get `read` access to folder if it has `read` relation granted directly to the folder or its parent folders. - From 13d1f0259762a9fb212b252ee7463cae606b008f Mon Sep 17 00:00:00 2001 From: Esteban Beltran Date: Tue, 11 Mar 2025 09:40:15 -0600 Subject: [PATCH 55/63] Frontend Sandbox: Do not perform authenticated queries for non authenticated users (#101946) * Do not perform authenticated queries for non authenticated users * Empty commit --- .../sandbox/sandbox_plugin_loader_registry.test.ts | 9 +++++++++ .../plugins/sandbox/sandbox_plugin_loader_registry.ts | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.test.ts b/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.test.ts index 8138baf6b6f..9e1f8a11b0d 100644 --- a/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.test.ts +++ b/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.test.ts @@ -1,5 +1,6 @@ import { PluginMeta, PluginSignatureStatus, PluginSignatureType } from '@grafana/data'; import { config } from '@grafana/runtime'; +import { contextSrv } from 'app/core/services/context_srv'; import { getPluginDetails } from '../admin/api'; import { CatalogPluginDetails } from '../admin/types'; @@ -30,6 +31,7 @@ jest.mock('../admin/api', () => ({ const getPluginSettingsMock = jest.mocked(getPluginSettings); const getPluginDetailsMock = jest.mocked(getPluginDetails); +const mockContextSrv = jest.mocked(contextSrv); const fakePluginSettings: PluginMeta = { id: 'test-plugin', @@ -45,6 +47,7 @@ describe('Sandbox eligibility checks', () => { jest.clearAllMocks(); getPluginDetailsMock.mockReset(); getPluginSettingsMock.mockReset(); + mockContextSrv.isSignedIn = true; // restore default check setSandboxEnabledCheck(isPluginFrontendSandboxEnabled); @@ -63,6 +66,12 @@ describe('Sandbox eligibility checks', () => { expect(result).toBe(false); }); + test('isPluginFrontendSandboxEligible returns false for unsigned users', async () => { + mockContextSrv.isSignedIn = false; + const isEligible = await isPluginFrontendSandboxEligible({ pluginId: 'test-plugin' }); + expect(isEligible).toBe(false); + }); + test('shouldLoadPluginInFrontendSandbox returns false when feature toggle is off', async () => { config.featureToggles.pluginsFrontendSandbox = false; const result = await shouldLoadPluginInFrontendSandbox({ pluginId: 'test-plugin' }); diff --git a/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.ts b/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.ts index 2dbef3be1e1..6001734a905 100644 --- a/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.ts +++ b/public/app/features/plugins/sandbox/sandbox_plugin_loader_registry.ts @@ -1,5 +1,6 @@ import { PluginSignatureType } from '@grafana/data'; import { config } from '@grafana/runtime'; +import { contextSrv } from 'app/core/core'; import { getPluginDetails } from '../admin/api'; import { getPluginSettings } from '../pluginSettings'; @@ -62,6 +63,10 @@ export async function isPluginFrontendSandboxEligible({ return false; } + if (!contextSrv.isSignedIn) { + return false; + } + // grafana signature and internal plugins are not allowed in the sandbox return isPluginSignatureEligibleForSandbox({ pluginId }); } From 59d87fe3f1c0dd59353e6176bf55bd4a3c37c0bf Mon Sep 17 00:00:00 2001 From: owensmallwood Date: Tue, 11 Mar 2025 10:15:58 -0600 Subject: [PATCH 56/63] Unified Storage: Use match all query instead of wildcard for not-in requirement query (#101953) use match all query insteaed of wildcard --- pkg/storage/unified/search/bleve.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/storage/unified/search/bleve.go b/pkg/storage/unified/search/bleve.go index 630c9832315..322abff0516 100644 --- a/pkg/storage/unified/search/bleve.go +++ b/pkg/storage/unified/search/bleve.go @@ -803,7 +803,7 @@ func requirementQuery(req *resource.Requirement, prefix string) (query.Query, *r boolQuery.AddMustNot(mustNotQueries...) // must still have a value - notEmptyQuery := bleve.NewWildcardQuery("*") + notEmptyQuery := bleve.NewMatchAllQuery() boolQuery.AddMust(notEmptyQuery) return boolQuery, nil From 7e4beb2074ae23e083312218c1177af35c815d80 Mon Sep 17 00:00:00 2001 From: Yuri Tseretyan Date: Tue, 11 Mar 2025 12:40:44 -0400 Subject: [PATCH 57/63] Alerting: API to return deleted rules (#101429) --- pkg/services/ngalert/api/api_ruler.go | 20 ++++ pkg/services/ngalert/api/persist.go | 1 + pkg/services/ngalert/store/alert_rule.go | 34 +++++++ pkg/services/ngalert/store/alert_rule_test.go | 57 +++++++++++ pkg/services/ngalert/tests/fakes/rules.go | 13 +++ pkg/tests/api/alerting/api_ruler_test.go | 98 +++++++++++++++++++ pkg/tests/api/alerting/testing.go | 10 ++ 7 files changed, 233 insertions(+) diff --git a/pkg/services/ngalert/api/api_ruler.go b/pkg/services/ngalert/api/api_ruler.go index 2d88ae849e1..e5ece7154e3 100644 --- a/pkg/services/ngalert/api/api_ruler.go +++ b/pkg/services/ngalert/api/api_ruler.go @@ -261,6 +261,26 @@ func (srv RulerSrv) RouteGetRulesGroupConfig(c *contextmodel.ReqContext, namespa // RouteGetRulesConfig returns all alert rules that are available to the current user func (srv RulerSrv) RouteGetRulesConfig(c *contextmodel.ReqContext) response.Response { + if strings.ToLower(c.Query("deleted")) == "true" { + if !srv.featureManager.IsEnabledGlobally(featuremgmt.FlagAlertRuleRestore) { + return ErrResp(http.StatusBadRequest, errors.New("restore of deleted rules is not enabled"), "") + } + if !c.SignedInUser.HasRole(identity.RoleAdmin) { + return ErrResp(http.StatusForbidden, errors.New("only admins can get deleted rules"), "") + } + rules, err := srv.store.ListDeletedRules(c.Req.Context(), c.SignedInUser.GetOrgID()) + if err != nil { + return ErrResp(http.StatusInternalServerError, err, "failed to get deleted rules") + } + result := apimodels.NamespaceConfigResponse{} + if len(rules) > 0 { + result[""] = []apimodels.GettableRuleGroupConfig{ + toGettableRuleGroupConfig("", rules, map[string]ngmodels.Provenance{}, srv.resolveUserIdToNameFn(c.Req.Context())), + } + } + return response.JSON(http.StatusOK, result) + } + namespaceMap, err := srv.store.GetUserVisibleNamespaces(c.Req.Context(), c.SignedInUser.GetOrgID(), c.SignedInUser) if err != nil { return ErrResp(http.StatusInternalServerError, err, "failed to get namespaces visible to the user") diff --git a/pkg/services/ngalert/api/persist.go b/pkg/services/ngalert/api/persist.go index b169be59c07..30b79b666dd 100644 --- a/pkg/services/ngalert/api/persist.go +++ b/pkg/services/ngalert/api/persist.go @@ -23,6 +23,7 @@ type RuleStore interface { GetAlertRuleByUID(ctx context.Context, query *ngmodels.GetAlertRuleByUIDQuery) (*ngmodels.AlertRule, error) GetAlertRulesGroupByRuleUID(ctx context.Context, query *ngmodels.GetAlertRulesGroupByRuleUIDQuery) ([]*ngmodels.AlertRule, error) ListAlertRules(ctx context.Context, query *ngmodels.ListAlertRulesQuery) (ngmodels.RulesGroup, error) + ListDeletedRules(ctx context.Context, orgID int64) ([]*ngmodels.AlertRule, error) // InsertAlertRules will insert all alert rules passed into the function // and return the map of uuid to id. diff --git a/pkg/services/ngalert/store/alert_rule.go b/pkg/services/ngalert/store/alert_rule.go index 47ab409c63a..d4fb0202a78 100644 --- a/pkg/services/ngalert/store/alert_rule.go +++ b/pkg/services/ngalert/store/alert_rule.go @@ -236,6 +236,40 @@ func (st DBstore) GetAlertRuleVersions(ctx context.Context, orgID int64, guid st return alertRules, nil } +// ListDeletedRules retrieves a list of deleted alert rules for the specified organization ID from the database. +// It ensures that only the latest version of each rule is included and filters out invalid or duplicated versions. +// Returns a slice of *models.AlertRule or an error if the operation fails. +func (st DBstore) ListDeletedRules(ctx context.Context, orgID int64) ([]*ngmodels.AlertRule, error) { + alertRules := make([]*ngmodels.AlertRule, 0) + err := st.SQLStore.WithDbSession(ctx, func(sess *db.Session) error { + // take only the latest versions of each rule by GUID + rows, err := sess.Table(alertRuleVersion{}).Where("rule_org_id = ? AND rule_uid = ''", orgID).Rows(alertRuleVersion{}) + if err != nil { + return err + } + // Deserialize each rule separately in case any of them contain invalid JSON. + for rows.Next() { + rule := new(alertRuleVersion) + err = rows.Scan(rule) + if err != nil { + st.Logger.Error("Invalid rule version found in DB store, ignoring it", "func", "GetAlertRuleVersions", "error", err) + continue + } + converted, err := alertRuleToModelsAlertRule(alertRuleVersionToAlertRule(*rule), st.Logger) + if err != nil { + st.Logger.Error("Invalid rule found in DB store, cannot convert, ignoring it", "func", "GetAlertRuleVersions", "error", err, "version_id", rule.ID) + continue + } + alertRules = append(alertRules, &converted) + } + return nil + }) + if err != nil { + return nil, err + } + return alertRules, nil +} + // GetRuleByID retrieves models.AlertRule by ID. // It returns models.ErrAlertRuleNotFound if no alert rule is found for the provided ID. func (st DBstore) GetRuleByID(ctx context.Context, query ngmodels.GetAlertRuleByIDQuery) (result *ngmodels.AlertRule, err error) { diff --git a/pkg/services/ngalert/store/alert_rule_test.go b/pkg/services/ngalert/store/alert_rule_test.go index 2b6d7d76971..c3e94e7e806 100644 --- a/pkg/services/ngalert/store/alert_rule_test.go +++ b/pkg/services/ngalert/store/alert_rule_test.go @@ -1954,6 +1954,63 @@ func TestIntegration_ListAlertRules(t *testing.T) { }) } +func TestIntegration_ListDeletedRules(t *testing.T) { + if testing.Short() { + t.Skip("skipping integration test") + } + cfg := setting.NewCfg() + cfg.UnifiedAlerting = setting.UnifiedAlertingSettings{ + BaseInterval: 1 * time.Second, + RuleVersionRecordLimit: -1, + } + sqlStore := db.InitTestDB(t) + folderService := setupFolderService(t, sqlStore, cfg, featuremgmt.WithFeatures()) + b := &fakeBus{} + store := createTestStore(sqlStore, folderService, &logtest.Fake{}, cfg.UnifiedAlerting, b) + store.FeatureToggles = featuremgmt.WithFeatures(featuremgmt.FlagAlertRuleRestore) + + orgID := int64(1) + gen := models.RuleGen + gen = gen.With(gen.WithIntervalMatching(store.Cfg.BaseInterval), gen.WithOrgID(orgID)) + + result, err := store.InsertAlertRules(context.Background(), &models.AlertingUserUID, []models.AlertRule{gen.Generate()}) + require.NoError(t, err) + rule, err := store.GetAlertRuleByUID(context.Background(), &models.GetAlertRuleByUIDQuery{UID: result[0].UID}) + require.NoError(t, err) + + rule2 := models.CopyRule(rule, gen.WithTitle(util.GenerateShortUID())) + err = store.UpdateAlertRules(context.Background(), &models.AlertingUserUID, []models.UpdateRule{ + { + Existing: rule, + New: *rule2, + }, + }) + require.NoError(t, err) + rule2, err = store.GetAlertRuleByUID(context.Background(), &models.GetAlertRuleByUIDQuery{UID: result[0].UID}) + require.NoError(t, err) + + versions, err := store.GetAlertRuleVersions(context.Background(), orgID, rule.GUID) + require.NoError(t, err) + require.Len(t, versions, 2) + + t.Run("should not return if rule is not deleted", func(t *testing.T) { + list, err := store.ListDeletedRules(context.Background(), orgID) + require.NoError(t, err) + require.Empty(t, list) + }) + + err = store.DeleteAlertRulesByUID(context.Background(), orgID, &models.AlertingUserUID, rule.UID) + require.NoError(t, err) + + t.Run("should return the last deleted rule", func(t *testing.T) { + list, err := store.ListDeletedRules(context.Background(), orgID) + require.NoError(t, err) + require.Len(t, list, 1) + assert.Empty(t, list[0].UID) + assert.Empty(t, rule2.Diff(list[0], "ID", "UID", "DashboardUID", "PanelID")) + }) +} + func createTestStore( sqlStore db.DB, folderService folder.Service, diff --git a/pkg/services/ngalert/tests/fakes/rules.go b/pkg/services/ngalert/tests/fakes/rules.go index 10bc282e8a8..24d9959a0e2 100644 --- a/pkg/services/ngalert/tests/fakes/rules.go +++ b/pkg/services/ngalert/tests/fakes/rules.go @@ -24,6 +24,7 @@ type RuleStore struct { // OrgID -> RuleGroup -> Namespace -> Rules Rules map[int64][]*models.AlertRule History map[string][]*models.AlertRule + Deleted map[int64][]*models.AlertRule Hook func(cmd any) error // use Hook if you need to intercept some query and return an error RecordedOps []any Folders map[int64][]*folder.Folder @@ -460,3 +461,15 @@ func (f *RuleStore) GetAlertRuleVersions(_ context.Context, orgID int64, guid st return f.History[guid], nil } + +func (f *RuleStore) ListDeletedRules(_ context.Context, orgID int64) ([]*models.AlertRule, error) { + f.mtx.Lock() + defer f.mtx.Unlock() + defer func() { + f.RecordedOps = append(f.RecordedOps, GenericRecordedQuery{Name: "ListDeletedRules", Params: []any{orgID}}) + }() + if err := f.Hook(orgID); err != nil { + return nil, err + } + return f.Deleted[orgID], nil +} diff --git a/pkg/tests/api/alerting/api_ruler_test.go b/pkg/tests/api/alerting/api_ruler_test.go index 9f03a070f53..3cdf2d2a20f 100644 --- a/pkg/tests/api/alerting/api_ruler_test.go +++ b/pkg/tests/api/alerting/api_ruler_test.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "io" + "maps" "math/rand" "net/http" "path" @@ -15,6 +16,7 @@ import ( "time" "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" "github.com/grafana/grafana-plugin-sdk-go/data" "github.com/prometheus/alertmanager/pkg/labels" @@ -4645,6 +4647,102 @@ func TestIntegrationRuleVersions(t *testing.T) { }) } +func TestIntegrationRuleSoftDelete(t *testing.T) { + testinfra.SQLiteIntegrationTest(t) + + // Setup Grafana and its Database + dir, p := testinfra.CreateGrafDir(t, testinfra.GrafanaOpts{ + DisableLegacyAlerting: true, + EnableUnifiedAlerting: true, + EnableQuota: true, + DisableAnonymous: true, + AppModeProduction: true, + EnableFeatureToggles: []string{featuremgmt.FlagAlertRuleRestore}, + }) + + grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, p) + + createUser(t, env.SQLStore, env.Cfg, user.CreateUserCommand{ + DefaultOrgRole: string(org.RoleAdmin), + Password: "admin", + Login: "admin", + }) + + createUser(t, env.SQLStore, env.Cfg, user.CreateUserCommand{ + DefaultOrgRole: string(org.RoleEditor), + Password: "password", + Login: "editor", + }) + + adminClient := newAlertingApiClient(grafanaListedAddr, "admin", "admin") + editorClient := newAlertingApiClient(grafanaListedAddr, "editor", "password") + + deleted, status, data := adminClient.GetDeletedRulesWithStatus(t) + requireStatusCode(t, http.StatusOK, status, data) + require.Emptyf(t, deleted, "Expected empty list of deleted rules, got %v", deleted) + + // Create the namespace we'll save our alerts to. + adminClient.CreateFolder(t, "folder1", "folder1") + + var group apimodels.RuleGroupConfigResponse + { // create rules and some history + postGroupRaw, err := testData.ReadFile(path.Join("test-data", "rulegroup-1-post.json")) + require.NoError(t, err) + var group1 apimodels.PostableRuleGroupConfig + require.NoError(t, json.Unmarshal(postGroupRaw, &group1)) + + // Create rule under folder1 + response := adminClient.PostRulesGroup(t, "folder1", &group1) + require.NotEmptyf(t, response.Created, "Expected created to be set") + + // create some versions of the rule + for i := 0; i < 3; i++ { + groups, status := adminClient.GetRulesGroup(t, "folder1", group1.Name) + require.Equal(t, http.StatusAccepted, status) + group1 = convertGettableRuleGroupToPostable(groups.GettableRuleGroupConfig) + group1.Rules[0].Annotations[util.GenerateShortUID()] = util.GenerateShortUID() + _ = adminClient.PostRulesGroup(t, "folder1", &group1) + } + group, status = adminClient.GetRulesGroup(t, "folder1", group1.Name) + require.Equal(t, http.StatusAccepted, status) + } + + // deleting group by using editor user + status, body := editorClient.DeleteRulesGroup(t, "folder1", group.Name) + require.Equalf(t, http.StatusAccepted, status, "failed to delete group. Response: %s", body) + + t.Run("should see deleted rules", func(t *testing.T) { + rules, status, raw := adminClient.GetDeletedRulesWithStatus(t) + requireStatusCode(t, http.StatusOK, status, raw) + + require.Containsf(t, rules, "", "All rules should be in empty folder but got %v", slices.Collect(maps.Keys(rules))) + require.Lenf(t, rules[""], 1, "All deleted rules should be in single group but got %d", len(rules[""])) + require.Equalf(t, "", rules[""][0].Name, "All deleted rules should be in empty group but got %v", rules[""][0].Name) + + require.Len(t, rules[""][0].Rules, len(group.Rules)) + require.Empty(t, cmp.Diff(group.Rules, rules[""][0].Rules, cmpopts.IgnoreFields(apimodels.GettableGrafanaRule{}, "UID", "Version", "Updated", "UpdatedBy"))) + rule := rules[""][0].Rules[0] + require.Equalf(t, "editor", rule.GrafanaManagedAlert.UpdatedBy.Name, "Field 'UpdatedBy' should be set by editor but got %v ", rule.GrafanaManagedAlert.UpdatedBy) + }) + + t.Run("only admin should be able to see deleted rules", func(t *testing.T) { + t.Run("editor", func(t *testing.T) { + _, status, raw := editorClient.GetDeletedRulesWithStatus(t) + requireStatusCode(t, http.StatusForbidden, status, raw) + }) + t.Run("viewer", func(t *testing.T) { + createUser(t, env.SQLStore, env.Cfg, user.CreateUserCommand{ + DefaultOrgRole: string(org.RoleViewer), + Password: "password", + Login: "viewer", + }) + client := newAlertingApiClient(grafanaListedAddr, "viewer", "password") + _, status, raw := client.GetDeletedRulesWithStatus(t) + requireStatusCode(t, http.StatusForbidden, status, raw) + }) + }) +} + func newTestingRuleConfig(t *testing.T) apimodels.PostableRuleGroupConfig { interval, err := model.ParseDuration("1m") require.NoError(t, err) diff --git a/pkg/tests/api/alerting/testing.go b/pkg/tests/api/alerting/testing.go index f613d7a5547..25a25fd4e58 100644 --- a/pkg/tests/api/alerting/testing.go +++ b/pkg/tests/api/alerting/testing.go @@ -647,6 +647,16 @@ func (a apiClient) GetAllRulesWithStatus(t *testing.T) (apimodels.NamespaceConfi return result, resp.StatusCode, b } +func (a apiClient) GetDeletedRulesWithStatus(t *testing.T) (apimodels.NamespaceConfigResponse, int, string) { + t.Helper() + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/api/ruler/grafana/api/v1/rules", a.url), nil) + require.NoError(t, err) + q := req.URL.Query() + q.Add("deleted", "true") + req.URL.RawQuery = q.Encode() + return sendRequestJSON[apimodels.NamespaceConfigResponse](t, req, http.StatusOK) +} + func (a apiClient) ExportRulesWithStatus(t *testing.T, params *apimodels.AlertRulesExportParameters) (int, string) { t.Helper() u, err := url.Parse(fmt.Sprintf("%s/api/ruler/grafana/api/v1/export/rules", a.url)) From 42ae2fb02695281956e3787f7dbaa0cbb58e6d08 Mon Sep 17 00:00:00 2001 From: Will Assis <35489495+gassiss@users.noreply.github.com> Date: Tue, 11 Mar 2025 13:56:34 -0300 Subject: [PATCH 58/63] fix(unified-storage): add missing dashboard legacy_id when in legacy read mode (#101944) * add missing dashboard legacy_id when in modes 0-2 --- .../dashboard/legacysearcher/search_client.go | 8 +++++- .../legacysearcher/search_client_test.go | 27 ++++++++++++++++--- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/pkg/registry/apis/dashboard/legacysearcher/search_client.go b/pkg/registry/apis/dashboard/legacysearcher/search_client.go index 1f98dc3a1e1..c80919971c6 100644 --- a/pkg/registry/apis/dashboard/legacysearcher/search_client.go +++ b/pkg/registry/apis/dashboard/legacysearcher/search_client.go @@ -213,6 +213,11 @@ func (c *DashboardSearchClient) Search(ctx context.Context, req *resource.Resour searchFields.Field(resource.SEARCH_FIELD_TITLE), searchFields.Field(resource.SEARCH_FIELD_FOLDER), searchFields.Field(resource.SEARCH_FIELD_TAGS), + { + Name: unisearch.DASHBOARD_LEGACY_ID, + Type: resource.ResourceTableColumnDefinition_INT64, + Description: "Deprecated legacy id of the dashboard", + }, { Name: sortByField, Type: resource.ResourceTableColumnDefinition_INT64, @@ -270,7 +275,7 @@ func (c *DashboardSearchClient) Search(ctx context.Context, req *resource.Resour list.Results.Rows = append(list.Results.Rows, &resource.ResourceTableRow{ Key: getResourceKey(dashboard, req.Options.Key.Namespace), - Cells: [][]byte{[]byte(dashboard.Title), []byte(dashboard.FolderUID), tags, []byte(strconv.FormatInt(dashboard.SortMeta, 10))}, + Cells: [][]byte{[]byte(dashboard.Title), []byte(dashboard.FolderUID), tags, []byte(strconv.FormatInt(dashboard.ID, 10)), []byte(strconv.FormatInt(dashboard.SortMeta, 10))}, }) } @@ -306,6 +311,7 @@ func formatQueryResult(res []dashboards.DashboardSearchProjection) []*dashboards hit, exists := hits[key] if !exists { hit = &dashboards.DashboardSearchProjection{ + ID: item.ID, UID: item.UID, Title: item.Title, FolderUID: item.FolderUID, diff --git a/pkg/registry/apis/dashboard/legacysearcher/search_client_test.go b/pkg/registry/apis/dashboard/legacysearcher/search_client_test.go index 4b56d2e9b6f..ffbc973ba07 100644 --- a/pkg/registry/apis/dashboard/legacysearcher/search_client_test.go +++ b/pkg/registry/apis/dashboard/legacysearcher/search_client_test.go @@ -43,8 +43,8 @@ func TestDashboardSearchClient_Search(t *testing.T) { Type: "dash-db", // should set type based off of key Sort: sorter, }).Return([]dashboards.DashboardSearchProjection{ - {UID: "uid", Title: "Test Dashboard", FolderUID: "folder1", Term: "term"}, - {UID: "uid2", Title: "Test Dashboard2", FolderUID: "folder2"}, + {ID: 1, UID: "uid", Title: "Test Dashboard", FolderUID: "folder1", Term: "term"}, + {ID: 2, UID: "uid2", Title: "Test Dashboard2", FolderUID: "folder2"}, }, nil).Once() req := &resource.ResourceSearchRequest{ @@ -72,6 +72,11 @@ func TestDashboardSearchClient_Search(t *testing.T) { searchFields.Field(resource.SEARCH_FIELD_TITLE), searchFields.Field(resource.SEARCH_FIELD_FOLDER), searchFields.Field(resource.SEARCH_FIELD_TAGS), + { + Name: unisearch.DASHBOARD_LEGACY_ID, + Type: resource.ResourceTableColumnDefinition_INT64, + Description: "Deprecated legacy id of the dashboard", + }, { Name: "", // sort by should be empty if title is what we sorted by Type: resource.ResourceTableColumnDefinition_INT64, @@ -88,6 +93,7 @@ func TestDashboardSearchClient_Search(t *testing.T) { []byte("Test Dashboard"), []byte("folder1"), tags, + []byte("1"), []byte(strconv.FormatInt(0, 10)), }, }, @@ -101,6 +107,7 @@ func TestDashboardSearchClient_Search(t *testing.T) { []byte("Test Dashboard2"), []byte("folder2"), emptyTags, + []byte("2"), []byte(strconv.FormatInt(0, 10)), }, }, @@ -120,7 +127,7 @@ func TestDashboardSearchClient_Search(t *testing.T) { Type: "dash-db", Sort: sortOptionAsc, }).Return([]dashboards.DashboardSearchProjection{ - {UID: "uid", Title: "Test Dashboard", FolderUID: "folder", SortMeta: int64(50)}, + {ID: 1, UID: "uid", Title: "Test Dashboard", FolderUID: "folder", SortMeta: int64(50)}, }, nil).Once() req := &resource.ResourceSearchRequest{ @@ -145,6 +152,11 @@ func TestDashboardSearchClient_Search(t *testing.T) { searchFields.Field(resource.SEARCH_FIELD_TITLE), searchFields.Field(resource.SEARCH_FIELD_FOLDER), searchFields.Field(resource.SEARCH_FIELD_TAGS), + { + Name: unisearch.DASHBOARD_LEGACY_ID, + Type: resource.ResourceTableColumnDefinition_INT64, + Description: "Deprecated legacy id of the dashboard", + }, { Name: "views_total", Type: resource.ResourceTableColumnDefinition_INT64, @@ -161,6 +173,7 @@ func TestDashboardSearchClient_Search(t *testing.T) { []byte("Test Dashboard"), []byte("folder"), emptyTags, + []byte("1"), []byte(strconv.FormatInt(50, 10)), }, }, @@ -180,7 +193,7 @@ func TestDashboardSearchClient_Search(t *testing.T) { Type: "dash-db", Sort: sortOptionAsc, }).Return([]dashboards.DashboardSearchProjection{ - {UID: "uid", Title: "Test Dashboard", FolderUID: "folder", SortMeta: int64(2)}, + {ID: 1, UID: "uid", Title: "Test Dashboard", FolderUID: "folder", SortMeta: int64(2)}, }, nil).Once() req := &resource.ResourceSearchRequest{ @@ -205,6 +218,11 @@ func TestDashboardSearchClient_Search(t *testing.T) { searchFields.Field(resource.SEARCH_FIELD_TITLE), searchFields.Field(resource.SEARCH_FIELD_FOLDER), searchFields.Field(resource.SEARCH_FIELD_TAGS), + { + Name: unisearch.DASHBOARD_LEGACY_ID, + Type: resource.ResourceTableColumnDefinition_INT64, + Description: "Deprecated legacy id of the dashboard", + }, { Name: "errors_last_30_days", Type: resource.ResourceTableColumnDefinition_INT64, @@ -221,6 +239,7 @@ func TestDashboardSearchClient_Search(t *testing.T) { []byte("Test Dashboard"), []byte("folder"), emptyTags, + []byte("1"), []byte(strconv.FormatInt(2, 10)), }, }, From 7a3415148e579c102c0d0f171c0fb26fbe6ac58c Mon Sep 17 00:00:00 2001 From: Sam Jewell <2903904+samjewell@users.noreply.github.com> Date: Tue, 11 Mar 2025 17:14:33 +0000 Subject: [PATCH 59/63] SQL Expressions: Add cell-limit for input dataframes (#101700) * expr: Add row limit to SQL expressions Adds a configurable row limit to SQL expressions to prevent memory issues with large result sets. The limit is configured via the `sql_expression_row_limit` setting in the `[expressions]` section of grafana.ini, with a default of 100,000 rows. The limit is enforced by checking the total number of rows across all input tables before executing the SQL query. If the total exceeds the limit, the query fails with an error message indicating the limit was exceeded. * revert addition of newline * Switch to table-driven tests * Remove single-frame test-cases. We only need to test for the multi frame case. Single frame is a subset of the multi-frame case * Add helper function Simplify the way tests are set up and written * Support convention, that limit: 0 is no limit * Set the row-limit in one place only * Update default limit to 20k rows As per some discussion here: https://raintank-corp.slack.com/archives/C071A5XCFST/p1741611647001369?thread_ts=1740047619.804869&cid=C071A5XCFST * Test row-limit is applied from config Make sure we protect this from regressions This is perhaps a brittle test, somewhat coupled to the code here. But it's good enough to prevent regressions at least. * Add public documentation for the limit * Limit total number of cells instead of rows * Use named-return for totalRows As @kylebrandt requested during review of #101700 * Leave DF cells as zero values during limits tests When testing the cell limit we don't interact with the cell values at all, so we leave them at their zero values both to speed up tests, and to simplify and clarify that their values aren't used. * Set SQLCmd limit at object creation - don't mutate * Test that SQL node receives limit when built And that it receives it from the Grafana config * Improve TODO message for new Expression Parser * Fix failing test by always creating config on the Service --- .../setup-grafana/configure-grafana/_index.md | 4 + pkg/expr/graph.go | 2 +- pkg/expr/graph_test.go | 2 + pkg/expr/nodes.go | 4 +- pkg/expr/reader.go | 4 +- pkg/expr/service_test.go | 65 ++++++++ pkg/expr/sql_command.go | 38 ++++- pkg/expr/sql_command_test.go | 142 +++++++++++++++++- pkg/setting/setting.go | 4 + 9 files changed, 253 insertions(+), 12 deletions(-) diff --git a/docs/sources/setup-grafana/configure-grafana/_index.md b/docs/sources/setup-grafana/configure-grafana/_index.md index 5c7b92515ec..9f16b072e63 100644 --- a/docs/sources/setup-grafana/configure-grafana/_index.md +++ b/docs/sources/setup-grafana/configure-grafana/_index.md @@ -2753,6 +2753,10 @@ Set the default start of the week, valid values are: `saturday`, `sunday`, `mond Set this to `false` to disable expressions and hide them in the Grafana UI. Default is `true`. +#### `sql_expression_cell_limit` + +Set the maximum number of cells that can be passed to a SQL expression. Default is `100000`. + ### `[geomap]` This section controls the defaults settings for **Geomap Plugin**. diff --git a/pkg/expr/graph.go b/pkg/expr/graph.go index 6632a6b74c1..ae0ec6f9660 100644 --- a/pkg/expr/graph.go +++ b/pkg/expr/graph.go @@ -277,7 +277,7 @@ func (s *Service) buildGraph(req *Request) (*simple.DirectedGraph, error) { case TypeDatasourceNode: node, err = s.buildDSNode(dp, rn, req) case TypeCMDNode: - node, err = buildCMDNode(rn, s.features) + node, err = buildCMDNode(rn, s.features, s.cfg.SQLExpressionCellLimit) case TypeMLNode: if s.features.IsEnabledGlobally(featuremgmt.FlagMlExpressions) { node, err = s.buildMLNode(dp, rn, req) diff --git a/pkg/expr/graph_test.go b/pkg/expr/graph_test.go index fafca8f6876..dfa9f5f5b0a 100644 --- a/pkg/expr/graph_test.go +++ b/pkg/expr/graph_test.go @@ -8,6 +8,7 @@ import ( "github.com/grafana/grafana/pkg/services/datasources" "github.com/grafana/grafana/pkg/services/featuremgmt" + "github.com/grafana/grafana/pkg/setting" ) func TestServicebuildPipeLine(t *testing.T) { @@ -234,6 +235,7 @@ func TestServicebuildPipeLine(t *testing.T) { } s := Service{ features: featuremgmt.WithFeatures(featuremgmt.FlagExpressionParser), + cfg: setting.NewCfg(), } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/expr/nodes.go b/pkg/expr/nodes.go index 1159ef13d04..dea3b10e659 100644 --- a/pkg/expr/nodes.go +++ b/pkg/expr/nodes.go @@ -106,7 +106,7 @@ func (gn *CMDNode) Execute(ctx context.Context, now time.Time, vars mathexp.Vars return gn.Command.Execute(ctx, now, vars, s.tracer) } -func buildCMDNode(rn *rawNode, toggles featuremgmt.FeatureToggles) (*CMDNode, error) { +func buildCMDNode(rn *rawNode, toggles featuremgmt.FeatureToggles, sqlExpressionCellLimit int64) (*CMDNode, error) { commandType, err := GetExpressionCommandType(rn.Query) if err != nil { return nil, fmt.Errorf("invalid command type in expression '%v': %w", rn.RefID, err) @@ -163,7 +163,7 @@ func buildCMDNode(rn *rawNode, toggles featuremgmt.FeatureToggles) (*CMDNode, er case TypeThreshold: node.Command, err = UnmarshalThresholdCommand(rn, toggles) case TypeSQL: - node.Command, err = UnmarshalSQLCommand(rn) + node.Command, err = UnmarshalSQLCommand(rn, sqlExpressionCellLimit) default: return nil, fmt.Errorf("expression command type '%v' in expression '%v' not implemented", commandType, rn.RefID) } diff --git a/pkg/expr/reader.go b/pkg/expr/reader.go index ef18d9d8c2b..10a219f0692 100644 --- a/pkg/expr/reader.go +++ b/pkg/expr/reader.go @@ -134,7 +134,9 @@ func (h *ExpressionQueryReader) ReadQuery( err = iter.ReadVal(q) if err == nil { eq.Properties = q - eq.Command, err = NewSQLCommand(common.RefID, q.Expression) + // TODO: Cascade limit from Grafana config in this (new Expression Parser) branch of the code + cellLimit := 0 // zero means no limit + eq.Command, err = NewSQLCommand(common.RefID, q.Expression, int64(cellLimit)) } case QueryTypeThreshold: diff --git a/pkg/expr/service_test.go b/pkg/expr/service_test.go index 2fe6f6e1e9c..a343cdaf7b4 100644 --- a/pkg/expr/service_test.go +++ b/pkg/expr/service_test.go @@ -146,6 +146,71 @@ func TestDSQueryError(t *testing.T) { require.Equal(t, fp(42), res.Responses["C"].Frames[0].Fields[0].At(0)) } +func TestSQLExpressionCellLimitFromConfig(t *testing.T) { + tests := []struct { + name string + configCellLimit int64 + expectedLimit int64 + }{ + { + name: "should pass default cell limit (0) to SQL command", + configCellLimit: 0, + expectedLimit: 0, + }, + { + name: "should pass custom cell limit to SQL command", + configCellLimit: 5000, + expectedLimit: 5000, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create a request with an SQL expression + sqlQuery := Query{ + RefID: "A", + DataSource: dataSourceModel(), + JSON: json.RawMessage(`{ "datasource": { "uid": "__expr__", "type": "__expr__"}, "type": "sql", "expression": "SELECT 1 AS n" }`), + TimeRange: AbsoluteTimeRange{ + From: time.Time{}, + To: time.Time{}, + }, + } + + queries := []Query{sqlQuery} + + // Create service with specified cell limit + cfg := setting.NewCfg() + cfg.ExpressionsEnabled = true + cfg.SQLExpressionCellLimit = tt.configCellLimit + + features := featuremgmt.WithFeatures(featuremgmt.FlagSqlExpressions) + + // Create service with our configured limit + s := &Service{ + cfg: cfg, + features: features, + converter: &ResultConverter{ + Features: features, + }, + } + + req := &Request{Queries: queries, User: &user.SignedInUser{}} + + // Build the pipeline + pipeline, err := s.BuildPipeline(req) + require.NoError(t, err) + + node := pipeline[0] + cmdNode := node.(*CMDNode) + sqlCmd := cmdNode.Command.(*SQLCommand) + + // Verify the SQL command has the correct limit + require.Equal(t, tt.expectedLimit, sqlCmd.limit, "SQL command has incorrect cell limit") + }) + } +} + func fp(f float64) *float64 { return &f } diff --git a/pkg/expr/sql_command.go b/pkg/expr/sql_command.go index 069d2a39e91..0b4d7ab698e 100644 --- a/pkg/expr/sql_command.go +++ b/pkg/expr/sql_command.go @@ -19,10 +19,11 @@ type SQLCommand struct { query string varsToQuery []string refID string + limit int64 } // NewSQLCommand creates a new SQLCommand. -func NewSQLCommand(refID, rawSQL string) (*SQLCommand, error) { +func NewSQLCommand(refID, rawSQL string, limit int64) (*SQLCommand, error) { if rawSQL == "" { return nil, errutil.BadRequest("sql-missing-query", errutil.WithPublicMessage("missing SQL query")) @@ -40,15 +41,17 @@ func NewSQLCommand(refID, rawSQL string) (*SQLCommand, error) { if tables != nil { logger.Debug("REF tables", "tables", tables, "sql", rawSQL) } + return &SQLCommand{ query: rawSQL, varsToQuery: tables, refID: refID, + limit: limit, }, nil } // UnmarshalSQLCommand creates a SQLCommand from Grafana's frontend query. -func UnmarshalSQLCommand(rn *rawNode) (*SQLCommand, error) { +func UnmarshalSQLCommand(rn *rawNode, limit int64) (*SQLCommand, error) { if rn.TimeRange == nil { logger.Error("time range must be specified for refID", "refID", rn.RefID) return nil, fmt.Errorf("time range must be specified for refID %s", rn.RefID) @@ -65,7 +68,7 @@ func UnmarshalSQLCommand(rn *rawNode) (*SQLCommand, error) { return nil, fmt.Errorf("expected sql expression to be type string, but got type %T", expressionRaw) } - return NewSQLCommand(rn.RefID, expression) + return NewSQLCommand(rn.RefID, expression, limit) } // NeedsVars returns the variable names (refIds) that are dependencies @@ -91,12 +94,23 @@ func (gr *SQLCommand) Execute(ctx context.Context, now time.Time, vars mathexp.V allFrames = append(allFrames, frames...) } - rsp := mathexp.Results{} - - db := sql.DB{} + totalCells := totalCells(allFrames) + // limit of 0 or less means no limit (following convention) + if gr.limit > 0 && totalCells > gr.limit { + return mathexp.Results{}, + fmt.Errorf( + "SQL expression: total cell count across all input tables exceeds limit of %d. Total cells: %d", + gr.limit, + totalCells, + ) + } logger.Debug("Executing query", "query", gr.query, "frames", len(allFrames)) + + db := sql.DB{} frame, err := db.QueryFrames(ctx, gr.refID, gr.query, allFrames) + + rsp := mathexp.Results{} if err != nil { logger.Error("Failed to query frames", "error", err.Error()) rsp.Error = err @@ -121,3 +135,15 @@ func (gr *SQLCommand) Execute(ctx context.Context, now time.Time, vars mathexp.V func (gr *SQLCommand) Type() string { return TypeSQL.String() } + +func totalCells(frames []*data.Frame) (total int64) { + for _, frame := range frames { + if frame != nil { + // Calculate cells as rows × columns + rows := int64(frame.Rows()) + cols := int64(len(frame.Fields)) + total += rows * cols + } + } + return +} diff --git a/pkg/expr/sql_command_test.go b/pkg/expr/sql_command_test.go index 3e0c5527721..07387a46612 100644 --- a/pkg/expr/sql_command_test.go +++ b/pkg/expr/sql_command_test.go @@ -1,13 +1,21 @@ package expr import ( + "context" + "fmt" + "net/http" "strings" "testing" + "time" + + "github.com/grafana/grafana-plugin-sdk-go/data" + "github.com/grafana/grafana/pkg/expr/mathexp" + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/trace" ) func TestNewCommand(t *testing.T) { - t.Skip() - cmd, err := NewSQLCommand("a", "select a from foo, bar") + cmd, err := NewSQLCommand("a", "select a from foo, bar", 0) if err != nil && strings.Contains(err.Error(), "feature is not enabled") { return } @@ -25,3 +33,133 @@ func TestNewCommand(t *testing.T) { return } } + +// Helper function for creating test data +func createFrameWithRowsAndCols(rows int, cols int) *data.Frame { + frame := data.NewFrame("dummy") + + for c := 0; c < cols; c++ { + values := make([]string, rows) + frame.Fields = append(frame.Fields, data.NewField(fmt.Sprintf("col%d", c), nil, values)) + } + + return frame +} + +func TestSQLCommandCellLimits(t *testing.T) { + tests := []struct { + name string + limit int64 + frames []*data.Frame + vars []string + expectError bool + errorContains string + }{ + { + name: "single (long) frame within cell limit", + limit: 10, + frames: []*data.Frame{ + createFrameWithRowsAndCols(10, 1), // 10 cells + }, + vars: []string{"foo"}, + }, + { + name: "single (wide) frame within cell limit", + limit: 10, + frames: []*data.Frame{ + createFrameWithRowsAndCols(1, 10), // 10 cells + }, + vars: []string{"foo"}, + }, + { + name: "multiple frames within cell limit", + limit: 12, + frames: []*data.Frame{ + createFrameWithRowsAndCols(2, 3), // 6 cells + createFrameWithRowsAndCols(2, 3), // 6 cells + }, + vars: []string{"foo", "bar"}, + }, + { + name: "single (long) frame exceeds cell limit", + limit: 9, + frames: []*data.Frame{ + createFrameWithRowsAndCols(10, 1), // 10 cells > 9 limit + }, + vars: []string{"foo"}, + expectError: true, + errorContains: "exceeds limit", + }, + { + name: "single (wide) frame exceeds cell limit", + limit: 9, + frames: []*data.Frame{ + createFrameWithRowsAndCols(1, 10), // 10 cells > 9 limit + }, + vars: []string{"foo"}, + expectError: true, + errorContains: "exceeds limit", + }, + { + name: "multiple frames exceed cell limit", + limit: 11, + frames: []*data.Frame{ + createFrameWithRowsAndCols(2, 3), // 6 cells + createFrameWithRowsAndCols(2, 3), // 6 cells + }, + vars: []string{"foo", "bar"}, + expectError: true, + errorContains: "exceeds limit", + }, + { + name: "limit of 0 means no limit: allow large frame", + limit: 0, + frames: []*data.Frame{ + createFrameWithRowsAndCols(200000, 1), // 200,000 cells + }, + vars: []string{"foo", "bar"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cmd, err := NewSQLCommand("a", "select a from foo, bar", tt.limit) + require.NoError(t, err, "Failed to create SQL command") + + vars := mathexp.Vars{} + + for i, frame := range tt.frames { + vars[tt.vars[i]] = mathexp.Results{ + Values: mathexp.Values{mathexp.TableData{Frame: frame}}, + } + } + + _, err = cmd.Execute(context.Background(), time.Now(), vars, &testTracer{}) + + if tt.expectError { + require.Error(t, err) + require.Contains(t, err.Error(), tt.errorContains) + } else { + require.NoError(t, err) + } + }) + } +} + +type testTracer struct { + trace.Tracer +} + +func (t *testTracer) Start(ctx context.Context, name string, s ...trace.SpanStartOption) (context.Context, trace.Span) { + return ctx, &testSpan{} +} +func (t *testTracer) Inject(context.Context, http.Header, trace.Span) { + +} + +type testSpan struct { + trace.Span +} + +func (ts *testSpan) End(opt ...trace.SpanEndOption) { +} diff --git a/pkg/setting/setting.go b/pkg/setting/setting.go index cc1b10b9054..c5805d8520d 100644 --- a/pkg/setting/setting.go +++ b/pkg/setting/setting.go @@ -419,6 +419,9 @@ type Cfg struct { // ExpressionsEnabled specifies whether expressions are enabled. ExpressionsEnabled bool + // SQLExpressionCellLimit is the maximum number of cells (rows × columns, across all frames) that can be accepted by a SQL expression. + SQLExpressionCellLimit int64 + ImageUploadProvider string // LiveMaxConnections is a maximum number of WebSocket connections to @@ -780,6 +783,7 @@ func (cfg *Cfg) readAnnotationSettings() error { func (cfg *Cfg) readExpressionsSettings() { expressions := cfg.Raw.Section("expressions") cfg.ExpressionsEnabled = expressions.Key("enabled").MustBool(true) + cfg.SQLExpressionCellLimit = expressions.Key("sql_expression_cell_limit").MustInt64(100000) } type AnnotationCleanupSettings struct { From e645a7d8ff3f5b31d1e04a1efcbce10d027cdefd Mon Sep 17 00:00:00 2001 From: Denis Vodopianov Date: Tue, 11 Mar 2025 18:25:52 +0100 Subject: [PATCH 60/63] Chore: update golang version in .drone.yaml (#101894) --- .drone.yml | 206 ++++++++++++++++---------------- public/api-enterprise-spec.json | 82 +++++++++++-- public/api-merged.json | 52 +++++++- public/openapi3.json | 52 +++++++- scripts/drone/variables.star | 2 +- 5 files changed, 276 insertions(+), 118 deletions(-) diff --git a/.drone.yml b/.drone.yml index dbcc1662f84..6340d739fd6 100644 --- a/.drone.yml +++ b/.drone.yml @@ -25,7 +25,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - commands: - ./bin/build verify-drone @@ -75,7 +75,7 @@ steps: - go install github.com/bazelbuild/buildtools/buildifier@latest - buildifier --lint=warn -mode=check -r . depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: lint-starlark trigger: event: @@ -437,7 +437,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -446,21 +446,21 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: wire-install - commands: - apk add --update build-base shared-mime-info shared-mime-info-lang - go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m depends_on: - wire-install - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: test-backend - commands: - apk add --update build-base @@ -469,7 +469,7 @@ steps: | grep -o '\(.*\)/' | sort -u) depends_on: - wire-install - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: test-backend-integration trigger: event: @@ -524,7 +524,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - commands: - echo $(/usr/bin/github-app-external-token) > /github-app/token @@ -569,16 +569,16 @@ steps: - apk add --update make - make gen-go depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: wire-install - commands: - go run scripts/modowners/modowners.go check go.mod - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: validate-modfile - commands: - apk add --update make - make swagger-validate - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: validate-openapi-spec trigger: event: @@ -655,7 +655,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -665,7 +665,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -674,7 +674,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-jsonnet - commands: - yarn install --immutable || yarn install --immutable @@ -712,7 +712,7 @@ steps: - /src/grafana-build artifacts -a targz:grafana:linux/amd64 -a targz:grafana:linux/arm64 -a targz:grafana:linux/arm/v7 -a docker:grafana:linux/amd64 -a docker:grafana:linux/amd64:ubuntu -a docker:grafana:linux/arm64 -a docker:grafana:linux/arm64:ubuntu -a docker:grafana:linux/arm/v7 - -a docker:grafana:linux/arm/v7:ubuntu --go-version=1.23.7 --yarn-cache=$$YARN_CACHE_FOLDER + -a docker:grafana:linux/arm/v7:ubuntu --go-version=1.24.1 --yarn-cache=$$YARN_CACHE_FOLDER --build-id=$$DRONE_BUILD_NUMBER --ubuntu-base=ubuntu:22.04 --alpine-base=alpine:3.21.3 --tag-format='{{ .version_base }}-{{ .buildID }}-{{ .arch }}' --ubuntu-tag-format='{{ .version_base }}-{{ .buildID }}-ubuntu-{{ .arch }}' --verify='false' --grafana-dir=$$PWD @@ -1110,7 +1110,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - commands: - echo $DRONE_RUNNER_NAME @@ -1124,7 +1124,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -1133,14 +1133,14 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: wire-install - commands: - dockerize -wait tcp://postgres:5432 -timeout 120s @@ -1161,7 +1161,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: postgres-integration-tests - commands: - dockerize -wait tcp://mysql80:3306 -timeout 120s @@ -1182,7 +1182,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql80 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: mysql-8.0-integration-tests - commands: - dockerize -wait tcp://redis:6379 -timeout 120s @@ -1198,7 +1198,7 @@ steps: - wait-for-redis environment: REDIS_URL: redis://redis:6379/0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: redis-integration-tests - commands: - dockerize -wait tcp://memcached:11211 -timeout 120s @@ -1214,7 +1214,7 @@ steps: - wait-for-memcached environment: MEMCACHED_HOSTS: memcached:11211 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: memcached-integration-tests - commands: - dockerize -wait tcp://mimir_backend:8080 -timeout 120s @@ -1230,7 +1230,7 @@ steps: environment: AM_TENANT_ID: test AM_URL: http://mimir_backend:8080 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: remote-alertmanager-integration-tests trigger: event: @@ -1312,7 +1312,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-cue trigger: event: @@ -1433,7 +1433,7 @@ steps: && return 1; fi depends_on: - clone-enterprise - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: swagger-gen trigger: event: @@ -1538,7 +1538,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -1549,7 +1549,7 @@ steps: - CODEGEN_VERIFY=1 make gen-cue depends_on: - clone-enterprise - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -1559,14 +1559,14 @@ steps: - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: - clone-enterprise - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: wire-install - commands: - apk add --update build-base @@ -1574,7 +1574,7 @@ steps: - go test -v -run=^$ -benchmem -timeout=1h -count=8 -bench=. ${GO_PACKAGES} depends_on: - wire-install - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: sqlite-benchmark-integration-tests - commands: - apk add --update build-base @@ -1586,7 +1586,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: postgres-benchmark-integration-tests - commands: - apk add --update build-base @@ -1597,7 +1597,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql80 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: mysql-8.0-benchmark-integration-tests trigger: event: @@ -1669,7 +1669,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-cue trigger: branch: main @@ -1852,7 +1852,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -1861,21 +1861,21 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: wire-install - commands: - apk add --update build-base shared-mime-info shared-mime-info-lang - go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m depends_on: - wire-install - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: test-backend - commands: - apk add --update build-base @@ -1884,7 +1884,7 @@ steps: | grep -o '\(.*\)/' | sort -u) depends_on: - wire-install - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: test-backend-integration trigger: branch: main @@ -1929,22 +1929,22 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - commands: - apk add --update make - make gen-go depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: wire-install - commands: - go run scripts/modowners/modowners.go check go.mod - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: validate-modfile - commands: - apk add --update make - make swagger-validate - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: validate-openapi-spec - commands: - ./bin/build verify-drone @@ -2076,7 +2076,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -2086,7 +2086,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -2095,7 +2095,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-jsonnet - commands: - yarn install --immutable || yarn install --immutable @@ -2132,7 +2132,7 @@ steps: - /src/grafana-build artifacts -a targz:grafana:linux/amd64 -a targz:grafana:linux/arm64 -a targz:grafana:linux/arm/v7 -a docker:grafana:linux/amd64 -a docker:grafana:linux/amd64:ubuntu -a docker:grafana:linux/arm64 -a docker:grafana:linux/arm64:ubuntu -a docker:grafana:linux/arm/v7 - -a docker:grafana:linux/arm/v7:ubuntu --go-version=1.23.7 --yarn-cache=$$YARN_CACHE_FOLDER + -a docker:grafana:linux/arm/v7:ubuntu --go-version=1.24.1 --yarn-cache=$$YARN_CACHE_FOLDER --build-id=$$DRONE_BUILD_NUMBER --ubuntu-base=ubuntu:22.04 --alpine-base=alpine:3.21.3 --tag-format='{{ .version_base }}-{{ .buildID }}-{{ .arch }}' --ubuntu-tag-format='{{ .version_base }}-{{ .buildID }}-ubuntu-{{ .arch }}' --verify='false' --grafana-dir=$$PWD @@ -2607,7 +2607,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - commands: - echo $DRONE_RUNNER_NAME @@ -2621,7 +2621,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -2630,14 +2630,14 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: wire-install - commands: - dockerize -wait tcp://postgres:5432 -timeout 120s @@ -2658,7 +2658,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: postgres-integration-tests - commands: - dockerize -wait tcp://mysql80:3306 -timeout 120s @@ -2679,7 +2679,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql80 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: mysql-8.0-integration-tests - commands: - dockerize -wait tcp://redis:6379 -timeout 120s @@ -2695,7 +2695,7 @@ steps: - wait-for-redis environment: REDIS_URL: redis://redis:6379/0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: redis-integration-tests - commands: - dockerize -wait tcp://memcached:11211 -timeout 120s @@ -2711,7 +2711,7 @@ steps: - wait-for-memcached environment: MEMCACHED_HOSTS: memcached:11211 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: memcached-integration-tests - commands: - dockerize -wait tcp://mimir_backend:8080 -timeout 120s @@ -2727,7 +2727,7 @@ steps: environment: AM_TENANT_ID: test AM_URL: http://mimir_backend:8080 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: remote-alertmanager-integration-tests trigger: branch: main @@ -2996,7 +2996,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -3005,21 +3005,21 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: wire-install - commands: - apk add --update build-base shared-mime-info shared-mime-info-lang - go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m depends_on: - wire-install - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: test-backend - commands: - apk add --update build-base @@ -3028,7 +3028,7 @@ steps: | grep -o '\(.*\)/' | sort -u) depends_on: - wire-install - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: test-backend-integration trigger: branch: @@ -3071,22 +3071,22 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - commands: - apk add --update make - make gen-go depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: wire-install - commands: - go run scripts/modowners/modowners.go check go.mod - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: validate-modfile - commands: - apk add --update make - make swagger-validate - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: validate-openapi-spec trigger: branch: @@ -3165,7 +3165,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - commands: - echo $DRONE_RUNNER_NAME @@ -3179,7 +3179,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -3188,14 +3188,14 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: wire-install - commands: - dockerize -wait tcp://postgres:5432 -timeout 120s @@ -3216,7 +3216,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: postgres-integration-tests - commands: - dockerize -wait tcp://mysql80:3306 -timeout 120s @@ -3237,7 +3237,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql80 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: mysql-8.0-integration-tests - commands: - dockerize -wait tcp://redis:6379 -timeout 120s @@ -3253,7 +3253,7 @@ steps: - wait-for-redis environment: REDIS_URL: redis://redis:6379/0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: redis-integration-tests - commands: - dockerize -wait tcp://memcached:11211 -timeout 120s @@ -3269,7 +3269,7 @@ steps: - wait-for-memcached environment: MEMCACHED_HOSTS: memcached:11211 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: memcached-integration-tests - commands: - dockerize -wait tcp://mimir_backend:8080 -timeout 120s @@ -3285,7 +3285,7 @@ steps: environment: AM_TENANT_ID: test AM_URL: http://mimir_backend:8080 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: remote-alertmanager-integration-tests trigger: branch: @@ -3385,7 +3385,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - commands: - ./bin/build artifacts docker fetch --edition oss @@ -3517,7 +3517,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - commands: - ./bin/build artifacts docker fetch --edition oss @@ -3658,7 +3658,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - commands: - ./bin/build artifacts packages --artifacts-editions=oss --tag $${DRONE_TAG} --src-bucket @@ -3750,7 +3750,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - commands: - yarn install --immutable || yarn install --immutable @@ -3850,7 +3850,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - depends_on: - compile-build-cmd @@ -3947,7 +3947,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: compile-build-cmd - commands: - ./bin/build publish grafana-com --edition oss ${DRONE_TAG} @@ -4009,7 +4009,7 @@ steps: from_secret: grafana_api_key GCP_KEY_BASE64: from_secret: gcp_key_base64 - GO_VERSION: 1.23.7 + GO_VERSION: 1.24.1 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -4084,7 +4084,7 @@ steps: from_secret: grafana_api_key GCP_KEY_BASE64: from_secret: gcp_key_base64 - GO_VERSION: 1.23.7 + GO_VERSION: 1.24.1 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -4201,7 +4201,7 @@ steps: from_secret: grafana_api_key GCP_KEY_BASE64: from_secret: gcp_key_base64 - GO_VERSION: 1.23.7 + GO_VERSION: 1.24.1 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -4352,7 +4352,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -4361,21 +4361,21 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: wire-install - commands: - apk add --update build-base shared-mime-info shared-mime-info-lang - go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m depends_on: - wire-install - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: test-backend - commands: - apk add --update build-base @@ -4384,7 +4384,7 @@ steps: | grep -o '\(.*\)/' | sort -u) depends_on: - wire-install - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: test-backend-integration trigger: cron: @@ -4438,7 +4438,7 @@ steps: from_secret: grafana_api_key GCP_KEY_BASE64: from_secret: gcp_key_base64 - GO_VERSION: 1.23.7 + GO_VERSION: 1.24.1 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -4582,7 +4582,7 @@ steps: from_secret: grafana_api_key GCP_KEY_BASE64: from_secret: gcp_key_base64 - GO_VERSION: 1.23.7 + GO_VERSION: 1.24.1 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -4689,7 +4689,7 @@ steps: - export GITHUB_TOKEN=$(cat /github-app/token) - dagger run --silent /src/grafana-build artifacts -a $${ARTIFACTS} --grafana-ref=$${GRAFANA_REF} --enterprise-ref=$${ENTERPRISE_REF} --grafana-repo=$${GRAFANA_REPO} --version=$${VERSION} - --go-version=1.23.7 + --go-version=1.24.1 depends_on: - github-app-generate-token environment: @@ -4710,7 +4710,7 @@ steps: from_secret: grafana_api_key GCP_KEY_BASE64: from_secret: gcp_key_base64 - GO_VERSION: 1.23.7 + GO_VERSION: 1.24.1 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -4848,7 +4848,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -4857,14 +4857,14 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: wire-install - commands: - dockerize -wait tcp://postgres:5432 -timeout 120s @@ -4885,7 +4885,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: postgres-integration-tests - commands: - dockerize -wait tcp://mysql80:3306 -timeout 120s @@ -4906,7 +4906,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql80 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: mysql-8.0-integration-tests - commands: - dockerize -wait tcp://redis:6379 -timeout 120s @@ -4922,7 +4922,7 @@ steps: - wait-for-redis environment: REDIS_URL: redis://redis:6379/0 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: redis-integration-tests - commands: - dockerize -wait tcp://memcached:11211 -timeout 120s @@ -4938,7 +4938,7 @@ steps: - wait-for-memcached environment: MEMCACHED_HOSTS: memcached:11211 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: memcached-integration-tests - commands: - dockerize -wait tcp://mimir_backend:8080 -timeout 120s @@ -4954,7 +4954,7 @@ steps: environment: AM_TENANT_ID: test AM_URL: http://mimir_backend:8080 - image: golang:1.23.7-alpine + image: golang:1.24.1-alpine name: remote-alertmanager-integration-tests trigger: event: @@ -5257,7 +5257,7 @@ steps: - commands: - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM docker:27-cli - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM alpine/git:2.40.1 - - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM golang:1.23.7-alpine + - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM golang:1.24.1-alpine - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM node:22.11.0-alpine - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM node:22-bookworm - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM google/cloud-sdk:431.0.0 @@ -5295,7 +5295,7 @@ steps: - commands: - trivy --exit-code 1 --severity HIGH,CRITICAL docker:27-cli - trivy --exit-code 1 --severity HIGH,CRITICAL alpine/git:2.40.1 - - trivy --exit-code 1 --severity HIGH,CRITICAL golang:1.23.7-alpine + - trivy --exit-code 1 --severity HIGH,CRITICAL golang:1.24.1-alpine - trivy --exit-code 1 --severity HIGH,CRITICAL node:22.11.0-alpine - trivy --exit-code 1 --severity HIGH,CRITICAL node:22-bookworm - trivy --exit-code 1 --severity HIGH,CRITICAL google/cloud-sdk:431.0.0 @@ -5564,6 +5564,6 @@ kind: secret name: gcr_credentials --- kind: signature -hmac: 33f2e5615dfd7889899f9f8f16f7716190fa637fe98f1efd7e29607f8946be7d +hmac: f55fddb4c6faf30b232ae778ec6c022c9f3d32955879e8a764c715642712c5ea ... diff --git a/public/api-enterprise-spec.json b/public/api-enterprise-spec.json index 3faeab0aa9a..a036e242e30 100644 --- a/public/api-enterprise-spec.json +++ b/public/api-enterprise-spec.json @@ -2779,6 +2779,7 @@ } }, "AnnotationActions": { + "description": "+k8s:deepcopy-gen=true", "type": "object", "properties": { "canAdd": { @@ -2853,6 +2854,7 @@ } }, "AnnotationPermission": { + "description": "+k8s:deepcopy-gen=true", "type": "object", "properties": { "dashboard": { @@ -3206,6 +3208,24 @@ "type": "string" } }, + "InhibitAnyPolicy": { + "description": "InhibitAnyPolicy and InhibitAnyPolicyZero indicate the presence and value\nof the inhibitAnyPolicy extension.\n\nThe value of InhibitAnyPolicy indicates the number of additional\ncertificates in the path after this certificate that may use the\nanyPolicy policy OID to indicate a match with any other policy.\n\nWhen parsing a certificate, a positive non-zero InhibitAnyPolicy means\nthat the field was specified, -1 means it was unset, and\nInhibitAnyPolicyZero being true mean that the field was explicitly set to\nzero. The case of InhibitAnyPolicy==0 with InhibitAnyPolicyZero==false\nshould be treated equivalent to -1 (unset).", + "type": "integer", + "format": "int64" + }, + "InhibitAnyPolicyZero": { + "description": "InhibitAnyPolicyZero indicates that InhibitAnyPolicy==0 should be\ninterpreted as an actual maximum path length of zero. Otherwise, that\ncombination is interpreted as InhibitAnyPolicy not being set.", + "type": "boolean" + }, + "InhibitPolicyMapping": { + "description": "InhibitPolicyMapping and InhibitPolicyMappingZero indicate the presence\nand value of the inhibitPolicyMapping field of the policyConstraints\nextension.\n\nThe value of InhibitPolicyMapping indicates the number of additional\ncertificates in the path after this certificate that may use policy\nmapping.\n\nWhen parsing a certificate, a positive non-zero InhibitPolicyMapping\nmeans that the field was specified, -1 means it was unset, and\nInhibitPolicyMappingZero being true mean that the field was explicitly\nset to zero. The case of InhibitPolicyMapping==0 with\nInhibitPolicyMappingZero==false should be treated equivalent to -1\n(unset).", + "type": "integer", + "format": "int64" + }, + "InhibitPolicyMappingZero": { + "description": "InhibitPolicyMappingZero indicates that InhibitPolicyMapping==0 should be\ninterpreted as an actual maximum path length of zero. Otherwise, that\ncombination is interpreted as InhibitAnyPolicy not being set.", + "type": "boolean" + }, "IsCA": { "type": "boolean" }, @@ -3270,19 +3290,26 @@ } }, "Policies": { - "description": "Policies contains all policy identifiers included in the certificate.\nIn Go 1.22, encoding/gob cannot handle and ignores this field.", + "description": "Policies contains all policy identifiers included in the certificate.\nSee CreateCertificate for context about how this field and the PolicyIdentifiers field\ninteract.\nIn Go 1.22, encoding/gob cannot handle and ignores this field.", "type": "array", "items": { "type": "string" } }, "PolicyIdentifiers": { - "description": "PolicyIdentifiers contains asn1.ObjectIdentifiers, the components\nof which are limited to int32. If a certificate contains a policy which\ncannot be represented by asn1.ObjectIdentifier, it will not be included in\nPolicyIdentifiers, but will be present in Policies, which contains all parsed\npolicy OIDs.", + "description": "PolicyIdentifiers contains asn1.ObjectIdentifiers, the components\nof which are limited to int32. If a certificate contains a policy which\ncannot be represented by asn1.ObjectIdentifier, it will not be included in\nPolicyIdentifiers, but will be present in Policies, which contains all parsed\npolicy OIDs.\nSee CreateCertificate for context about how this field and the Policies field\ninteract.", "type": "array", "items": { "$ref": "#/definitions/ObjectIdentifier" } }, + "PolicyMappings": { + "description": "PolicyMappings contains a list of policy mappings included in the certificate.", + "type": "array", + "items": { + "$ref": "#/definitions/PolicyMapping" + } + }, "PublicKey": {}, "PublicKeyAlgorithm": { "$ref": "#/definitions/PublicKeyAlgorithm" @@ -3322,6 +3349,15 @@ "format": "uint8" } }, + "RequireExplicitPolicy": { + "description": "RequireExplicitPolicy and RequireExplicitPolicyZero indicate the presence\nand value of the requireExplicitPolicy field of the policyConstraints\nextension.\n\nThe value of RequireExplicitPolicy indicates the number of additional\ncertificates in the path after this certificate before an explicit policy\nis required for the rest of the path. When an explicit policy is required,\neach subsequent certificate in the path must contain a required policy OID,\nor a policy OID which has been declared as equivalent through the policy\nmapping extension.\n\nWhen parsing a certificate, a positive non-zero RequireExplicitPolicy\nmeans that the field was specified, -1 means it was unset, and\nRequireExplicitPolicyZero being true mean that the field was explicitly\nset to zero. The case of RequireExplicitPolicy==0 with\nRequireExplicitPolicyZero==false should be treated equivalent to -1\n(unset).", + "type": "integer", + "format": "int64" + }, + "RequireExplicitPolicyZero": { + "description": "RequireExplicitPolicyZero indicates that RequireExplicitPolicy==0 should be\ninterpreted as an actual maximum path length of zero. Otherwise, that\ncombination is interpreted as InhibitAnyPolicy not being set.", + "type": "boolean" + }, "SerialNumber": { "type": "string" }, @@ -4047,6 +4083,9 @@ "annotationsPermissions": { "$ref": "#/definitions/AnnotationPermission" }, + "apiVersion": { + "type": "string" + }, "canAdmin": { "type": "boolean" }, @@ -4737,6 +4776,9 @@ "type": "integer", "format": "int64" }, + "managedBy": { + "$ref": "#/definitions/ManagerKind" + }, "orgId": { "type": "integer", "format": "int64" @@ -4752,10 +4794,6 @@ "$ref": "#/definitions/Folder" } }, - "repository": { - "description": "When the folder belongs to a repository\nNOTE: this is only populated when folders are managed by unified storage", - "type": "string" - }, "title": { "type": "string" }, @@ -4785,11 +4823,10 @@ "type": "integer", "format": "int64" }, - "parentUid": { - "type": "string" + "managedBy": { + "$ref": "#/definitions/ManagerKind" }, - "repository": { - "description": "When the folder belongs to a repository\nNOTE: this is only populated when folders are managed by unified storage", + "parentUid": { "type": "string" }, "title": { @@ -5536,6 +5573,11 @@ } } }, + "ManagerKind": { + "description": "It can be a user or a tool or a generic API client.\n+enum", + "type": "string", + "title": "ManagerKind is the type of manager, which is responsible for managing the resource." + }, "MassDeleteAnnotationsCmd": { "type": "object", "properties": { @@ -6175,6 +6217,20 @@ "$ref": "#/definitions/Playlist" } }, + "PolicyMapping": { + "type": "object", + "title": "PolicyMapping represents a policy mapping entry in the policyMappings extension.", + "properties": { + "IssuerDomainPolicy": { + "description": "IssuerDomainPolicy contains a policy OID the issuing certificate considers\nequivalent to SubjectDomainPolicy in the subject certificate.", + "type": "string" + }, + "SubjectDomainPolicy": { + "description": "SubjectDomainPolicy contains a OID the issuing certificate considers\nequivalent to IssuerDomainPolicy in the subject certificate.", + "type": "string" + } + } + }, "PostAnnotationsCmd": { "type": "object", "required": [ @@ -9946,6 +10002,12 @@ "type": "object" } }, + "notAcceptableError": { + "description": "NotAcceptableError is returned when the server cannot produce a response matching the accepted formats.", + "schema": { + "$ref": "#/definitions/ErrorResponseBody" + } + }, "notFoundError": { "description": "NotFoundError is returned when the requested resource was not found.", "schema": { diff --git a/public/api-merged.json b/public/api-merged.json index 873200a1fb7..44d88382eb6 100644 --- a/public/api-merged.json +++ b/public/api-merged.json @@ -13615,6 +13615,24 @@ "type": "string" } }, + "InhibitAnyPolicy": { + "description": "InhibitAnyPolicy and InhibitAnyPolicyZero indicate the presence and value\nof the inhibitAnyPolicy extension.\n\nThe value of InhibitAnyPolicy indicates the number of additional\ncertificates in the path after this certificate that may use the\nanyPolicy policy OID to indicate a match with any other policy.\n\nWhen parsing a certificate, a positive non-zero InhibitAnyPolicy means\nthat the field was specified, -1 means it was unset, and\nInhibitAnyPolicyZero being true mean that the field was explicitly set to\nzero. The case of InhibitAnyPolicy==0 with InhibitAnyPolicyZero==false\nshould be treated equivalent to -1 (unset).", + "type": "integer", + "format": "int64" + }, + "InhibitAnyPolicyZero": { + "description": "InhibitAnyPolicyZero indicates that InhibitAnyPolicy==0 should be\ninterpreted as an actual maximum path length of zero. Otherwise, that\ncombination is interpreted as InhibitAnyPolicy not being set.", + "type": "boolean" + }, + "InhibitPolicyMapping": { + "description": "InhibitPolicyMapping and InhibitPolicyMappingZero indicate the presence\nand value of the inhibitPolicyMapping field of the policyConstraints\nextension.\n\nThe value of InhibitPolicyMapping indicates the number of additional\ncertificates in the path after this certificate that may use policy\nmapping.\n\nWhen parsing a certificate, a positive non-zero InhibitPolicyMapping\nmeans that the field was specified, -1 means it was unset, and\nInhibitPolicyMappingZero being true mean that the field was explicitly\nset to zero. The case of InhibitPolicyMapping==0 with\nInhibitPolicyMappingZero==false should be treated equivalent to -1\n(unset).", + "type": "integer", + "format": "int64" + }, + "InhibitPolicyMappingZero": { + "description": "InhibitPolicyMappingZero indicates that InhibitPolicyMapping==0 should be\ninterpreted as an actual maximum path length of zero. Otherwise, that\ncombination is interpreted as InhibitAnyPolicy not being set.", + "type": "boolean" + }, "IsCA": { "type": "boolean" }, @@ -13679,19 +13697,26 @@ } }, "Policies": { - "description": "Policies contains all policy identifiers included in the certificate.\nIn Go 1.22, encoding/gob cannot handle and ignores this field.", + "description": "Policies contains all policy identifiers included in the certificate.\nSee CreateCertificate for context about how this field and the PolicyIdentifiers field\ninteract.\nIn Go 1.22, encoding/gob cannot handle and ignores this field.", "type": "array", "items": { "type": "string" } }, "PolicyIdentifiers": { - "description": "PolicyIdentifiers contains asn1.ObjectIdentifiers, the components\nof which are limited to int32. If a certificate contains a policy which\ncannot be represented by asn1.ObjectIdentifier, it will not be included in\nPolicyIdentifiers, but will be present in Policies, which contains all parsed\npolicy OIDs.", + "description": "PolicyIdentifiers contains asn1.ObjectIdentifiers, the components\nof which are limited to int32. If a certificate contains a policy which\ncannot be represented by asn1.ObjectIdentifier, it will not be included in\nPolicyIdentifiers, but will be present in Policies, which contains all parsed\npolicy OIDs.\nSee CreateCertificate for context about how this field and the Policies field\ninteract.", "type": "array", "items": { "$ref": "#/definitions/ObjectIdentifier" } }, + "PolicyMappings": { + "description": "PolicyMappings contains a list of policy mappings included in the certificate.", + "type": "array", + "items": { + "$ref": "#/definitions/PolicyMapping" + } + }, "PublicKey": {}, "PublicKeyAlgorithm": { "$ref": "#/definitions/PublicKeyAlgorithm" @@ -13731,6 +13756,15 @@ "format": "uint8" } }, + "RequireExplicitPolicy": { + "description": "RequireExplicitPolicy and RequireExplicitPolicyZero indicate the presence\nand value of the requireExplicitPolicy field of the policyConstraints\nextension.\n\nThe value of RequireExplicitPolicy indicates the number of additional\ncertificates in the path after this certificate before an explicit policy\nis required for the rest of the path. When an explicit policy is required,\neach subsequent certificate in the path must contain a required policy OID,\nor a policy OID which has been declared as equivalent through the policy\nmapping extension.\n\nWhen parsing a certificate, a positive non-zero RequireExplicitPolicy\nmeans that the field was specified, -1 means it was unset, and\nRequireExplicitPolicyZero being true mean that the field was explicitly\nset to zero. The case of RequireExplicitPolicy==0 with\nRequireExplicitPolicyZero==false should be treated equivalent to -1\n(unset).", + "type": "integer", + "format": "int64" + }, + "RequireExplicitPolicyZero": { + "description": "RequireExplicitPolicyZero indicates that RequireExplicitPolicy==0 should be\ninterpreted as an actual maximum path length of zero. Otherwise, that\ncombination is interpreted as InhibitAnyPolicy not being set.", + "type": "boolean" + }, "SerialNumber": { "type": "string" }, @@ -18116,6 +18150,20 @@ "$ref": "#/definitions/Playlist" } }, + "PolicyMapping": { + "type": "object", + "title": "PolicyMapping represents a policy mapping entry in the policyMappings extension.", + "properties": { + "IssuerDomainPolicy": { + "description": "IssuerDomainPolicy contains a policy OID the issuing certificate considers\nequivalent to SubjectDomainPolicy in the subject certificate.", + "type": "string" + }, + "SubjectDomainPolicy": { + "description": "SubjectDomainPolicy contains a OID the issuing certificate considers\nequivalent to IssuerDomainPolicy in the subject certificate.", + "type": "string" + } + } + }, "PostAnnotationsCmd": { "type": "object", "required": [ diff --git a/public/openapi3.json b/public/openapi3.json index 9d4c63135c3..ccfd199e14e 100644 --- a/public/openapi3.json +++ b/public/openapi3.json @@ -3676,6 +3676,24 @@ }, "type": "array" }, + "InhibitAnyPolicy": { + "description": "InhibitAnyPolicy and InhibitAnyPolicyZero indicate the presence and value\nof the inhibitAnyPolicy extension.\n\nThe value of InhibitAnyPolicy indicates the number of additional\ncertificates in the path after this certificate that may use the\nanyPolicy policy OID to indicate a match with any other policy.\n\nWhen parsing a certificate, a positive non-zero InhibitAnyPolicy means\nthat the field was specified, -1 means it was unset, and\nInhibitAnyPolicyZero being true mean that the field was explicitly set to\nzero. The case of InhibitAnyPolicy==0 with InhibitAnyPolicyZero==false\nshould be treated equivalent to -1 (unset).", + "format": "int64", + "type": "integer" + }, + "InhibitAnyPolicyZero": { + "description": "InhibitAnyPolicyZero indicates that InhibitAnyPolicy==0 should be\ninterpreted as an actual maximum path length of zero. Otherwise, that\ncombination is interpreted as InhibitAnyPolicy not being set.", + "type": "boolean" + }, + "InhibitPolicyMapping": { + "description": "InhibitPolicyMapping and InhibitPolicyMappingZero indicate the presence\nand value of the inhibitPolicyMapping field of the policyConstraints\nextension.\n\nThe value of InhibitPolicyMapping indicates the number of additional\ncertificates in the path after this certificate that may use policy\nmapping.\n\nWhen parsing a certificate, a positive non-zero InhibitPolicyMapping\nmeans that the field was specified, -1 means it was unset, and\nInhibitPolicyMappingZero being true mean that the field was explicitly\nset to zero. The case of InhibitPolicyMapping==0 with\nInhibitPolicyMappingZero==false should be treated equivalent to -1\n(unset).", + "format": "int64", + "type": "integer" + }, + "InhibitPolicyMappingZero": { + "description": "InhibitPolicyMappingZero indicates that InhibitPolicyMapping==0 should be\ninterpreted as an actual maximum path length of zero. Otherwise, that\ncombination is interpreted as InhibitAnyPolicy not being set.", + "type": "boolean" + }, "IsCA": { "type": "boolean" }, @@ -3740,19 +3758,26 @@ "type": "array" }, "Policies": { - "description": "Policies contains all policy identifiers included in the certificate.\nIn Go 1.22, encoding/gob cannot handle and ignores this field.", + "description": "Policies contains all policy identifiers included in the certificate.\nSee CreateCertificate for context about how this field and the PolicyIdentifiers field\ninteract.\nIn Go 1.22, encoding/gob cannot handle and ignores this field.", "items": { "type": "string" }, "type": "array" }, "PolicyIdentifiers": { - "description": "PolicyIdentifiers contains asn1.ObjectIdentifiers, the components\nof which are limited to int32. If a certificate contains a policy which\ncannot be represented by asn1.ObjectIdentifier, it will not be included in\nPolicyIdentifiers, but will be present in Policies, which contains all parsed\npolicy OIDs.", + "description": "PolicyIdentifiers contains asn1.ObjectIdentifiers, the components\nof which are limited to int32. If a certificate contains a policy which\ncannot be represented by asn1.ObjectIdentifier, it will not be included in\nPolicyIdentifiers, but will be present in Policies, which contains all parsed\npolicy OIDs.\nSee CreateCertificate for context about how this field and the Policies field\ninteract.", "items": { "$ref": "#/components/schemas/ObjectIdentifier" }, "type": "array" }, + "PolicyMappings": { + "description": "PolicyMappings contains a list of policy mappings included in the certificate.", + "items": { + "$ref": "#/components/schemas/PolicyMapping" + }, + "type": "array" + }, "PublicKey": {}, "PublicKeyAlgorithm": { "$ref": "#/components/schemas/PublicKeyAlgorithm" @@ -3792,6 +3817,15 @@ }, "type": "array" }, + "RequireExplicitPolicy": { + "description": "RequireExplicitPolicy and RequireExplicitPolicyZero indicate the presence\nand value of the requireExplicitPolicy field of the policyConstraints\nextension.\n\nThe value of RequireExplicitPolicy indicates the number of additional\ncertificates in the path after this certificate before an explicit policy\nis required for the rest of the path. When an explicit policy is required,\neach subsequent certificate in the path must contain a required policy OID,\nor a policy OID which has been declared as equivalent through the policy\nmapping extension.\n\nWhen parsing a certificate, a positive non-zero RequireExplicitPolicy\nmeans that the field was specified, -1 means it was unset, and\nRequireExplicitPolicyZero being true mean that the field was explicitly\nset to zero. The case of RequireExplicitPolicy==0 with\nRequireExplicitPolicyZero==false should be treated equivalent to -1\n(unset).", + "format": "int64", + "type": "integer" + }, + "RequireExplicitPolicyZero": { + "description": "RequireExplicitPolicyZero indicates that RequireExplicitPolicy==0 should be\ninterpreted as an actual maximum path length of zero. Otherwise, that\ncombination is interpreted as InhibitAnyPolicy not being set.", + "type": "boolean" + }, "SerialNumber": { "type": "string" }, @@ -8179,6 +8213,20 @@ }, "type": "array" }, + "PolicyMapping": { + "properties": { + "IssuerDomainPolicy": { + "description": "IssuerDomainPolicy contains a policy OID the issuing certificate considers\nequivalent to SubjectDomainPolicy in the subject certificate.", + "type": "string" + }, + "SubjectDomainPolicy": { + "description": "SubjectDomainPolicy contains a OID the issuing certificate considers\nequivalent to IssuerDomainPolicy in the subject certificate.", + "type": "string" + } + }, + "title": "PolicyMapping represents a policy mapping entry in the policyMappings extension.", + "type": "object" + }, "PostAnnotationsCmd": { "properties": { "dashboardId": { diff --git a/scripts/drone/variables.star b/scripts/drone/variables.star index c737ef65d61..51da1d676ba 100644 --- a/scripts/drone/variables.star +++ b/scripts/drone/variables.star @@ -3,7 +3,7 @@ global variables """ grabpl_version = "v3.1.2" -golang_version = "1.23.7" +golang_version = "1.24.1" # nodejs_version should match what's in ".nvmrc", but without the v prefix. nodejs_version = "22.11.0" From 4dbd1846c70c839fa71a06b7fb72d82d784aeb14 Mon Sep 17 00:00:00 2001 From: Ashley Harrison Date: Tue, 11 Mar 2025 17:28:36 +0000 Subject: [PATCH 61/63] Chore: bump codeql versions used in pr checks (#101957) * bump codeql versions used in pr checks * update supported versions * use glob syntax * wider glob --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/pr-codeql-analysis-go.yml | 4 ++-- .github/workflows/pr-codeql-analysis-javascript.yml | 4 ++-- .github/workflows/pr-codeql-analysis-python.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index c1f90ceb831..8c8b1abde50 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -8,7 +8,7 @@ name: "CodeQL" on: workflow_dispatch: push: - branches: [main, v1.8.x, v2.0.x, v2.1.x, v2.6.x, v3.0.x, v3.1.x, v4.0.x, v4.1.x, v4.2.x, v4.3.x, v4.4.x, v4.5.x, v4.6.x, v4.7.x, v5.0.x, v5.1.x, v5.2.x, v5.3.x, v5.4.x, v6.0.x, v6.1.x, v6.2.x, v6.3.x, v6.4.x, v6.5.x, v6.6.x, v6.7.x, v7.0.x, v7.1.x, v7.2.x] + branches: [main, v*.*.*] paths-ignore: - '**/*.cue' - '**/*.json' diff --git a/.github/workflows/pr-codeql-analysis-go.yml b/.github/workflows/pr-codeql-analysis-go.yml index ce9082f4400..46645b7fa3f 100644 --- a/.github/workflows/pr-codeql-analysis-go.yml +++ b/.github/workflows/pr-codeql-analysis-go.yml @@ -40,7 +40,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: "go" @@ -50,4 +50,4 @@ jobs: make build-go - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/pr-codeql-analysis-javascript.yml b/.github/workflows/pr-codeql-analysis-javascript.yml index 6c5264c926a..d24b7db9671 100644 --- a/.github/workflows/pr-codeql-analysis-javascript.yml +++ b/.github/workflows/pr-codeql-analysis-javascript.yml @@ -28,9 +28,9 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: "javascript" - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/pr-codeql-analysis-python.yml b/.github/workflows/pr-codeql-analysis-python.yml index aea55365afc..4e8b1b14747 100644 --- a/.github/workflows/pr-codeql-analysis-python.yml +++ b/.github/workflows/pr-codeql-analysis-python.yml @@ -26,9 +26,9 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: "python" - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 From 85b0b47efdd811b46af2715aec7a54943d985ea6 Mon Sep 17 00:00:00 2001 From: Alexander Akhmetov Date: Tue, 11 Mar 2025 19:53:28 +0100 Subject: [PATCH 62/63] Alerting: Allow disabling provenance in the Prometheus conversion API (#101573) When creating Grafana-managed alerts from Prometheus rule definitions with mimirtool or cortextool, the rules are marked as "provisioned" and are not editable in the Grafana UI. This PR allows changing this by providing an extra header: --extra-header="X-Disable-Provenance=true". When provenance is disabled, we do not keep the original rule definition in YAML, so it is impossible to read it back using the Prometheus conversion API (mimirtool/cortextool). This is intentional because if we did keep it and the rule was later changed in the UI, its Prometheus YAML definition would no longer reflect the latest version of the alert rule, as it would be unchanged. --- .../ngalert/api/api_convert_prometheus.go | 38 +++++- .../api/api_convert_prometheus_test.go | 115 +++++++++++++++++ pkg/services/ngalert/prom/convert.go | 32 +++-- pkg/services/ngalert/prom/convert_test.go | 68 ++++++++++ .../ngalert/provisioning/alert_rules_test.go | 36 ++++++ .../provisioning/validation/provenance.go | 20 ++- .../validation/provenance_test.go | 60 +++++++++ .../alerting/api_convert_prometheus_test.go | 117 ++++++++++++++++++ 8 files changed, 466 insertions(+), 20 deletions(-) diff --git a/pkg/services/ngalert/api/api_convert_prometheus.go b/pkg/services/ngalert/api/api_convert_prometheus.go index 3c7878bc500..57d312768cb 100644 --- a/pkg/services/ngalert/api/api_convert_prometheus.go +++ b/pkg/services/ngalert/api/api_convert_prometheus.go @@ -188,11 +188,12 @@ func (srv *ConvertPrometheusSrv) RouteConvertPrometheusDeleteNamespace(c *contex } logger.Info("Deleting all Prometheus-imported rule groups", "folder_uid", namespace.UID, "folder_title", namespaceTitle) + provenance := getProvenance(c) filterOpts := &provisioning.FilterOptions{ NamespaceUIDs: []string{namespace.UID}, ImportedPrometheusRule: util.Pointer(true), } - err = srv.alertRuleService.DeleteRuleGroups(c.Req.Context(), c.SignedInUser, models.ProvenanceConvertedPrometheus, filterOpts) + err = srv.alertRuleService.DeleteRuleGroups(c.Req.Context(), c.SignedInUser, provenance, filterOpts) if errors.Is(err, models.ErrAlertRuleGroupNotFound) { return response.Empty(http.StatusNotFound) } @@ -218,7 +219,8 @@ func (srv *ConvertPrometheusSrv) RouteConvertPrometheusDeleteRuleGroup(c *contex } logger.Info("Deleting Prometheus-imported rule group", "folder_uid", folder.UID, "folder_title", namespaceTitle, "group", group) - err = srv.alertRuleService.DeleteRuleGroup(c.Req.Context(), c.SignedInUser, folder.UID, group, models.ProvenanceConvertedPrometheus) + provenance := getProvenance(c) + err = srv.alertRuleService.DeleteRuleGroup(c.Req.Context(), c.SignedInUser, folder.UID, group, provenance) if errors.Is(err, models.ErrAlertRuleGroupNotFound) { return response.Empty(http.StatusNotFound) } @@ -352,13 +354,21 @@ func (srv *ConvertPrometheusSrv) RouteConvertPrometheusPostRuleGroup(c *contextm return errorToResponse(err) } - group, err := srv.convertToGrafanaRuleGroup(c, ds, ns.UID, promGroup, logger) + provenance := getProvenance(c) + + // If the provenance is not ConvertedPrometheus, we don't keep the original rule definition. + // This is because the rules can be modified through the UI, which may break compatibility + // with the Prometheus format. We only preserve the original rule definition + // to ensure we can return them in this API in Prometheus format. + keepOriginalRuleDefinition := provenance == models.ProvenanceConvertedPrometheus + + group, err := srv.convertToGrafanaRuleGroup(c, ds, ns.UID, promGroup, keepOriginalRuleDefinition, logger) if err != nil { logger.Error("Failed to convert Prometheus rules to Grafana rules", "error", err) return errorToResponse(err) } - err = srv.alertRuleService.ReplaceRuleGroup(c.Req.Context(), c.SignedInUser, *group, models.ProvenanceConvertedPrometheus) + err = srv.alertRuleService.ReplaceRuleGroup(c.Req.Context(), c.SignedInUser, *group, provenance) if err != nil { logger.Error("Failed to replace rule group", "error", err) return errorToResponse(err) @@ -387,7 +397,14 @@ func (srv *ConvertPrometheusSrv) getOrCreateNamespace(c *contextmodel.ReqContext return ns, nil } -func (srv *ConvertPrometheusSrv) convertToGrafanaRuleGroup(c *contextmodel.ReqContext, ds *datasources.DataSource, namespaceUID string, promGroup apimodels.PrometheusRuleGroup, logger log.Logger) (*models.AlertRuleGroup, error) { +func (srv *ConvertPrometheusSrv) convertToGrafanaRuleGroup( + c *contextmodel.ReqContext, + ds *datasources.DataSource, + namespaceUID string, + promGroup apimodels.PrometheusRuleGroup, + keepOriginalRuleDefinition bool, + logger log.Logger, +) (*models.AlertRuleGroup, error) { logger.Info("Converting Prometheus rules to Grafana rules", "rules", len(promGroup.Rules), "folder_uid", namespaceUID, "datasource_uid", ds.UID, "datasource_type", ds.Type) rules := make([]prom.PrometheusRule, len(promGroup.Rules)) @@ -429,6 +446,7 @@ func (srv *ConvertPrometheusSrv) convertToGrafanaRuleGroup(c *contextmodel.ReqCo AlertRules: prom.RulesConfig{ IsPaused: pauseAlertRules, }, + KeepOriginalRuleDefinition: util.Pointer(keepOriginalRuleDefinition), }, ) if err != nil { @@ -537,3 +555,13 @@ func promGroupHasRecordingRules(promGroup apimodels.PrometheusRuleGroup) bool { } return false } + +// getProvenance determines the provenance value to use for rules created via the Prometheus conversion API. +// If the X-Disable-Provenance header is present in the request, returns ProvenanceNone, +// otherwise returns ProvenanceConvertedPrometheus. +func getProvenance(ctx *contextmodel.ReqContext) models.Provenance { + if _, disabled := ctx.Req.Header[disableProvenanceHeaderName]; disabled { + return models.ProvenanceNone + } + return models.ProvenanceConvertedPrometheus +} diff --git a/pkg/services/ngalert/api/api_convert_prometheus_test.go b/pkg/services/ngalert/api/api_convert_prometheus_test.go index c6b0a33166a..fda8be8cecd 100644 --- a/pkg/services/ngalert/api/api_convert_prometheus_test.go +++ b/pkg/services/ngalert/api/api_convert_prometheus_test.go @@ -144,6 +144,11 @@ func TestRouteConvertPrometheusPostRuleGroup(t *testing.T) { promDefinition, err := r.PrometheusRuleDefinition() require.NoError(t, err) require.Equal(t, expectedDef, promDefinition) + + // Verify provenance was set to ProvenanceConvertedPrometheus + prov, err := provenanceStore.GetProvenance(context.Background(), r, 1) + require.NoError(t, err) + require.Equal(t, models.ProvenanceConvertedPrometheus, prov) } }) @@ -341,6 +346,41 @@ func TestRouteConvertPrometheusPostRuleGroup(t *testing.T) { }) } }) + + t.Run("with disable provenance header should use ProvenanceNone", func(t *testing.T) { + provenanceStore := fakes.NewFakeProvisioningStore() + srv, _, ruleStore, folderService := createConvertPrometheusSrv(t, withProvenanceStore(provenanceStore)) + + // Create a folder in the root + fldr := randFolder() + fldr.ParentUID = "" + folderService.ExpectedFolder = fldr + folderService.ExpectedFolders = []*folder.Folder{fldr} + ruleStore.Folders[1] = append(ruleStore.Folders[1], fldr) + + // Create request with the X-Disable-Provenance header + rc := createRequestCtx() + rc.Req.Header.Set("X-Disable-Provenance", "true") + + response := srv.RouteConvertPrometheusPostRuleGroup(rc, fldr.Title, simpleGroup) + require.Equal(t, http.StatusAccepted, response.Status()) + + // Get the created rules + rules, err := ruleStore.ListAlertRules(context.Background(), &models.ListAlertRulesQuery{ + OrgID: 1, + }) + require.NoError(t, err) + require.Len(t, rules, 2) + + // Verify provenance was set to ProvenanceNone + for _, r := range rules { + prov, err := provenanceStore.GetProvenance(context.Background(), r, 1) + require.NoError(t, err) + require.Equal(t, models.ProvenanceNone, prov, "Provenance should be ProvenanceNone when X-Disable-Provenance header is set") + // Prometheus rule definition should not be saved when provenance is disabled + require.Nil(t, r.Metadata.PrometheusStyleRule) + } + }) } func TestRouteConvertPrometheusGetRuleGroup(t *testing.T) { @@ -743,6 +783,29 @@ func TestRouteConvertPrometheusDeleteNamespace(t *testing.T) { require.NoError(t, err) require.NotNil(t, remaining) }) + + t.Run("with disable provenance header should still be able to delete rules", func(t *testing.T) { + provenanceStore := fakes.NewFakeProvisioningStore() + srv, ruleStore, fldr, rule := initNamespace("prometheus definition", withProvenanceStore(provenanceStore)) + + // Mark the rule as provisioned with API provenance + err := provenanceStore.SetProvenance(context.Background(), rule, 1, models.ProvenanceConvertedPrometheus) + require.NoError(t, err) + + rc := createRequestCtx() + rc.Req.Header.Set("X-Disable-Provenance", "true") + + response := srv.RouteConvertPrometheusDeleteNamespace(rc, fldr.Title) + require.Equal(t, http.StatusAccepted, response.Status()) + + // Verify the rule was deleted + remaining, err := ruleStore.GetAlertRuleByUID(context.Background(), &models.GetAlertRuleByUIDQuery{ + UID: rule.UID, + OrgID: rule.OrgID, + }) + require.Error(t, err) + require.Nil(t, remaining) + }) }) } @@ -854,6 +917,29 @@ func TestRouteConvertPrometheusDeleteRuleGroup(t *testing.T) { require.NoError(t, err) require.NotNil(t, remaining) }) + + t.Run("with disable provenance header should still be able to delete rules", func(t *testing.T) { + provenanceStore := fakes.NewFakeProvisioningStore() + srv, ruleStore, fldr, rule := initGroup("", groupName, withProvenanceStore(provenanceStore)) + + // Mark the rule as provisioned with API provenance + err := provenanceStore.SetProvenance(context.Background(), rule, 1, models.ProvenanceConvertedPrometheus) + require.NoError(t, err) + + rc := createRequestCtx() + rc.Req.Header.Set("X-Disable-Provenance", "true") + + response := srv.RouteConvertPrometheusDeleteRuleGroup(rc, fldr.Title, groupName) + require.Equal(t, http.StatusAccepted, response.Status()) + + // Verify the rule was deleted + remaining, err := ruleStore.GetAlertRuleByUID(context.Background(), &models.GetAlertRuleByUIDQuery{ + UID: rule.UID, + OrgID: rule.OrgID, + }) + require.Error(t, err) + require.Nil(t, remaining) + }) }) } @@ -995,3 +1081,32 @@ func TestGetWorkingFolderUID(t *testing.T) { require.Equal(t, specifiedFolderUID, folderUID) }) } + +func TestGetProvenance(t *testing.T) { + t.Run("should return ProvenanceConvertedPrometheus when header is not present", func(t *testing.T) { + rc := createRequestCtx() + // Ensure the header is not present + rc.Req.Header.Del(disableProvenanceHeaderName) + + provenance := getProvenance(rc) + require.Equal(t, models.ProvenanceConvertedPrometheus, provenance) + }) + + t.Run("should return ProvenanceNone when header is present", func(t *testing.T) { + rc := createRequestCtx() + // Set the disable provenance header + rc.Req.Header.Set(disableProvenanceHeaderName, "true") + + provenance := getProvenance(rc) + require.Equal(t, models.ProvenanceNone, provenance) + }) + + t.Run("should return ProvenanceNone when header is present with any value", func(t *testing.T) { + rc := createRequestCtx() + // Set the disable provenance header with an empty value + rc.Req.Header.Set(disableProvenanceHeaderName, "") + + provenance := getProvenance(rc) + require.Equal(t, models.ProvenanceNone, provenance) + }) +} diff --git a/pkg/services/ngalert/prom/convert.go b/pkg/services/ngalert/prom/convert.go index ccbbf89e23b..f64b17bfc5e 100644 --- a/pkg/services/ngalert/prom/convert.go +++ b/pkg/services/ngalert/prom/convert.go @@ -37,8 +37,12 @@ type Config struct { EvaluationOffset *time.Duration ExecErrState models.ExecutionErrorState NoDataState models.NoDataState - RecordingRules RulesConfig - AlertRules RulesConfig + // KeepOriginalRuleDefinition indicates whether the original Prometheus rule definition + // if saved to the alert rule metadata. If not, then it will not be possible to convert + // the alert rule back to Prometheus format. + KeepOriginalRuleDefinition *bool + RecordingRules RulesConfig + AlertRules RulesConfig } // RulesConfig contains configuration that applies to either recording or alerting rules. @@ -51,10 +55,11 @@ var ( defaultEvaluationOffset = 0 * time.Minute defaultConfig = Config{ - FromTimeRange: &defaultTimeRange, - EvaluationOffset: &defaultEvaluationOffset, - ExecErrState: models.ErrorErrState, - NoDataState: models.OK, + FromTimeRange: &defaultTimeRange, + EvaluationOffset: &defaultEvaluationOffset, + ExecErrState: models.ErrorErrState, + NoDataState: models.OK, + KeepOriginalRuleDefinition: util.Pointer(true), } ) @@ -87,7 +92,9 @@ func NewConverter(cfg Config) (*Converter, error) { if cfg.NoDataState == "" { cfg.NoDataState = defaultConfig.NoDataState } - + if cfg.KeepOriginalRuleDefinition == nil { + cfg.KeepOriginalRuleDefinition = defaultConfig.KeepOriginalRuleDefinition + } if cfg.DatasourceType != datasources.DS_PROMETHEUS && cfg.DatasourceType != datasources.DS_LOKI { return nil, fmt.Errorf("invalid datasource type: %s", cfg.DatasourceType) } @@ -233,11 +240,12 @@ func (p *Converter) convertRule(orgID int64, namespaceUID string, promGroup Prom RuleGroup: promGroup.Name, IsPaused: isPaused, Record: record, - Metadata: models.AlertRuleMetadata{ - PrometheusStyleRule: &models.PrometheusStyleRule{ - OriginalRuleDefinition: string(originalRuleDefinition), - }, - }, + } + + if p.cfg.KeepOriginalRuleDefinition != nil && *p.cfg.KeepOriginalRuleDefinition { + result.Metadata.PrometheusStyleRule = &models.PrometheusStyleRule{ + OriginalRuleDefinition: string(originalRuleDefinition), + } } return result, nil diff --git a/pkg/services/ngalert/prom/convert_test.go b/pkg/services/ngalert/prom/convert_test.go index 2d7e2b26535..2281a9da1c0 100644 --- a/pkg/services/ngalert/prom/convert_test.go +++ b/pkg/services/ngalert/prom/convert_test.go @@ -618,3 +618,71 @@ func TestPrometheusRulesToGrafana_UID(t *testing.T) { }) }) } + +func TestPrometheusRulesToGrafana_KeepOriginalRuleDefinition(t *testing.T) { + orgID := int64(1) + namespace := "namespace" + + promGroup := PrometheusRuleGroup{ + Name: "test-group", + Rules: []PrometheusRule{ + { + Alert: "test-alert", + Expr: "up == 0", + }, + }, + } + + testCases := []struct { + name string + keepOriginalRuleDefinition *bool + expectDefinition bool + }{ + { + name: "keep original rule definition is true", + keepOriginalRuleDefinition: util.Pointer(true), + expectDefinition: true, + }, + { + name: "keep original rule definition is false", + keepOriginalRuleDefinition: util.Pointer(false), + expectDefinition: false, + }, + { + name: "keep original rule definition is nil (should use default)", + keepOriginalRuleDefinition: nil, + expectDefinition: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + cfg := Config{ + DatasourceUID: "datasource-uid", + DatasourceType: datasources.DS_PROMETHEUS, + DefaultInterval: 1 * time.Minute, + KeepOriginalRuleDefinition: tc.keepOriginalRuleDefinition, + } + + converter, err := NewConverter(cfg) + require.NoError(t, err) + + // Convert the Prometheus rule to Grafana + grafanaGroup, err := converter.PrometheusRulesToGrafana(orgID, namespace, promGroup) + require.NoError(t, err) + require.Len(t, grafanaGroup.Rules, 1) + + if tc.expectDefinition { + originalRuleDefinition, err := yaml.Marshal(promGroup.Rules[0]) + require.NoError(t, err) + require.Equal( + t, + string(originalRuleDefinition), + grafanaGroup.Rules[0].Metadata.PrometheusStyleRule.OriginalRuleDefinition, + ) + } else { + require.Nil(t, grafanaGroup.Rules[0].Metadata.PrometheusStyleRule) + } + }) + } +} diff --git a/pkg/services/ngalert/provisioning/alert_rules_test.go b/pkg/services/ngalert/provisioning/alert_rules_test.go index c98c293fd34..68991883c03 100644 --- a/pkg/services/ngalert/provisioning/alert_rules_test.go +++ b/pkg/services/ngalert/provisioning/alert_rules_test.go @@ -674,6 +674,42 @@ func TestAlertRuleService(t *testing.T) { to: models.ProvenanceNone, errNil: false, }, + { + name: "should be able to update from provenance none to 'converted prometheus'", + from: models.ProvenanceNone, + to: models.ProvenanceConvertedPrometheus, + errNil: true, + }, + { + name: "should be able to update from provenance 'converted prometheus' to none", + from: models.ProvenanceConvertedPrometheus, + to: models.ProvenanceNone, + errNil: true, + }, + { + name: "should not be able to update from provenance 'converted prometheus' to api", + from: models.ProvenanceConvertedPrometheus, + to: models.ProvenanceAPI, + errNil: false, + }, + { + name: "should not be able to update from provenance 'converted prometheus' to file", + from: models.ProvenanceConvertedPrometheus, + to: models.ProvenanceFile, + errNil: false, + }, + { + name: "should not be able to update from provenance api to 'converted prometheus'", + from: models.ProvenanceAPI, + to: models.ProvenanceConvertedPrometheus, + errNil: false, + }, + { + name: "should not be able to update from provenance file to 'converted prometheus'", + from: models.ProvenanceFile, + to: models.ProvenanceConvertedPrometheus, + errNil: false, + }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { diff --git a/pkg/services/ngalert/provisioning/validation/provenance.go b/pkg/services/ngalert/provisioning/validation/provenance.go index 387cdd56b3e..b57dcee37db 100644 --- a/pkg/services/ngalert/provisioning/validation/provenance.go +++ b/pkg/services/ngalert/provisioning/validation/provenance.go @@ -7,9 +7,23 @@ import ( // CanUpdateProvenanceInRuleGroup checks if a provenance can be updated for a rule group and its alerts. // ReplaceRuleGroup function intends to replace an entire rule group: inserting, updating, and removing rules. func CanUpdateProvenanceInRuleGroup(storedProvenance, provenance models.Provenance) bool { - return storedProvenance == provenance || - storedProvenance == models.ProvenanceNone || - (storedProvenance == models.ProvenanceAPI && provenance == models.ProvenanceNone) + // Same provenance is always allowed + if storedProvenance == provenance { + return true + } + + // Can always update stored ProvenanceNone + if storedProvenance == models.ProvenanceNone { + return true + } + + // Can reset to ProvenanceNone from specific provenances + if provenance == models.ProvenanceNone { + return storedProvenance == models.ProvenanceAPI || + storedProvenance == models.ProvenanceConvertedPrometheus + } + + return false } type ProvenanceStatusTransitionValidator = func(from, to models.Provenance) error diff --git a/pkg/services/ngalert/provisioning/validation/provenance_test.go b/pkg/services/ngalert/provisioning/validation/provenance_test.go index b98ce241b03..04b9c61eccb 100644 --- a/pkg/services/ngalert/provisioning/validation/provenance_test.go +++ b/pkg/services/ngalert/provisioning/validation/provenance_test.go @@ -15,6 +15,7 @@ func TestValidateProvenanceRelaxed(t *testing.T) { models.ProvenanceNone, models.ProvenanceAPI, models.ProvenanceFile, + models.ProvenanceConvertedPrometheus, models.Provenance(fmt.Sprintf("random-%s", util.GenerateShortUID())), } t.Run("all transitions from 'none' are allowed", func(t *testing.T) { @@ -49,3 +50,62 @@ func TestValidateProvenanceRelaxed(t *testing.T) { } }) } + +func TestCanUpdateProvenanceInRuleGroup(t *testing.T) { + all := []models.Provenance{ + models.ProvenanceNone, + models.ProvenanceAPI, + models.ProvenanceFile, + models.ProvenanceConvertedPrometheus, + models.Provenance(fmt.Sprintf("random-%s", util.GenerateShortUID())), + } + + t.Run("same provenance transitions are allowed", func(t *testing.T) { + for _, provenance := range all { + assert.True(t, CanUpdateProvenanceInRuleGroup(provenance, provenance)) + } + }) + + t.Run("all transitions from 'none' are allowed", func(t *testing.T) { + for _, provenance := range all { + assert.True(t, CanUpdateProvenanceInRuleGroup(models.ProvenanceNone, provenance)) + } + }) + + t.Run("only specific provenances can transition to 'none'", func(t *testing.T) { + allowed := []models.Provenance{ + models.ProvenanceAPI, + models.ProvenanceConvertedPrometheus, + } + + for _, from := range allowed { + assert.True(t, CanUpdateProvenanceInRuleGroup(from, models.ProvenanceNone), + "transition %s -> 'none' should be allowed", from) + } + + notAllowed := []models.Provenance{ + models.ProvenanceFile, + models.Provenance(fmt.Sprintf("random-%s", util.GenerateShortUID())), + } + + for _, from := range notAllowed { + assert.False(t, CanUpdateProvenanceInRuleGroup(from, models.ProvenanceNone), + "transition %s -> 'none' should not be allowed", from) + } + }) + + t.Run("transitions between different provenances are not allowed", func(t *testing.T) { + for _, from := range all { + if from == models.ProvenanceNone { + continue // always allowed + } + for _, to := range all { + if from == to || to == models.ProvenanceNone { + continue // always allowed + } + assert.False(t, CanUpdateProvenanceInRuleGroup(from, to), + "transition %s -> '%s' should not be allowed", from, to) + } + } + }) +} diff --git a/pkg/tests/api/alerting/api_convert_prometheus_test.go b/pkg/tests/api/alerting/api_convert_prometheus_test.go index ec881bc09c5..e07382e6bca 100644 --- a/pkg/tests/api/alerting/api_convert_prometheus_test.go +++ b/pkg/tests/api/alerting/api_convert_prometheus_test.go @@ -12,6 +12,7 @@ import ( "github.com/grafana/grafana/pkg/expr" "github.com/grafana/grafana/pkg/services/datasources" apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions" + "github.com/grafana/grafana/pkg/services/ngalert/models" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/tests/testinfra" @@ -603,6 +604,122 @@ func TestIntegrationConvertPrometheusEndpoints_FolderUIDHeader(t *testing.T) { }) } +func TestIntegrationConvertPrometheusEndpoints_Provenance(t *testing.T) { + runTest := func(t *testing.T, enableLokiPaths bool) { + testinfra.SQLiteIntegrationTest(t) + + // Setup Grafana and its Database + dir, gpath := testinfra.CreateGrafDir(t, testinfra.GrafanaOpts{ + DisableLegacyAlerting: true, + EnableUnifiedAlerting: true, + DisableAnonymous: true, + AppModeProduction: true, + EnableFeatureToggles: []string{"alertingConversionAPI", "grafanaManagedRecordingRulesDatasources", "grafanaManagedRecordingRules"}, + EnableRecordingRules: true, + }) + + grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, gpath) + + // Create admin user + createUser(t, env.SQLStore, env.Cfg, user.CreateUserCommand{ + DefaultOrgRole: string(org.RoleAdmin), + Password: "password", + Login: "admin", + }) + adminClient := newAlertingApiClient(grafanaListedAddr, "admin", "password") + adminClient.prometheusConversionUseLokiPaths = enableLokiPaths + + ds := adminClient.CreateDatasource(t, datasources.DS_PROMETHEUS) + + t.Run("default provenance is ProvenanceConvertedPrometheus", func(t *testing.T) { + namespace := "test-namespace-provenance-" + util.GenerateShortUID() + + // We have to create a folder to get its UID to use in the ruler API later to fetch the rule group. + namespaceUID := util.GenerateShortUID() + adminClient.CreateFolder(t, namespaceUID, namespace) + + adminClient.ConvertPrometheusPostRuleGroup(t, namespace, ds.Body.Datasource.UID, promGroup1, nil) + + // Get the rule group using the ruler API and check its provenance + ruleGroup, status := adminClient.GetRulesGroup(t, namespaceUID, promGroup1.Name) + require.Equal(t, http.StatusAccepted, status) + for _, rule := range ruleGroup.Rules { + require.Equal(t, apimodels.Provenance(models.ProvenanceConvertedPrometheus), rule.GrafanaManagedAlert.Provenance) + } + }) + + t.Run("with disable provenance header should use ProvenanceNone", func(t *testing.T) { + namespace := "test-namespace-provenance-" + util.GenerateShortUID() + + // We have to create a folder to get its UID to use in the ruler API later to fetch the rule group. + namespaceUID := util.GenerateShortUID() + adminClient.CreateFolder(t, namespaceUID, namespace) + + // Create rule group with the X-Disable-Provenance header + headers := map[string]string{ + "X-Disable-Provenance": "true", + } + adminClient.ConvertPrometheusPostRuleGroup(t, namespace, ds.Body.Datasource.UID, promGroup1, headers) + + // Get the rule group using the ruler API and check its provenance + ruleGroup, status := adminClient.GetRulesGroup(t, namespaceUID, promGroup1.Name) + require.Equal(t, http.StatusAccepted, status) + for _, rule := range ruleGroup.Rules { + require.Equal(t, apimodels.Provenance(models.ProvenanceNone), rule.GrafanaManagedAlert.Provenance) + } + }) + + t.Run("can delete rule groups with X-Disable-Provenance header", func(t *testing.T) { + namespace := "test-namespace-delete-provenance-" + util.GenerateShortUID() + namespaceUID := util.GenerateShortUID() + adminClient.CreateFolder(t, namespaceUID, namespace) + + // Create a rule group + adminClient.ConvertPrometheusPostRuleGroup(t, namespace, ds.Body.Datasource.UID, promGroup1, nil) + + // Now try to delete with X-Disable-Provenance header + // This should succeed + headers := map[string]string{ + "X-Disable-Provenance": "true", + } + adminClient.ConvertPrometheusDeleteRuleGroup(t, namespace, promGroup1.Name, headers) + + // Verify the rule group is gone + _, status, _ := adminClient.GetRulesGroupWithStatus(t, namespaceUID, promGroup1.Name) + require.Equal(t, http.StatusNotFound, status) + }) + + t.Run("can delete namespaces with X-Disable-Provenance header", func(t *testing.T) { + namespace := "test-namespace-delete-ns-provenance-" + util.GenerateShortUID() + namespaceUID := util.GenerateShortUID() + adminClient.CreateFolder(t, namespaceUID, namespace) + + // Create a rule group with provenance=ProvenanceConvertedPrometheus + adminClient.ConvertPrometheusPostRuleGroup(t, namespace, ds.Body.Datasource.UID, promGroup1, nil) + + // Now delete with X-Disable-Provenance header + // This should succeed + headers := map[string]string{ + "X-Disable-Provenance": "true", + } + adminClient.ConvertPrometheusDeleteNamespace(t, namespace, headers) + + // Verify the namespace has no rule groups + namespaces := adminClient.ConvertPrometheusGetAllRules(t, nil) + _, exists := namespaces[namespace] + require.False(t, exists) + }) + } + + t.Run("with the mimirtool paths", func(t *testing.T) { + runTest(t, false) + }) + + t.Run("with the cortextool Loki paths", func(t *testing.T) { + runTest(t, true) + }) +} + func TestIntegrationConvertPrometheusEndpoints_Delete(t *testing.T) { runTest := func(t *testing.T, enableLokiPaths bool) { testinfra.SQLiteIntegrationTest(t) From fca3d07286b72ea6cd8c00f1de95e041ed60125c Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Tue, 11 Mar 2025 22:24:35 +0300 Subject: [PATCH 63/63] Provisioning: Expose stats (#101927) --- pkg/apis/provisioning/v0alpha1/types.go | 27 ++++-- .../v0alpha1/zz_generated.deepcopy.go | 32 +++++- .../v0alpha1/zz_generated.openapi.go | 76 +++++++++++++-- ...enerated.openapi_violation_exceptions.list | 3 +- .../provisioning/v0alpha1/resourcecount.go | 15 +-- .../apis/provisioning/jobs/sync/worker.go | 4 +- pkg/registry/apis/provisioning/register.go | 58 +++++++---- .../apis/provisioning/resources/object.go | 97 ++++++++++++++++--- .../provisioning.grafana.app-v0alpha1.json | 45 ++++++++- .../provisioning/api/endpoints.gen.ts | 14 ++- 10 files changed, 303 insertions(+), 68 deletions(-) diff --git a/pkg/apis/provisioning/v0alpha1/types.go b/pkg/apis/provisioning/v0alpha1/types.go index b14bb2592da..170b655d999 100644 --- a/pkg/apis/provisioning/v0alpha1/types.go +++ b/pkg/apis/provisioning/v0alpha1/types.go @@ -348,16 +348,31 @@ type ResourceStats struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` + // Stats across all unified storage + // When legacy storage is still used, this will offer a shim // +listType=atomic - Items []ResourceCount `json:"items,omitempty"` + Instance []ResourceCount `json:"instance,omitempty"` + + // Stats for each manager + // +listType=atomic + Managed []ManagerStats `json:"managed,omitempty"` +} + +type ManagerStats struct { + // Manager kind + Kind utils.ManagerKind `json:"kind,omitempty"` + + // Manager identity + Identity string `json:"id,omitempty"` + + // stats + Stats []ResourceCount `json:"stats"` } type ResourceCount struct { - Kind utils.ManagerKind `json:"kind,omitempty"` - Identity string `json:"id,omitempty"` - Group string `json:"group"` - Resource string `json:"resource"` - Count int64 `json:"count"` + Group string `json:"group"` + Resource string `json:"resource"` + Count int64 `json:"count"` } // HistoryList is a list of versions of a resource diff --git a/pkg/apis/provisioning/v0alpha1/zz_generated.deepcopy.go b/pkg/apis/provisioning/v0alpha1/zz_generated.deepcopy.go index 6cdc255840a..6ab9dfc8a11 100644 --- a/pkg/apis/provisioning/v0alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/provisioning/v0alpha1/zz_generated.deepcopy.go @@ -352,6 +352,27 @@ func (in *LocalRepositoryConfig) DeepCopy() *LocalRepositoryConfig { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ManagerStats) DeepCopyInto(out *ManagerStats) { + *out = *in + if in.Stats != nil { + in, out := &in.Stats, &out.Stats + *out = make([]ResourceCount, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManagerStats. +func (in *ManagerStats) DeepCopy() *ManagerStats { + if in == nil { + return nil + } + out := new(ManagerStats) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *MigrateJobOptions) DeepCopyInto(out *MigrateJobOptions) { *out = *in @@ -656,11 +677,18 @@ func (in *ResourceStats) DeepCopyInto(out *ResourceStats) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items + if in.Instance != nil { + in, out := &in.Instance, &out.Instance *out = make([]ResourceCount, len(*in)) copy(*out, *in) } + if in.Managed != nil { + in, out := &in.Managed, &out.Managed + *out = make([]ManagerStats, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } diff --git a/pkg/apis/provisioning/v0alpha1/zz_generated.openapi.go b/pkg/apis/provisioning/v0alpha1/zz_generated.openapi.go index 91e3ae5de2d..ec6e3c0cdbc 100644 --- a/pkg/apis/provisioning/v0alpha1/zz_generated.openapi.go +++ b/pkg/apis/provisioning/v0alpha1/zz_generated.openapi.go @@ -28,6 +28,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.JobSpec": schema_pkg_apis_provisioning_v0alpha1_JobSpec(ref), "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.JobStatus": schema_pkg_apis_provisioning_v0alpha1_JobStatus(ref), "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.LocalRepositoryConfig": schema_pkg_apis_provisioning_v0alpha1_LocalRepositoryConfig(ref), + "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.ManagerStats": schema_pkg_apis_provisioning_v0alpha1_ManagerStats(ref), "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.MigrateJobOptions": schema_pkg_apis_provisioning_v0alpha1_MigrateJobOptions(ref), "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.PullRequestJobOptions": schema_pkg_apis_provisioning_v0alpha1_PullRequestJobOptions(ref), "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.Repository": schema_pkg_apis_provisioning_v0alpha1_Repository(ref), @@ -761,6 +762,49 @@ func schema_pkg_apis_provisioning_v0alpha1_LocalRepositoryConfig(ref common.Refe } } +func schema_pkg_apis_provisioning_v0alpha1_ManagerStats(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Manager kind", + Type: []string{"string"}, + Format: "", + }, + }, + "id": { + SchemaProps: spec.SchemaProps{ + Description: "Manager identity", + Type: []string{"string"}, + Format: "", + }, + }, + "stats": { + SchemaProps: spec.SchemaProps{ + Description: "stats", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.ResourceCount"), + }, + }, + }, + }, + }, + }, + Required: []string{"stats"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.ResourceCount"}, + } +} + func schema_pkg_apis_provisioning_v0alpha1_MigrateJobOptions(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -1187,12 +1231,6 @@ func schema_pkg_apis_provisioning_v0alpha1_ResourceCount(ref common.ReferenceCal SchemaProps: spec.SchemaProps{ Type: []string{"object"}, Properties: map[string]spec.Schema{ - "repository": { - SchemaProps: spec.SchemaProps{ - Type: []string{"string"}, - Format: "", - }, - }, "group": { SchemaProps: spec.SchemaProps{ Default: "", @@ -1468,14 +1506,15 @@ func schema_pkg_apis_provisioning_v0alpha1_ResourceStats(ref common.ReferenceCal Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), }, }, - "items": { + "instance": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ "x-kubernetes-list-type": "atomic", }, }, SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, + Description: "Stats across all unified storage When legacy storage is still used, this will offer a shim", + Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -1486,11 +1525,30 @@ func schema_pkg_apis_provisioning_v0alpha1_ResourceStats(ref common.ReferenceCal }, }, }, + "managed": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Stats for each manager", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.ManagerStats"), + }, + }, + }, + }, + }, }, }, }, Dependencies: []string{ - "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.ResourceCount", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.ManagerStats", "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1.ResourceCount", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, } } diff --git a/pkg/apis/provisioning/v0alpha1/zz_generated.openapi_violation_exceptions.list b/pkg/apis/provisioning/v0alpha1/zz_generated.openapi_violation_exceptions.list index 95d45ccebb1..093db63eeab 100644 --- a/pkg/apis/provisioning/v0alpha1/zz_generated.openapi_violation_exceptions.list +++ b/pkg/apis/provisioning/v0alpha1/zz_generated.openapi_violation_exceptions.list @@ -3,14 +3,15 @@ API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provis API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,JobResourceSummary,Errors API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,JobStatus,Errors API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,JobStatus,Summary +API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,ManagerStats,Stats API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositoryList,Items API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositorySpec,Workflows API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositoryViewList,Items API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,ResourceList,Items -API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,ResourceStats,Items API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,TestResults,Errors API rule violation: list_type_missing,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,WebhookStatus,SubscribedEvents API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,JobSpec,PullRequest +API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,ManagerStats,Identity API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,RepositorySpec,GitHub API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,ResourceWrapper,URLs API rule violation: names_match,github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1,SyncStatus,JobID diff --git a/pkg/generated/applyconfiguration/provisioning/v0alpha1/resourcecount.go b/pkg/generated/applyconfiguration/provisioning/v0alpha1/resourcecount.go index 6c0be497a97..8330fbdce42 100644 --- a/pkg/generated/applyconfiguration/provisioning/v0alpha1/resourcecount.go +++ b/pkg/generated/applyconfiguration/provisioning/v0alpha1/resourcecount.go @@ -7,10 +7,9 @@ package v0alpha1 // ResourceCountApplyConfiguration represents a declarative configuration of the ResourceCount type for use // with apply. type ResourceCountApplyConfiguration struct { - Repository *string `json:"repository,omitempty"` - Group *string `json:"group,omitempty"` - Resource *string `json:"resource,omitempty"` - Count *int64 `json:"count,omitempty"` + Group *string `json:"group,omitempty"` + Resource *string `json:"resource,omitempty"` + Count *int64 `json:"count,omitempty"` } // ResourceCountApplyConfiguration constructs a declarative configuration of the ResourceCount type for use with @@ -19,14 +18,6 @@ func ResourceCount() *ResourceCountApplyConfiguration { return &ResourceCountApplyConfiguration{} } -// WithRepository sets the Repository field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Repository field is set to the value of the last call. -func (b *ResourceCountApplyConfiguration) WithRepository(value string) *ResourceCountApplyConfiguration { - b.Repository = &value - return b -} - // WithGroup sets the Group field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Group field is set to the value of the last call. diff --git a/pkg/registry/apis/provisioning/jobs/sync/worker.go b/pkg/registry/apis/provisioning/jobs/sync/worker.go index 5d51f1f1e67..f8706b1271b 100644 --- a/pkg/registry/apis/provisioning/jobs/sync/worker.go +++ b/pkg/registry/apis/provisioning/jobs/sync/worker.go @@ -117,11 +117,11 @@ func (r *SyncWorker) Process(ctx context.Context, repo repository.Repository, jo // Only add stats patch if stats are not nil if stats, err := r.lister.Stats(ctx, cfg.Namespace, cfg.Name); err != nil { logger.Error("unable to read stats", "error", err) - } else if stats != nil && stats.Items != nil { + } else if stats != nil && len(stats.Managed) == 1 { patchOperations = append(patchOperations, map[string]interface{}{ "op": "replace", "path": "/status/stats", - "value": stats.Items, + "value": stats.Managed[0].Stats, }) } diff --git a/pkg/registry/apis/provisioning/register.go b/pkg/registry/apis/provisioning/register.go index 4dd916474e5..70ff8020817 100644 --- a/pkg/registry/apis/provisioning/register.go +++ b/pkg/registry/apis/provisioning/register.go @@ -125,7 +125,7 @@ func NewAPIBuilder( }, render: render, clonedir: clonedir, - resourceLister: resources.NewResourceLister(unified), + resourceLister: resources.NewResourceLister(unified, unified, legacyMigrator, storageStatus), legacyMigrator: legacyMigrator, storageStatus: storageStatus, unified: unified, @@ -737,23 +737,7 @@ spec: } } compBase := "com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1." - schema := oas.Components.Schemas[compBase+"ResourceStats"].Properties["items"] - schema.Items = &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - AllOf: []spec.Schema{ - { - SchemaProps: spec.SchemaProps{ - Ref: spec.MustCreateRef("#/components/schemas/" + compBase + "ResourceCount"), - }, - }, - }, - }, - }, - } - oas.Components.Schemas[compBase+"ResourceStats"].Properties["items"] = schema - - schema = oas.Components.Schemas[compBase+"RepositoryViewList"].Properties["items"] + schema := oas.Components.Schemas[compBase+"RepositoryViewList"].Properties["items"] schema.Items = &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -769,6 +753,44 @@ spec: } oas.Components.Schemas[compBase+"RepositoryViewList"].Properties["items"] = schema + countSpec := &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + AllOf: []spec.Schema{ + { + SchemaProps: spec.SchemaProps{ + Ref: spec.MustCreateRef("#/components/schemas/" + compBase + "ResourceCount"), + }, + }, + }, + }, + }, + } + managerSpec := &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + AllOf: []spec.Schema{ + { + SchemaProps: spec.SchemaProps{ + Ref: spec.MustCreateRef("#/components/schemas/" + compBase + "ManagerStats"), + }, + }, + }, + }, + }, + } + schema = oas.Components.Schemas[compBase+"ResourceStats"].Properties["instance"] + schema.Items = countSpec + oas.Components.Schemas[compBase+"ResourceStats"].Properties["instance"] = schema + + schema = oas.Components.Schemas[compBase+"ResourceStats"].Properties["managed"] + schema.Items = managerSpec + oas.Components.Schemas[compBase+"ResourceStats"].Properties["managed"] = schema + + schema = oas.Components.Schemas[compBase+"ManagerStats"].Properties["stats"] + schema.Items = countSpec + oas.Components.Schemas[compBase+"ManagerStats"].Properties["stats"] = schema + return oas, nil } diff --git a/pkg/registry/apis/provisioning/resources/object.go b/pkg/registry/apis/provisioning/resources/object.go index 38c676eb8da..db90b53df73 100644 --- a/pkg/registry/apis/provisioning/resources/object.go +++ b/pkg/registry/apis/provisioning/resources/object.go @@ -3,8 +3,12 @@ package resources import ( "context" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/grafana/grafana/pkg/apimachinery/utils" provisioning "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1" + "github.com/grafana/grafana/pkg/registry/apis/dashboard/legacy" + "github.com/grafana/grafana/pkg/storage/legacysql/dualwrite" "github.com/grafana/grafana/pkg/storage/unified/resource" ) @@ -15,18 +19,29 @@ type ResourceLister interface { } type ResourceListerFromSearch struct { - index resource.ManagedObjectIndexClient + managed resource.ManagedObjectIndexClient + index resource.ResourceIndexClient + legacyMigrator legacy.LegacyMigrator + storageStatus dualwrite.Service } -func NewResourceLister(index resource.ManagedObjectIndexClient) ResourceLister { +func NewResourceLister( + managed resource.ManagedObjectIndexClient, + index resource.ResourceIndexClient, + legacyMigrator legacy.LegacyMigrator, + storageStatus dualwrite.Service, +) ResourceLister { return &ResourceListerFromSearch{ - index: index, + index: index, + managed: managed, + legacyMigrator: legacyMigrator, + storageStatus: storageStatus, } } // List implements ResourceLister. func (o *ResourceListerFromSearch) List(ctx context.Context, namespace, repository string) (*provisioning.ResourceList, error) { - objects, err := o.index.ListManagedObjects(ctx, &resource.ListManagedObjectsRequest{ + objects, err := o.managed.ListManagedObjects(ctx, &resource.ListManagedObjectsRequest{ Namespace: namespace, Kind: string(utils.ManagerKindRepo), Id: repository, @@ -56,11 +71,15 @@ func (o *ResourceListerFromSearch) List(ctx context.Context, namespace, reposito // Stats implements ResourceLister. func (o *ResourceListerFromSearch) Stats(ctx context.Context, namespace, repository string) (*provisioning.ResourceStats, error) { - counts, err := o.index.CountManagedObjects(ctx, &resource.CountManagedObjectsRequest{ + req := &resource.CountManagedObjectsRequest{ Namespace: namespace, - Kind: string(utils.ManagerKindRepo), - Id: repository, - }) + } + if repository != "" { + req.Kind = string(utils.ManagerKindRepo) + req.Id = repository + } + + counts, err := o.managed.CountManagedObjects(ctx, req) if err != nil { return nil, err } @@ -68,12 +87,66 @@ func (o *ResourceListerFromSearch) Stats(ctx context.Context, namespace, reposit return nil, resource.GetError(counts.Error) } - stats := &provisioning.ResourceStats{} + lookup := make(map[string]*provisioning.ManagerStats) for _, v := range counts.Items { - stats.Items = append(stats.Items, provisioning.ResourceCount{ - Kind: utils.ManagerKind(v.Kind), - Identity: v.Id, + key := v.Kind + ":" + v.Id + m := lookup[key] + if m == nil { + m = &provisioning.ManagerStats{ + Kind: utils.ManagerKind(v.Kind), + Identity: v.Id, + } + lookup[key] = m + } + m.Stats = append(m.Stats, provisioning.ResourceCount{ + Group: v.Group, + Resource: v.Resource, + Count: v.Count, + }) + } + stats := &provisioning.ResourceStats{ + TypeMeta: metav1.TypeMeta{ + APIVersion: provisioning.SchemeGroupVersion.String(), + Kind: "ResourceStats", + }, + } + for _, v := range lookup { + stats.Managed = append(stats.Managed, *v) + } + // When selecting an explicit repository, do not fetch global stats + if repository != "" { + return stats, nil + } + + // Get the stats based on what a migration could support + if dualwrite.IsReadingLegacyDashboardsAndFolders(ctx, o.storageStatus) { + rsp, err := o.legacyMigrator.Migrate(ctx, legacy.MigrateOptions{ + Namespace: namespace, + WithHistory: false, + OnlyCount: true, + }) + if err != nil { + return nil, err + } + for _, v := range rsp.Summary { + stats.Instance = append(stats.Instance, provisioning.ResourceCount{ + Group: v.Group, + Resource: v.Resource, + Count: v.Count, + }) + } + } + + // Get full instance stats + info, err := o.index.GetStats(ctx, &resource.ResourceStatsRequest{ + Namespace: namespace, + }) + if err != nil { + return nil, err + } + for _, v := range info.Stats { + stats.Instance = append(stats.Instance, provisioning.ResourceCount{ Group: v.Group, Resource: v.Resource, Count: v.Count, diff --git a/pkg/tests/apis/openapi_snapshots/provisioning.grafana.app-v0alpha1.json b/pkg/tests/apis/openapi_snapshots/provisioning.grafana.app-v0alpha1.json index d8c30691224..7e305e99568 100644 --- a/pkg/tests/apis/openapi_snapshots/provisioning.grafana.app-v0alpha1.json +++ b/pkg/tests/apis/openapi_snapshots/provisioning.grafana.app-v0alpha1.json @@ -2990,6 +2990,33 @@ } } }, + "com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1.ManagerStats": { + "type": "object", + "required": [ + "stats" + ], + "properties": { + "id": { + "description": "Manager identity", + "type": "string" + }, + "kind": { + "description": "Manager kind", + "type": "string" + }, + "stats": { + "description": "stats", + "type": "array", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1.ResourceCount" + } + ] + } + } + } + }, "com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1.MigrateJobOptions": { "type": "object", "required": [ @@ -3344,9 +3371,6 @@ "type": "string", "default": "" }, - "repository": { - "type": "string" - }, "resource": { "type": "string", "default": "" @@ -3543,7 +3567,8 @@ "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", "type": "string" }, - "items": { + "instance": { + "description": "Stats across all unified storage When legacy storage is still used, this will offer a shim", "type": "array", "items": { "allOf": [ @@ -3558,6 +3583,18 @@ "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", "type": "string" }, + "managed": { + "description": "Stats for each manager", + "type": "array", + "items": { + "allOf": [ + { + "$ref": "#/components/schemas/com.github.grafana.grafana.pkg.apis.provisioning.v0alpha1.ManagerStats" + } + ] + }, + "x-kubernetes-list-type": "atomic" + }, "metadata": { "default": {} } diff --git a/public/app/features/provisioning/api/endpoints.gen.ts b/public/app/features/provisioning/api/endpoints.gen.ts index 0efebda5b12..fd8429fee34 100644 --- a/public/app/features/provisioning/api/endpoints.gen.ts +++ b/public/app/features/provisioning/api/endpoints.gen.ts @@ -899,7 +899,6 @@ export type HealthStatus = { export type ResourceCount = { count: number; group: string; - repository?: string; resource: string; }; export type SyncStatus = { @@ -1162,12 +1161,23 @@ export type RepositoryViewList = { /** The backend is using legacy storage FIXME: Not sure where this should be exposed... but we need it somewhere The UI should force the onboarding workflow when this is true */ legacyStorage?: boolean; }; +export type ManagerStats = { + /** Manager identity */ + id?: string; + /** Manager kind */ + kind?: string; + /** stats */ + stats: ResourceCount[]; +}; export type ResourceStats = { /** APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources */ apiVersion?: string; - items?: ResourceCount[]; + /** Stats across all unified storage When legacy storage is still used, this will offer a shim */ + instance?: ResourceCount[]; /** Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds */ kind?: string; + /** Stats for each manager */ + managed?: ManagerStats[]; metadata?: any; }; export const {