From 0d2a786816c7bac6bb14ab8ca2233a3e95c12da8 Mon Sep 17 00:00:00 2001 From: Ryan McKinley Date: Sun, 29 Jan 2023 20:14:12 -0800 Subject: [PATCH] Schema: Add schema for library panels (#62169) --- .betterer.results | 12 +- .../core/librarypanel/schema-reference.md | 70 ++++++ kinds/dashboard/dashboard_kind.cue | 8 + kinds/librarypanel/librarypanel_kind.cue | 63 +++++ packages/grafana-schema/src/index.gen.ts | 18 ++ .../raw/dashboard/x/dashboard_types.gen.ts | 9 + .../librarypanel/x/librarypanel_types.gen.ts | 65 ++++++ .../src/veneer/librarypanel.types.ts | 7 + pkg/kinds/dashboard/dashboard_types_gen.go | 9 +- .../librarypanel/librarypanel_kind_gen.go | 113 +++++++++ .../librarypanel/librarypanel_types_gen.go | 58 +++++ pkg/kindsys/report.json | 32 ++- pkg/registry/corekind/base_gen.go | 14 ++ pkg/services/libraryelements/database.go | 67 +++--- .../libraryelements_create_test.go | 37 +-- .../libraryelements_get_all_test.go | 217 +++++++++--------- .../libraryelements_get_test.go | 25 +- .../libraryelements_patch_test.go | 31 +-- .../libraryelements_permissions_test.go | 16 +- .../libraryelements/libraryelements_test.go | 7 +- pkg/services/libraryelements/models.go | 27 +-- .../librarypanels/librarypanels_test.go | 25 +- .../AddPanelWidget/AddPanelWidget.tsx | 2 +- .../DashExportModal/DashboardExporter.ts | 2 +- .../features/dashboard/state/PanelModel.ts | 6 +- .../LibraryPanelCard/LibraryPanelCard.tsx | 2 +- .../LibraryPanelsSearch.test.tsx | 18 +- .../LibraryPanelsView/reducer.test.ts | 11 +- .../SaveLibraryPanelModal.tsx | 4 +- public/app/features/library-panels/types.ts | 46 +--- .../ImportDashboardLibraryPanelsList.tsx | 4 +- .../manage-dashboards/state/actions.ts | 2 - 32 files changed, 724 insertions(+), 303 deletions(-) create mode 100644 docs/sources/developers/kinds/core/librarypanel/schema-reference.md create mode 100644 kinds/librarypanel/librarypanel_kind.cue create mode 100644 packages/grafana-schema/src/raw/librarypanel/x/librarypanel_types.gen.ts create mode 100644 packages/grafana-schema/src/veneer/librarypanel.types.ts create mode 100644 pkg/kinds/librarypanel/librarypanel_kind_gen.go create mode 100644 pkg/kinds/librarypanel/librarypanel_types_gen.go diff --git a/.betterer.results b/.betterer.results index 43127440a4e..f20d99d74fb 100644 --- a/.betterer.results +++ b/.betterer.results @@ -3106,8 +3106,10 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "6"], [0, 0, 0, "Unexpected any. Specify a different type.", "7"], [0, 0, 0, "Do not use any type assertions.", "8"], - [0, 0, 0, "Do not use any type assertions.", "9"], - [0, 0, 0, "Unexpected any. Specify a different type.", "10"] + [0, 0, 0, "Unexpected any. Specify a different type.", "9"], + [0, 0, 0, "Do not use any type assertions.", "10"], + [0, 0, 0, "Do not use any type assertions.", "11"], + [0, 0, 0, "Unexpected any. Specify a different type.", "12"] ], "public/app/features/dashboard/components/DashboardPrompt/DashboardPrompt.test.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -3988,9 +3990,6 @@ exports[`better eslint`] = { "public/app/features/library-panels/components/LibraryPanelsView/actions.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/app/features/library-panels/types.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"] - ], "public/app/features/library-panels/utils.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] @@ -4091,6 +4090,9 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "4"], [0, 0, 0, "Unexpected any. Specify a different type.", "5"] ], + "public/app/features/manage-dashboards/components/ImportDashboardLibraryPanelsList.tsx:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"] + ], "public/app/features/manage-dashboards/components/SnapshotListTable.test.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], diff --git a/docs/sources/developers/kinds/core/librarypanel/schema-reference.md b/docs/sources/developers/kinds/core/librarypanel/schema-reference.md new file mode 100644 index 00000000000..6ac3ad434f7 --- /dev/null +++ b/docs/sources/developers/kinds/core/librarypanel/schema-reference.md @@ -0,0 +1,70 @@ +--- +keywords: + - grafana + - schema +title: LibraryPanel kind +--- +> Both documentation generation and kinds schemas are in active development and subject to change without prior notice. + +# LibraryPanel kind + +## Maturity: experimental +## Version: 0.0 + +## Properties + +| Property | Type | Required | Description | +|-----------------|-------------------------------------------------|----------|--------------------------------------------------------------------------------------------------------------------------------------| +| `model` | [object](#model) | **Yes** | TODO: should be the same panel schema defined in dashboard
Typescript: Omit; | +| `name` | string | **Yes** | Panel name (also saved in the model) | +| `type` | string | **Yes** | The panel type (from inside the model) | +| `uid` | string | **Yes** | Library element UID | +| `version` | integer | **Yes** | panel version, incremented each time the dashboard is updated. | +| `description` | string | No | Panel description | +| `folderUid` | string | No | Folder UID | +| `meta` | [LibraryElementDTOMeta](#libraryelementdtometa) | No | | +| `schemaVersion` | integer | No | Dashboard version when this was saved (zero if unknown) | + +## LibraryElementDTOMeta + +### Properties + +| Property | Type | Required | Description | +|-----------------------|---------------------------------------------------------|----------|-------------| +| `connectedDashboards` | integer | **Yes** | | +| `createdBy` | [LibraryElementDTOMetaUser](#libraryelementdtometauser) | **Yes** | | +| `created` | string | **Yes** | | +| `folderName` | string | **Yes** | | +| `folderUid` | string | **Yes** | | +| `updatedBy` | [LibraryElementDTOMetaUser](#libraryelementdtometauser) | **Yes** | | +| `updated` | string | **Yes** | | + +### LibraryElementDTOMetaUser + +#### Properties + +| Property | Type | Required | Description | +|-------------|---------|----------|-------------| +| `avatarUrl` | string | **Yes** | | +| `id` | integer | **Yes** | | +| `name` | string | **Yes** | | + +### LibraryElementDTOMetaUser + +#### Properties + +| Property | Type | Required | Description | +|-------------|---------|----------|-------------| +| `avatarUrl` | string | **Yes** | | +| `id` | integer | **Yes** | | +| `name` | string | **Yes** | | + +## model + +TODO: should be the same panel schema defined in dashboard +Typescript: Omit; + +| Property | Type | Required | Description | +|----------|------|----------|-------------| + + diff --git a/kinds/dashboard/dashboard_kind.cue b/kinds/dashboard/dashboard_kind.cue index 2aa725ad809..002331eb31b 100644 --- a/kinds/dashboard/dashboard_kind.cue +++ b/kinds/dashboard/dashboard_kind.cue @@ -397,6 +397,9 @@ lineage: seqs: [ // TODO tighter constraint timeShift?: string @grafanamaturity(NeedsExpertReview) + // Dynamically load the panel + libraryPanel?: #LibraryPanelRef + // options is specified by the PanelOptions field in panel // plugin schemas. options: {...} @grafanamaturity(NeedsExpertReview) @@ -412,6 +415,11 @@ lineage: seqs: [ }] @grafanamaturity(NeedsExpertReview) } @cuetsy(kind="interface") @grafana(TSVeneer="type") @grafanamaturity(NeedsExpertReview) + #LibraryPanelRef: { + name: string + uid: string + } @cuetsy(kind="interface") + #MatcherConfig: { id: string | *"" @grafanamaturity(NeedsExpertReview) options?: _ @grafanamaturity(NeedsExpertReview) diff --git a/kinds/librarypanel/librarypanel_kind.cue b/kinds/librarypanel/librarypanel_kind.cue new file mode 100644 index 00000000000..6a9cbd5c897 --- /dev/null +++ b/kinds/librarypanel/librarypanel_kind.cue @@ -0,0 +1,63 @@ +package kind + +import "strings" + +name: "LibraryPanel" +maturity: "experimental" + +lineage: seqs: [ + { + schemas: [ + // 0.0 + { + @grafana(TSVeneer="type") + + // Folder UID + folderUid?: string @grafanamaturity(ToMetadata="sys") + + // Library element UID + uid: string + + // Panel name (also saved in the model) + name: string & strings.MinRunes(1) + + // Panel description + description?: string + + // The panel type (from inside the model) + type: string & strings.MinRunes(1) + + // Dashboard version when this was saved (zero if unknown) + schemaVersion?: uint16 + + // panel version, incremented each time the dashboard is updated. + version: int64 @grafanamaturity(NeedsExpertReview) + + // TODO: should be the same panel schema defined in dashboard + // Typescript: Omit; + model: {...} + + // Object storage metadata + meta?: #LibraryElementDTOMeta @grafanamaturity(ToMetadata="sys") + + #LibraryElementDTOMetaUser: { + id: int64 + name: string + avatarUrl: string + } @cuetsy(kind="interface") @grafanamaturity(NeedsExpertReview) + + #LibraryElementDTOMeta: { + folderName: string + folderUid: string @grafanamaturity(ToMetadata="sys") + connectedDashboards: int64 + + created: string @grafanamaturity(ToMetadata="sys") // time.Time in golang + updated: string @grafanamaturity(ToMetadata="sys") // time.Time in golang + + createdBy: #LibraryElementDTOMetaUser @grafanamaturity(ToMetadata="sys") + updatedBy: #LibraryElementDTOMetaUser @grafanamaturity(ToMetadata="sys") + } @cuetsy(kind="interface") @grafanamaturity(NeedsExpertReview) + }, + ] + }, +] diff --git a/packages/grafana-schema/src/index.gen.ts b/packages/grafana-schema/src/index.gen.ts index a7a76a0c3df..f37d525a6ad 100644 --- a/packages/grafana-schema/src/index.gen.ts +++ b/packages/grafana-schema/src/index.gen.ts @@ -26,6 +26,7 @@ export type { SpecialValueMap, ValueMappingResult, Transformation, + LibraryPanelRef, RowPanel, GraphPanel, HeatmapPanel @@ -86,6 +87,23 @@ export { defaultFieldConfig } from './veneer/dashboard.types'; +// Raw generated types from LibraryPanel kind. +export type { + LibraryElementDTOMetaUser, + LibraryElementDTOMeta +} from './raw/librarypanel/x/librarypanel_types.gen'; + +// The following exported declarations correspond to types in the librarypanel@0.0 kind's +// schema with attribute @grafana(TSVeneer="type"). +// +// The handwritten file for these type and default veneers is expected to be at +// packages/grafana-schema/src/veneer/librarypanel.types.ts. +// This re-export declaration enforces that the handwritten veneer file exists, +// and exports all the symbols in the list. +// +// TODO generate code such that tsc enforces type compatibility between raw and veneer decls +export type { LibraryPanel } from './veneer/librarypanel.types'; + // Raw generated types from Playlist kind. export type { Playlist, diff --git a/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts b/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts index 706d6522ba9..95b22b152ce 100644 --- a/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts +++ b/packages/grafana-schema/src/raw/dashboard/x/dashboard_types.gen.ts @@ -404,6 +404,10 @@ export interface Panel { * TODO tighter constraint */ interval?: string; + /** + * Dynamically load the panel + */ + libraryPanel?: LibraryPanelRef; /** * Panel links. * TODO fill this out - seems there are a couple variants? @@ -503,6 +507,11 @@ export const defaultFieldConfigSource: Partial = { overrides: [], }; +export interface LibraryPanelRef { + name: string; + uid: string; +} + export interface MatcherConfig { id: string; options?: unknown; diff --git a/packages/grafana-schema/src/raw/librarypanel/x/librarypanel_types.gen.ts b/packages/grafana-schema/src/raw/librarypanel/x/librarypanel_types.gen.ts new file mode 100644 index 00000000000..97cba2a5c5e --- /dev/null +++ b/packages/grafana-schema/src/raw/librarypanel/x/librarypanel_types.gen.ts @@ -0,0 +1,65 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. +// +// Generated by: +// kinds/gen.go +// Using jennies: +// TSTypesJenny +// LatestMajorsOrXJenny +// +// Run 'make gen-cue' from repository root to regenerate. + +export interface LibraryElementDTOMetaUser { + avatarUrl: string; + id: number; + name: string; +} + +export interface LibraryElementDTOMeta { + connectedDashboards: number; + created: string; + createdBy: LibraryElementDTOMetaUser; + folderName: string; + folderUid: string; + updated: string; + updatedBy: LibraryElementDTOMetaUser; +} + +export interface LibraryPanel { + /** + * Panel description + */ + description?: string; + /** + * Folder UID + */ + folderUid?: string; + /** + * Object storage metadata + */ + meta?: LibraryElementDTOMeta; + /** + * TODO: should be the same panel schema defined in dashboard + * Typescript: Omit; + */ + model: Record; + /** + * Panel name (also saved in the model) + */ + name: string; + /** + * Dashboard version when this was saved (zero if unknown) + */ + schemaVersion?: number; + /** + * The panel type (from inside the model) + */ + type: string; + /** + * Library element UID + */ + uid: string; + /** + * panel version, incremented each time the dashboard is updated. + */ + version: number; +} diff --git a/packages/grafana-schema/src/veneer/librarypanel.types.ts b/packages/grafana-schema/src/veneer/librarypanel.types.ts new file mode 100644 index 00000000000..007bb085742 --- /dev/null +++ b/packages/grafana-schema/src/veneer/librarypanel.types.ts @@ -0,0 +1,7 @@ +import * as raw from '../raw/librarypanel/x/librarypanel_types.gen'; + +import { Panel } from './dashboard.types'; + +export interface LibraryPanel extends raw.LibraryPanel { + model: Omit; +} diff --git a/pkg/kinds/dashboard/dashboard_types_gen.go b/pkg/kinds/dashboard/dashboard_types_gen.go index 7ed218331cc..9fdc6e22532 100644 --- a/pkg/kinds/dashboard/dashboard_types_gen.go +++ b/pkg/kinds/dashboard/dashboard_types_gen.go @@ -458,6 +458,12 @@ type HeatmapPanel struct { // HeatmapPanelType defines model for HeatmapPanel.Type. type HeatmapPanelType string +// LibraryPanelRef defines model for LibraryPanelRef. +type LibraryPanelRef struct { + Name string `json:"name"` + Uid string `json:"uid"` +} + // LoadingState defines model for LoadingState. type LoadingState string @@ -490,7 +496,8 @@ type Panel struct { // TODO docs // TODO tighter constraint - Interval *string `json:"interval,omitempty"` + Interval *string `json:"interval,omitempty"` + LibraryPanel *LibraryPanelRef `json:"libraryPanel,omitempty"` // Panel links. // TODO fill this out - seems there are a couple variants? diff --git a/pkg/kinds/librarypanel/librarypanel_kind_gen.go b/pkg/kinds/librarypanel/librarypanel_kind_gen.go new file mode 100644 index 00000000000..564ddfb169c --- /dev/null +++ b/pkg/kinds/librarypanel/librarypanel_kind_gen.go @@ -0,0 +1,113 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. +// +// Generated by: +// kinds/gen.go +// Using jennies: +// CoreKindJenny +// +// Run 'make gen-cue' from repository root to regenerate. + +package librarypanel + +import ( + "github.com/grafana/grafana/pkg/kindsys" + "github.com/grafana/thema" + "github.com/grafana/thema/vmux" +) + +// rootrel is the relative path from the grafana repository root to the +// directory containing the .cue files in which this kind is declared. Necessary +// for runtime errors related to the declaration and/or lineage to provide +// a real path to the correct .cue file. +const rootrel string = "kinds/librarypanel" + +// TODO standard generated docs +type Kind struct { + lin thema.ConvergentLineage[*LibraryPanel] + jcodec vmux.Codec + valmux vmux.ValueMux[*LibraryPanel] + decl kindsys.Decl[kindsys.CoreProperties] +} + +// type guard +var _ kindsys.Core = &Kind{} + +// TODO standard generated docs +func NewKind(rt *thema.Runtime, opts ...thema.BindOption) (*Kind, error) { + decl, err := kindsys.LoadCoreKind(rootrel, rt.Context(), nil) + if err != nil { + return nil, err + } + k := &Kind{ + decl: decl, + } + + lin, err := decl.Some().BindKindLineage(rt, opts...) + if err != nil { + return nil, err + } + + // Get the thema.Schema that the meta says is in the current version (which + // codegen ensures is always the latest) + cursch := thema.SchemaP(lin, k.decl.Properties.CurrentVersion) + tsch, err := thema.BindType[*LibraryPanel](cursch, &LibraryPanel{}) + if err != nil { + // Should be unreachable, modulo bugs in the Thema->Go code generator + return nil, err + } + + k.jcodec = vmux.NewJSONCodec("librarypanel.json") + k.lin = tsch.ConvergentLineage() + k.valmux = vmux.NewValueMux(k.lin.TypedSchema(), k.jcodec) + return k, nil +} + +// TODO standard generated docs +func (k *Kind) Name() string { + return "librarypanel" +} + +// TODO standard generated docs +func (k *Kind) MachineName() string { + return "librarypanel" +} + +// TODO standard generated docs +func (k *Kind) Lineage() thema.Lineage { + return k.lin +} + +// TODO standard generated docs +func (k *Kind) ConvergentLineage() thema.ConvergentLineage[*LibraryPanel] { + return k.lin +} + +// JSONValueMux is a version multiplexer that maps a []byte containing JSON data +// at any schematized dashboard version to an instance of LibraryPanel. +// +// Validation and translation errors emitted from this func will identify the +// input bytes as "dashboard.json". +// +// This is a thin wrapper around Thema's [vmux.ValueMux]. +func (k *Kind) JSONValueMux(b []byte) (*LibraryPanel, thema.TranslationLacunas, error) { + return k.valmux(b) +} + +// TODO standard generated docs +func (k *Kind) Maturity() kindsys.Maturity { + return k.decl.Properties.Maturity +} + +// Decl returns the [kindsys.Decl] containing both CUE and Go representations of the +// librarypanel declaration in .cue files. +func (k *Kind) Decl() kindsys.Decl[kindsys.CoreProperties] { + return k.decl +} + +// Props returns a [kindsys.SomeKindProps], with underlying type [kindsys.CoreProperties], +// representing the static properties declared in the librarypanel kind. +// +// This method is identical to calling Decl().Props. It is provided to satisfy [kindsys.Interface]. +func (k *Kind) Props() kindsys.SomeKindProperties { + return k.decl.Properties +} diff --git a/pkg/kinds/librarypanel/librarypanel_types_gen.go b/pkg/kinds/librarypanel/librarypanel_types_gen.go new file mode 100644 index 00000000000..bdd4545030d --- /dev/null +++ b/pkg/kinds/librarypanel/librarypanel_types_gen.go @@ -0,0 +1,58 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. +// +// Generated by: +// kinds/gen.go +// Using jennies: +// GoTypesJenny +// LatestJenny +// +// Run 'make gen-cue' from repository root to regenerate. + +package librarypanel + +// LibraryElementDTOMeta defines model for LibraryElementDTOMeta. +type LibraryElementDTOMeta struct { + ConnectedDashboards int64 `json:"connectedDashboards"` + Created string `json:"created"` + CreatedBy LibraryElementDTOMetaUser `json:"createdBy"` + FolderName string `json:"folderName"` + FolderUid string `json:"folderUid"` + Updated string `json:"updated"` + UpdatedBy LibraryElementDTOMetaUser `json:"updatedBy"` +} + +// LibraryElementDTOMetaUser defines model for LibraryElementDTOMetaUser. +type LibraryElementDTOMetaUser struct { + AvatarUrl string `json:"avatarUrl"` + Id int64 `json:"id"` + Name string `json:"name"` +} + +// LibraryPanel defines model for LibraryPanel. +type LibraryPanel struct { + // Panel description + Description *string `json:"description,omitempty"` + + // Folder UID + FolderUid *string `json:"folderUid,omitempty"` + Meta *LibraryElementDTOMeta `json:"meta,omitempty"` + + // TODO: should be the same panel schema defined in dashboard + // Typescript: Omit; + Model map[string]interface{} `json:"model"` + + // Panel name (also saved in the model) + Name string `json:"name"` + + // Dashboard version when this was saved (zero if unknown) + SchemaVersion *int `json:"schemaVersion,omitempty"` + + // The panel type (from inside the model) + Type string `json:"type"` + + // Library element UID + Uid string `json:"uid"` + + // panel version, incremented each time the dashboard is updated. + Version int64 `json:"version"` +} diff --git a/pkg/kindsys/report.json b/pkg/kindsys/report.json index d6f4b88460e..0944a34047f 100644 --- a/pkg/kindsys/report.json +++ b/pkg/kindsys/report.json @@ -807,6 +807,32 @@ "pluralName": "JaegerDataSourceCfgs", "schemaInterface": "DataSourceCfg" }, + "librarypanel": { + "category": "core", + "codeowners": [ + "grafana/grafana-as-code", + "grafana/grafana-bi-squad", + "grafana/plugins-platform-frontend", + "grafana/user-essentials" + ], + "currentVersion": [ + 0, + 0 + ], + "grafanaMaturityCount": 10, + "lineageIsGroup": false, + "links": { + "docs": "https://grafana.com/docs/grafana/next/developers/kinds/core/librarypanel/schema-reference", + "go": "https://github.com/grafana/grafana/tree/main/pkg/kinds/librarypanel", + "schema": "https://github.com/grafana/grafana/tree/main/kinds/librarypanel/librarypanel_kind.cue", + "ts": "https://github.com/grafana/grafana/tree/main/packages/grafana-schema/src/raw/librarypanel/x/librarypanel_types.gen.ts" + }, + "machineName": "librarypanel", + "maturity": "experimental", + "name": "LibraryPanel", + "pluralMachineName": "librarypanels", + "pluralName": "LibraryPanels" + }, "livepanelcfg": { "category": "composable", "codeowners": [], @@ -1846,6 +1872,7 @@ "dashboard", "datasource", "folder", + "librarypanel", "playlist", "preferences", "publicdashboard", @@ -1856,7 +1883,7 @@ "thumb", "user" ], - "count": 13 + "count": 14 } }, "maturity": { @@ -1870,6 +1897,7 @@ "dashboardlistpanelcfg", "gaugepanelcfg", "histogrampanelcfg", + "librarypanel", "newspanelcfg", "nodegraphpanelcfg", "piechartpanelcfg", @@ -1880,7 +1908,7 @@ "textpanelcfg", "xychartpanelcfg" ], - "count": 16 + "count": 17 }, "mature": { "name": "mature", diff --git a/pkg/registry/corekind/base_gen.go b/pkg/registry/corekind/base_gen.go index 8a180db1ca0..99d00e9c0d0 100644 --- a/pkg/registry/corekind/base_gen.go +++ b/pkg/registry/corekind/base_gen.go @@ -13,6 +13,7 @@ import ( "fmt" "github.com/grafana/grafana/pkg/kinds/dashboard" + "github.com/grafana/grafana/pkg/kinds/librarypanel" "github.com/grafana/grafana/pkg/kinds/playlist" "github.com/grafana/grafana/pkg/kinds/preferences" "github.com/grafana/grafana/pkg/kinds/publicdashboard" @@ -35,6 +36,7 @@ import ( type Base struct { all []kindsys.Core dashboard *dashboard.Kind + librarypanel *librarypanel.Kind playlist *playlist.Kind preferences *preferences.Kind publicdashboard *publicdashboard.Kind @@ -45,6 +47,7 @@ type Base struct { // type guards var ( _ kindsys.Core = &dashboard.Kind{} + _ kindsys.Core = &librarypanel.Kind{} _ kindsys.Core = &playlist.Kind{} _ kindsys.Core = &preferences.Kind{} _ kindsys.Core = &publicdashboard.Kind{} @@ -57,6 +60,11 @@ func (b *Base) Dashboard() *dashboard.Kind { return b.dashboard } +// LibraryPanel returns the [kindsys.Interface] implementation for the librarypanel kind. +func (b *Base) LibraryPanel() *librarypanel.Kind { + return b.librarypanel +} + // Playlist returns the [kindsys.Interface] implementation for the playlist kind. func (b *Base) Playlist() *playlist.Kind { return b.playlist @@ -92,6 +100,12 @@ func doNewBase(rt *thema.Runtime) *Base { } reg.all = append(reg.all, reg.dashboard) + reg.librarypanel, err = librarypanel.NewKind(rt) + if err != nil { + panic(fmt.Sprintf("error while initializing the librarypanel Kind: %s", err)) + } + reg.all = append(reg.all, reg.librarypanel) + reg.playlist, err = playlist.NewKind(rt) if err != nil { panic(fmt.Sprintf("error while initializing the playlist Kind: %s", err)) diff --git a/pkg/services/libraryelements/database.go b/pkg/services/libraryelements/database.go index 99f6f1d3057..ae8f3cf8df3 100644 --- a/pkg/services/libraryelements/database.go +++ b/pkg/services/libraryelements/database.go @@ -10,6 +10,7 @@ import ( "github.com/grafana/grafana/pkg/api/dtos" "github.com/grafana/grafana/pkg/infra/db" + "github.com/grafana/grafana/pkg/kinds/librarypanel" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/org" @@ -166,15 +167,15 @@ func (l *LibraryElementService) createLibraryElement(c context.Context, signedIn ConnectedDashboards: 0, Created: element.Created, Updated: element.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: element.CreatedBy, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: element.CreatedBy, Name: signedInUser.Login, - AvatarURL: dtos.GetGravatarUrl(signedInUser.Email), + AvatarUrl: dtos.GetGravatarUrl(signedInUser.Email), }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: element.UpdatedBy, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: element.UpdatedBy, Name: signedInUser.Login, - AvatarURL: dtos.GetGravatarUrl(signedInUser.Email), + AvatarUrl: dtos.GetGravatarUrl(signedInUser.Email), }, }, } @@ -279,15 +280,15 @@ func getLibraryElements(c context.Context, store db.DB, cfg *setting.Cfg, signed ConnectedDashboards: libraryElement.ConnectedDashboards, Created: libraryElement.Created, Updated: libraryElement.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: libraryElement.CreatedBy, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: libraryElement.CreatedBy, Name: libraryElement.CreatedByName, - AvatarURL: dtos.GetGravatarUrl(libraryElement.CreatedByEmail), + AvatarUrl: dtos.GetGravatarUrl(libraryElement.CreatedByEmail), }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: libraryElement.UpdatedBy, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: libraryElement.UpdatedBy, Name: libraryElement.UpdatedByName, - AvatarURL: dtos.GetGravatarUrl(libraryElement.UpdatedByEmail), + AvatarUrl: dtos.GetGravatarUrl(libraryElement.UpdatedByEmail), }, }, } @@ -392,15 +393,15 @@ func (l *LibraryElementService) getAllLibraryElements(c context.Context, signedI ConnectedDashboards: element.ConnectedDashboards, Created: element.Created, Updated: element.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: element.CreatedBy, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: element.CreatedBy, Name: element.CreatedByName, - AvatarURL: dtos.GetGravatarUrl(element.CreatedByEmail), + AvatarUrl: dtos.GetGravatarUrl(element.CreatedByEmail), }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: element.UpdatedBy, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: element.UpdatedBy, Name: element.UpdatedByName, - AvatarURL: dtos.GetGravatarUrl(element.UpdatedByEmail), + AvatarUrl: dtos.GetGravatarUrl(element.UpdatedByEmail), }, }, }) @@ -541,15 +542,15 @@ func (l *LibraryElementService) patchLibraryElement(c context.Context, signedInU ConnectedDashboards: elementInDB.ConnectedDashboards, Created: libraryElement.Created, Updated: libraryElement.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: elementInDB.CreatedBy, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: elementInDB.CreatedBy, Name: elementInDB.CreatedByName, - AvatarURL: dtos.GetGravatarUrl(elementInDB.CreatedByEmail), + AvatarUrl: dtos.GetGravatarUrl(elementInDB.CreatedByEmail), }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: libraryElement.UpdatedBy, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: libraryElement.UpdatedBy, Name: signedInUser.Login, - AvatarURL: dtos.GetGravatarUrl(signedInUser.Email), + AvatarUrl: dtos.GetGravatarUrl(signedInUser.Email), }, }, } @@ -589,10 +590,10 @@ func (l *LibraryElementService) getConnections(c context.Context, signedInUser * ConnectionID: connection.ConnectionID, ConnectionUID: connection.ConnectionUID, Created: connection.Created, - CreatedBy: LibraryElementDTOMetaUser{ - ID: connection.CreatedBy, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: connection.CreatedBy, Name: connection.CreatedByName, - AvatarURL: dtos.GetGravatarUrl(connection.CreatedByEmail), + AvatarUrl: dtos.GetGravatarUrl(connection.CreatedByEmail), }, }) } @@ -638,15 +639,15 @@ func (l *LibraryElementService) getElementsForDashboardID(c context.Context, das ConnectedDashboards: element.ConnectedDashboards, Created: element.Created, Updated: element.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: element.CreatedBy, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: element.CreatedBy, Name: element.CreatedByName, - AvatarURL: dtos.GetGravatarUrl(element.CreatedByEmail), + AvatarUrl: dtos.GetGravatarUrl(element.CreatedByEmail), }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: element.UpdatedBy, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: element.UpdatedBy, Name: element.UpdatedByName, - AvatarURL: dtos.GetGravatarUrl(element.UpdatedByEmail), + AvatarUrl: dtos.GetGravatarUrl(element.UpdatedByEmail), }, }, } diff --git a/pkg/services/libraryelements/libraryelements_create_test.go b/pkg/services/libraryelements/libraryelements_create_test.go index ecc54aca467..ef71130e19b 100644 --- a/pkg/services/libraryelements/libraryelements_create_test.go +++ b/pkg/services/libraryelements/libraryelements_create_test.go @@ -6,6 +6,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/require" + "github.com/grafana/grafana/pkg/kinds/librarypanel" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/util" ) @@ -45,15 +46,15 @@ func TestCreateLibraryElement(t *testing.T) { ConnectedDashboards: 0, Created: sc.initialResult.Result.Meta.Created, Updated: sc.initialResult.Result.Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: "signed_in_user", - AvatarURL: "/avatar/37524e1eb8b3e32850b57db0a19af93b", + AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b", }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: "signed_in_user", - AvatarURL: "/avatar/37524e1eb8b3e32850b57db0a19af93b", + AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b", }, }, }, @@ -94,15 +95,15 @@ func TestCreateLibraryElement(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Meta.Created, Updated: result.Result.Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: "signed_in_user", - AvatarURL: "/avatar/37524e1eb8b3e32850b57db0a19af93b", + AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b", }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: "signed_in_user", - AvatarURL: "/avatar/37524e1eb8b3e32850b57db0a19af93b", + AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b", }, }, }, @@ -169,15 +170,15 @@ func TestCreateLibraryElement(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Meta.Created, Updated: result.Result.Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: "signed_in_user", - AvatarURL: "/avatar/37524e1eb8b3e32850b57db0a19af93b", + AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b", }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: "signed_in_user", - AvatarURL: "/avatar/37524e1eb8b3e32850b57db0a19af93b", + AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b", }, }, }, diff --git a/pkg/services/libraryelements/libraryelements_get_all_test.go b/pkg/services/libraryelements/libraryelements_get_all_test.go index bac68141c57..2c304eaab2f 100644 --- a/pkg/services/libraryelements/libraryelements_get_all_test.go +++ b/pkg/services/libraryelements/libraryelements_get_all_test.go @@ -8,6 +8,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/require" + "github.com/grafana/grafana/pkg/kinds/librarypanel" "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/services/search" @@ -81,15 +82,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[0].Meta.Created, Updated: result.Result.Elements[0].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -146,15 +147,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[0].Meta.Created, Updated: result.Result.Elements[0].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -208,15 +209,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[0].Meta.Created, Updated: result.Result.Elements[0].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -243,15 +244,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[1].Meta.Created, Updated: result.Result.Elements[1].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -308,15 +309,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[0].Meta.Created, Updated: result.Result.Elements[0].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -343,15 +344,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[1].Meta.Created, Updated: result.Result.Elements[1].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -429,15 +430,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[0].Meta.Created, Updated: result.Result.Elements[0].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -464,15 +465,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[1].Meta.Created, Updated: result.Result.Elements[1].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -568,15 +569,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[0].Meta.Created, Updated: result.Result.Elements[0].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -665,15 +666,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[0].Meta.Created, Updated: result.Result.Elements[0].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -700,15 +701,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[1].Meta.Created, Updated: result.Result.Elements[1].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -765,15 +766,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[0].Meta.Created, Updated: result.Result.Elements[0].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -830,15 +831,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[0].Meta.Created, Updated: result.Result.Elements[0].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -896,15 +897,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[0].Meta.Created, Updated: result.Result.Elements[0].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -971,15 +972,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[0].Meta.Created, Updated: result.Result.Elements[0].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -1044,15 +1045,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[0].Meta.Created, Updated: result.Result.Elements[0].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -1079,15 +1080,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[1].Meta.Created, Updated: result.Result.Elements[1].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -1146,15 +1147,15 @@ func TestGetAllLibraryElements(t *testing.T) { ConnectedDashboards: 0, Created: result.Result.Elements[0].Meta.Created, Updated: result.Result.Elements[0].Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, diff --git a/pkg/services/libraryelements/libraryelements_get_test.go b/pkg/services/libraryelements/libraryelements_get_test.go index ff587a20d85..ce6d6aecc73 100644 --- a/pkg/services/libraryelements/libraryelements_get_test.go +++ b/pkg/services/libraryelements/libraryelements_get_test.go @@ -5,6 +5,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/grafana/grafana/pkg/components/simplejson" + "github.com/grafana/grafana/pkg/kinds/librarypanel" "github.com/grafana/grafana/pkg/services/dashboards" "github.com/grafana/grafana/pkg/services/org" "github.com/grafana/grafana/pkg/web" @@ -54,15 +55,15 @@ func TestGetLibraryElement(t *testing.T) { ConnectedDashboards: 0, Created: res.Result.Meta.Created, Updated: res.Result.Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, @@ -149,15 +150,15 @@ func TestGetLibraryElement(t *testing.T) { ConnectedDashboards: 1, Created: res.Result.Meta.Created, Updated: res.Result.Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, diff --git a/pkg/services/libraryelements/libraryelements_patch_test.go b/pkg/services/libraryelements/libraryelements_patch_test.go index 51d1f06e822..83e3bd25c22 100644 --- a/pkg/services/libraryelements/libraryelements_patch_test.go +++ b/pkg/services/libraryelements/libraryelements_patch_test.go @@ -3,6 +3,7 @@ package libraryelements import ( "testing" + "github.com/grafana/grafana/pkg/kinds/librarypanel" "github.com/grafana/grafana/pkg/util" "github.com/google/go-cmp/cmp" @@ -68,15 +69,15 @@ func TestPatchLibraryElement(t *testing.T) { ConnectedDashboards: 0, Created: sc.initialResult.Result.Meta.Created, Updated: result.Result.Meta.Updated, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: "signed_in_user", - AvatarURL: "/avatar/37524e1eb8b3e32850b57db0a19af93b", + AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b", }, }, }, @@ -101,7 +102,7 @@ func TestPatchLibraryElement(t *testing.T) { var result = validateAndUnMarshalResponse(t, resp) sc.initialResult.Result.FolderID = newFolder.ID sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName - sc.initialResult.Result.Meta.CreatedBy.AvatarURL = userInDbAvatar + sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = userInDbAvatar sc.initialResult.Result.Meta.Updated = result.Result.Meta.Updated sc.initialResult.Result.Version = 2 sc.initialResult.Result.Meta.FolderName = "NewFolder" @@ -125,7 +126,7 @@ func TestPatchLibraryElement(t *testing.T) { var result = validateAndUnMarshalResponse(t, resp) sc.initialResult.Result.Name = "New Name" sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName - sc.initialResult.Result.Meta.CreatedBy.AvatarURL = userInDbAvatar + sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = userInDbAvatar sc.initialResult.Result.Meta.Updated = result.Result.Meta.Updated sc.initialResult.Result.Model["title"] = "Text - Library Panel" sc.initialResult.Result.Version = 2 @@ -148,7 +149,7 @@ func TestPatchLibraryElement(t *testing.T) { var result = validateAndUnMarshalResponse(t, resp) sc.initialResult.Result.UID = cmd.UID sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName - sc.initialResult.Result.Meta.CreatedBy.AvatarURL = userInDbAvatar + sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = userInDbAvatar sc.initialResult.Result.Meta.Updated = result.Result.Meta.Updated sc.initialResult.Result.Model["title"] = "Text - Library Panel" sc.initialResult.Result.Version = 2 @@ -225,7 +226,7 @@ func TestPatchLibraryElement(t *testing.T) { "description": "New description", } sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName - sc.initialResult.Result.Meta.CreatedBy.AvatarURL = userInDbAvatar + sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = userInDbAvatar sc.initialResult.Result.Meta.Updated = result.Result.Meta.Updated sc.initialResult.Result.Version = 2 if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" { @@ -252,7 +253,7 @@ func TestPatchLibraryElement(t *testing.T) { "description": "New description", } sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName - sc.initialResult.Result.Meta.CreatedBy.AvatarURL = userInDbAvatar + sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = userInDbAvatar sc.initialResult.Result.Meta.Updated = result.Result.Meta.Updated sc.initialResult.Result.Version = 2 if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" { @@ -279,7 +280,7 @@ func TestPatchLibraryElement(t *testing.T) { "description": "A description", } sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName - sc.initialResult.Result.Meta.CreatedBy.AvatarURL = userInDbAvatar + sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = userInDbAvatar sc.initialResult.Result.Meta.Updated = result.Result.Meta.Updated sc.initialResult.Result.Version = 2 if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" { @@ -295,9 +296,9 @@ func TestPatchLibraryElement(t *testing.T) { sc.ctx.Req.Body = mockRequestBody(cmd) resp := sc.service.patchHandler(sc.reqContext) var result = validateAndUnMarshalResponse(t, resp) - sc.initialResult.Result.Meta.UpdatedBy.ID = int64(2) + sc.initialResult.Result.Meta.UpdatedBy.Id = int64(2) sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName - sc.initialResult.Result.Meta.CreatedBy.AvatarURL = userInDbAvatar + sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = userInDbAvatar sc.initialResult.Result.Meta.Updated = result.Result.Meta.Updated sc.initialResult.Result.Version = 2 if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" { @@ -393,7 +394,7 @@ func TestPatchLibraryElement(t *testing.T) { "description": "A description", } sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName - sc.initialResult.Result.Meta.CreatedBy.AvatarURL = userInDbAvatar + sc.initialResult.Result.Meta.CreatedBy.AvatarUrl = userInDbAvatar sc.initialResult.Result.Meta.Updated = result.Result.Meta.Updated sc.initialResult.Result.Version = 2 if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" { diff --git a/pkg/services/libraryelements/libraryelements_permissions_test.go b/pkg/services/libraryelements/libraryelements_permissions_test.go index 3e3c1b4e6dc..b7078f7a5d6 100644 --- a/pkg/services/libraryelements/libraryelements_permissions_test.go +++ b/pkg/services/libraryelements/libraryelements_permissions_test.go @@ -252,9 +252,9 @@ func TestLibraryElementPermissions(t *testing.T) { resp := sc.service.createHandler(sc.reqContext) result := validateAndUnMarshalResponse(t, resp) result.Result.Meta.CreatedBy.Name = userInDbName - result.Result.Meta.CreatedBy.AvatarURL = userInDbAvatar + result.Result.Meta.CreatedBy.AvatarUrl = userInDbAvatar result.Result.Meta.UpdatedBy.Name = userInDbName - result.Result.Meta.UpdatedBy.AvatarURL = userInDbAvatar + result.Result.Meta.UpdatedBy.AvatarUrl = userInDbAvatar result.Result.Meta.FolderName = folder.Title result.Result.Meta.FolderUID = folder.UID results = append(results, result.Result) @@ -275,9 +275,9 @@ func TestLibraryElementPermissions(t *testing.T) { resp := sc.service.createHandler(sc.reqContext) result := validateAndUnMarshalResponse(t, resp) result.Result.Meta.CreatedBy.Name = userInDbName - result.Result.Meta.CreatedBy.AvatarURL = userInDbAvatar + result.Result.Meta.CreatedBy.AvatarUrl = userInDbAvatar result.Result.Meta.UpdatedBy.Name = userInDbName - result.Result.Meta.UpdatedBy.AvatarURL = userInDbAvatar + result.Result.Meta.UpdatedBy.AvatarUrl = userInDbAvatar result.Result.Meta.FolderName = "General" result.Result.Meta.FolderUID = "" sc.reqContext.SignedInUser.OrgRole = testCase.role @@ -315,9 +315,9 @@ func TestLibraryElementPermissions(t *testing.T) { resp := sc.service.createHandler(sc.reqContext) result := validateAndUnMarshalResponse(t, resp) result.Result.Meta.CreatedBy.Name = userInDbName - result.Result.Meta.CreatedBy.AvatarURL = userInDbAvatar + result.Result.Meta.CreatedBy.AvatarUrl = userInDbAvatar result.Result.Meta.UpdatedBy.Name = userInDbName - result.Result.Meta.UpdatedBy.AvatarURL = userInDbAvatar + result.Result.Meta.UpdatedBy.AvatarUrl = userInDbAvatar result.Result.Meta.FolderName = folder.Title result.Result.Meta.FolderUID = folder.UID results = append(results, result.Result) @@ -367,9 +367,9 @@ func TestLibraryElementPermissions(t *testing.T) { resp := sc.service.createHandler(sc.reqContext) result := validateAndUnMarshalResponse(t, resp) result.Result.Meta.CreatedBy.Name = userInDbName - result.Result.Meta.CreatedBy.AvatarURL = userInDbAvatar + result.Result.Meta.CreatedBy.AvatarUrl = userInDbAvatar result.Result.Meta.UpdatedBy.Name = userInDbName - result.Result.Meta.UpdatedBy.AvatarURL = userInDbAvatar + result.Result.Meta.UpdatedBy.AvatarUrl = userInDbAvatar result.Result.Meta.FolderName = "General" sc.reqContext.SignedInUser.OrgRole = testCase.role diff --git a/pkg/services/libraryelements/libraryelements_test.go b/pkg/services/libraryelements/libraryelements_test.go index 79171ff888a..68b852bcea5 100644 --- a/pkg/services/libraryelements/libraryelements_test.go +++ b/pkg/services/libraryelements/libraryelements_test.go @@ -19,6 +19,7 @@ import ( "github.com/grafana/grafana/pkg/infra/db" "github.com/grafana/grafana/pkg/infra/db/dbtest" "github.com/grafana/grafana/pkg/infra/tracing" + "github.com/grafana/grafana/pkg/kinds/librarypanel" "github.com/grafana/grafana/pkg/models" acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" "github.com/grafana/grafana/pkg/services/alerting" @@ -165,10 +166,10 @@ func TestGetLibraryPanelConnections(t *testing.T) { ConnectionID: dashInDB.ID, ConnectionUID: dashInDB.UID, Created: res.Result[0].Created, - CreatedBy: LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, }, diff --git a/pkg/services/libraryelements/models.go b/pkg/services/libraryelements/models.go index 54af6dbd9a0..3fd5d1db981 100644 --- a/pkg/services/libraryelements/models.go +++ b/pkg/services/libraryelements/models.go @@ -4,6 +4,8 @@ import ( "encoding/json" "errors" "time" + + "github.com/grafana/grafana/pkg/kinds/librarypanel" ) type LibraryConnectionKind int @@ -93,15 +95,8 @@ type LibraryElementDTOMeta struct { Created time.Time `json:"created"` Updated time.Time `json:"updated"` - CreatedBy LibraryElementDTOMetaUser `json:"createdBy"` - UpdatedBy LibraryElementDTOMetaUser `json:"updatedBy"` -} - -// LibraryElementDTOMetaUser is the meta information for user that creates/changes the library element. -type LibraryElementDTOMetaUser struct { - ID int64 `json:"id"` - Name string `json:"name"` - AvatarURL string `json:"avatarUrl"` + CreatedBy librarypanel.LibraryElementDTOMetaUser `json:"createdBy"` + UpdatedBy librarypanel.LibraryElementDTOMetaUser `json:"updatedBy"` } // libraryElementConnection is the model for library element connections. @@ -129,13 +124,13 @@ type libraryElementConnectionWithMeta struct { // LibraryElementConnectionDTO is the frontend DTO for element connections. type LibraryElementConnectionDTO struct { - ID int64 `json:"id"` - Kind int64 `json:"kind"` - ElementID int64 `json:"elementId"` - ConnectionID int64 `json:"connectionId"` - ConnectionUID string `json:"connectionUid"` - Created time.Time `json:"created"` - CreatedBy LibraryElementDTOMetaUser `json:"createdBy"` + ID int64 `json:"id"` + Kind int64 `json:"kind"` + ElementID int64 `json:"elementId"` + ConnectionID int64 `json:"connectionId"` + ConnectionUID string `json:"connectionUid"` + Created time.Time `json:"created"` + CreatedBy librarypanel.LibraryElementDTOMetaUser `json:"createdBy"` } var ( diff --git a/pkg/services/librarypanels/librarypanels_test.go b/pkg/services/librarypanels/librarypanels_test.go index c0ae1ba624c..85929ee8282 100644 --- a/pkg/services/librarypanels/librarypanels_test.go +++ b/pkg/services/librarypanels/librarypanels_test.go @@ -18,6 +18,7 @@ import ( "github.com/grafana/grafana/pkg/infra/db/dbtest" "github.com/grafana/grafana/pkg/infra/slugify" "github.com/grafana/grafana/pkg/infra/tracing" + "github.com/grafana/grafana/pkg/kinds/librarypanel" "github.com/grafana/grafana/pkg/models" acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" "github.com/grafana/grafana/pkg/services/alerting" @@ -634,15 +635,15 @@ func toLibraryElement(t *testing.T, res libraryelements.LibraryElementDTO) libra ConnectedDashboards: res.Meta.ConnectedDashboards, Created: res.Meta.Created, Updated: res.Meta.Updated, - CreatedBy: libraryelements.LibraryElementDTOMetaUser{ - ID: res.Meta.CreatedBy.ID, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: res.Meta.CreatedBy.Id, Name: res.Meta.CreatedBy.Name, - AvatarURL: res.Meta.CreatedBy.AvatarURL, + AvatarUrl: res.Meta.CreatedBy.AvatarUrl, }, - UpdatedBy: libraryelements.LibraryElementDTOMetaUser{ - ID: res.Meta.UpdatedBy.ID, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: res.Meta.UpdatedBy.Id, Name: res.Meta.UpdatedBy.Name, - AvatarURL: res.Meta.UpdatedBy.AvatarURL, + AvatarUrl: res.Meta.UpdatedBy.AvatarUrl, }, }, } @@ -672,15 +673,15 @@ func getExpected(t *testing.T, res libraryelements.LibraryElementDTO, UID string ConnectedDashboards: 0, Created: res.Meta.Created, Updated: res.Meta.Updated, - CreatedBy: libraryelements.LibraryElementDTOMetaUser{ - ID: 1, + CreatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, - UpdatedBy: libraryelements.LibraryElementDTOMetaUser{ - ID: 1, + UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ + Id: 1, Name: userInDbName, - AvatarURL: userInDbAvatar, + AvatarUrl: userInDbAvatar, }, }, } diff --git a/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.tsx b/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.tsx index cf158139c4f..b88b3d683a6 100644 --- a/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.tsx +++ b/public/app/features/dashboard/components/AddPanelWidget/AddPanelWidget.tsx @@ -113,7 +113,7 @@ export const AddPanelWidgetUnconnected = ({ panel, dashboard }: Props) => { const onAddLibraryPanel = (panelInfo: LibraryElementDTO) => { const { gridPos } = panel; - const newPanel: PanelModel = { + const newPanel = { ...panelInfo.model, gridPos, libraryPanel: panelInfo, diff --git a/public/app/features/dashboard/components/DashExportModal/DashboardExporter.ts b/public/app/features/dashboard/components/DashExportModal/DashboardExporter.ts index 86596469639..2fd1e04f537 100644 --- a/public/app/features/dashboard/components/DashExportModal/DashboardExporter.ts +++ b/public/app/features/dashboard/components/DashExportModal/DashboardExporter.ts @@ -177,7 +177,7 @@ export class DashboardExporter { model = libPanel.model; } - const { gridPos, id, ...rest } = model; + const { gridPos, id, ...rest } = model as any; if (!libraryPanels.has(uid)) { libraryPanels.set(uid, { name, uid, kind: LibraryElementKind.Panel, model: rest }); } diff --git a/public/app/features/dashboard/state/PanelModel.ts b/public/app/features/dashboard/state/PanelModel.ts index 6a1645da5fd..d55fba4feaf 100644 --- a/public/app/features/dashboard/state/PanelModel.ts +++ b/public/app/features/dashboard/state/PanelModel.ts @@ -23,6 +23,7 @@ import { restoreCustomOverrideRules, } from '@grafana/data'; import { getTemplateSrv, RefreshEvent } from '@grafana/runtime'; +import { LibraryPanel, LibraryPanelRef } from '@grafana/schema'; import config from 'app/core/config'; import { safeStringifyValue } from 'app/core/utils/explore'; import { getNextRefIdChar } from 'app/core/utils/query'; @@ -35,7 +36,6 @@ import { RenderEvent, } from 'app/types/events'; -import { LibraryElementDTO, LibraryPanelRef } from '../../library-panels/types'; import { PanelQueryRunner } from '../../query/state/PanelQueryRunner'; import { getVariablesUrlParams } from '../../variables/getAllVariableValuesForUrl'; import { getTimeSrv } from '../services/TimeSrv'; @@ -172,7 +172,7 @@ export class PanelModel implements DataConfigSource, IPanelModel { links?: DataLink[]; declare transparent: boolean; - libraryPanel?: LibraryPanelRef | LibraryElementDTO; + libraryPanel?: LibraryPanelRef | LibraryPanel; autoMigrateFrom?: string; @@ -680,7 +680,7 @@ export class PanelModel implements DataConfigSource, IPanelModel { return this.replaceVariables(this.title, undefined, 'text'); } - initLibraryPanel(libPanel: LibraryElementDTO) { + initLibraryPanel(libPanel: LibraryPanel) { for (const [key, val] of Object.entries(libPanel.model)) { switch (key) { case 'id': diff --git a/public/app/features/library-panels/components/LibraryPanelCard/LibraryPanelCard.tsx b/public/app/features/library-panels/components/LibraryPanelCard/LibraryPanelCard.tsx index 1717ab7c313..e3921fddb70 100644 --- a/public/app/features/library-panels/components/LibraryPanelCard/LibraryPanelCard.tsx +++ b/public/app/features/library-panels/components/LibraryPanelCard/LibraryPanelCard.tsx @@ -62,7 +62,7 @@ interface FolderLinkProps { function FolderLink({ libraryPanel }: FolderLinkProps): ReactElement | null { const styles = useStyles2(getStyles); - if (!libraryPanel.meta.folderUid && !libraryPanel.meta.folderName) { + if (!libraryPanel.meta?.folderUid && !libraryPanel.meta?.folderName) { return null; } diff --git a/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.test.tsx b/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.test.tsx index 726957acb8c..3b9df62c30c 100644 --- a/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.test.tsx +++ b/public/app/features/library-panels/components/LibraryPanelsSearch/LibraryPanelsSearch.test.tsx @@ -4,11 +4,12 @@ import userEvent from '@testing-library/user-event'; import React from 'react'; import { PanelPluginMeta, PluginType } from '@grafana/data'; +import { Panel } from '@grafana/schema'; import { backendSrv } from '../../../../core/services/backend_srv'; import * as panelUtils from '../../../panel/state/util'; import * as api from '../../state/api'; -import { LibraryElementKind, LibraryElementsSearchResult } from '../../types'; +import { LibraryElementsSearchResult } from '../../types'; import { LibraryPanelsSearch, LibraryPanelsSearchProps } from './LibraryPanelsSearch'; @@ -182,15 +183,12 @@ describe('LibraryPanelsSearch', () => { { elements: [ { - id: 1, name: 'Library Panel Name', - kind: LibraryElementKind.Panel, uid: 'uid', description: 'Library Panel Description', folderUid: '', - model: { type: 'timeseries', title: 'A title' }, + model: { type: 'timeseries', title: 'A title' } as Panel, type: 'timeseries', - orgId: 1, version: 1, meta: { folderName: 'General', @@ -237,15 +235,12 @@ describe('LibraryPanelsSearch', () => { perPage: 40, elements: [ { - id: 1, name: 'Library Panel Name', - kind: LibraryElementKind.Panel, uid: 'uid', description: 'Library Panel Description', folderUid: '', - model: { type: 'timeseries', title: 'A title' }, + model: { type: 'timeseries', title: 'A title' } as Panel, type: 'timeseries', - orgId: 1, version: 1, meta: { folderName: 'General', @@ -281,15 +276,12 @@ describe('LibraryPanelsSearch', () => { perPage: 40, elements: [ { - id: 1, name: 'Library Panel Name', - kind: LibraryElementKind.Panel, uid: 'uid', description: 'Library Panel Description', folderUid: '', - model: { type: 'timeseries', title: 'A title' }, + model: { type: 'timeseries', title: 'A title' } as Panel, type: 'timeseries', - orgId: 1, version: 1, meta: { folderName: 'General', diff --git a/public/app/features/library-panels/components/LibraryPanelsView/reducer.test.ts b/public/app/features/library-panels/components/LibraryPanelsView/reducer.test.ts index 527d345534b..ec96cc842d2 100644 --- a/public/app/features/library-panels/components/LibraryPanelsView/reducer.test.ts +++ b/public/app/features/library-panels/components/LibraryPanelsView/reducer.test.ts @@ -1,7 +1,8 @@ import { LoadingState } from '@grafana/data'; +import { Panel } from '@grafana/schema'; import { reducerTester } from '../../../../../test/core/redux/reducerTester'; -import { LibraryElementDTO, LibraryElementKind } from '../../types'; +import { LibraryElementDTO } from '../../types'; import { changePage, @@ -93,7 +94,6 @@ function getLibraryPanelMocks(count: number): LibraryElementDTO[] { mocks.push( mockLibraryPanel({ uid: i.toString(10), - id: i, name: `Test Panel ${i}`, }) ); @@ -104,11 +104,9 @@ function getLibraryPanelMocks(count: number): LibraryElementDTO[] { function mockLibraryPanel({ uid = '1', - id = 1, - orgId = 1, folderUid = '', name = 'Test Panel', - model = { type: 'text', title: 'Test Panel' }, + model = { type: 'text', title: 'Test Panel' } as Panel, meta = { folderName: 'General', folderUid: '', @@ -124,11 +122,8 @@ function mockLibraryPanel({ }: Partial = {}): LibraryElementDTO { return { uid, - id, - orgId, folderUid, name, - kind: LibraryElementKind.Panel, model, version, meta, diff --git a/public/app/features/library-panels/components/SaveLibraryPanelModal/SaveLibraryPanelModal.tsx b/public/app/features/library-panels/components/SaveLibraryPanelModal/SaveLibraryPanelModal.tsx index e3b551d302a..6956b60a2d9 100644 --- a/public/app/features/library-panels/components/SaveLibraryPanelModal/SaveLibraryPanelModal.tsx +++ b/public/app/features/library-panels/components/SaveLibraryPanelModal/SaveLibraryPanelModal.tsx @@ -64,8 +64,8 @@ export const SaveLibraryPanelModal = ({

{'This update will affect '} - {panel.libraryPanel.meta.connectedDashboards}{' '} - {panel.libraryPanel.meta.connectedDashboards === 1 ? 'dashboard' : 'dashboards'}. + {panel.libraryPanel.meta?.connectedDashboards}{' '} + {panel.libraryPanel.meta?.connectedDashboards === 1 ? 'dashboard' : 'dashboards'}. The following dashboards using the panel will be affected:

diff --git a/public/app/features/library-panels/types.ts b/public/app/features/library-panels/types.ts index d4d1cd4c085..0d4356ff7ba 100644 --- a/public/app/features/library-panels/types.ts +++ b/public/app/features/library-panels/types.ts @@ -1,17 +1,22 @@ import { AnyAction } from '@reduxjs/toolkit'; import { Dispatch } from 'react'; +import { LibraryPanel } from '@grafana/schema'; +import { LibraryElementDTOMetaUser } from '@grafana/schema/src/raw/librarypanel/x/librarypanel_types.gen'; + import { PanelModel } from '../dashboard/state'; export enum LibraryElementKind { Panel = 1, - Variable, } export enum LibraryElementConnectionKind { Dashboard = 1, } +/** @deprecated use LibraryPanel */ +export interface LibraryElementDTO extends LibraryPanel {} + export interface LibraryElementConnectionDTO { id: number; kind: LibraryElementConnectionKind; @@ -24,48 +29,13 @@ export interface LibraryElementConnectionDTO { export interface LibraryElementsSearchResult { totalCount: number; - elements: LibraryElementDTO[]; + elements: LibraryPanel[]; perPage: number; page: number; } -export interface LibraryElementDTO { - id: number; - orgId: number; - folderUid: string; - uid: string; - name: string; - kind: LibraryElementKind; - type: string; - description: string; - model: any; - version: number; - meta: LibraryElementDTOMeta; -} - -export interface LibraryElementDTOMeta { - folderName: string; - folderUid: string; - connectedDashboards: number; - created: string; - updated: string; - createdBy: LibraryElementDTOMetaUser; - updatedBy: LibraryElementDTOMetaUser; -} - -export interface LibraryElementDTOMetaUser { - id: number; - name: string; - avatarUrl: string; -} - -export interface LibraryPanelRef { - name: string; - uid: string; -} - export interface PanelModelWithLibraryPanel extends PanelModel { - libraryPanel: LibraryElementDTO; + libraryPanel: LibraryPanel; } export type DispatchResult = (dispatch: Dispatch) => void; diff --git a/public/app/features/manage-dashboards/components/ImportDashboardLibraryPanelsList.tsx b/public/app/features/manage-dashboards/components/ImportDashboardLibraryPanelsList.tsx index cb3b47b7b71..3228e8107ff 100644 --- a/public/app/features/manage-dashboards/components/ImportDashboardLibraryPanelsList.tsx +++ b/public/app/features/manage-dashboards/components/ImportDashboardLibraryPanelsList.tsx @@ -2,6 +2,7 @@ import { css } from '@emotion/css'; import React, { ReactElement } from 'react'; import { GrafanaTheme2 } from '@grafana/data'; +import { LibraryPanel } from '@grafana/schema'; import { Field, useStyles2 } from '@grafana/ui'; import { LibraryPanelCard } from '../../library-panels/components/LibraryPanelCard/LibraryPanelCard'; @@ -36,9 +37,10 @@ export function ImportDashboardLibraryPanelsList({ input.state === LibraryPanelInputState.New ? { ...input.model, meta: { ...input.model.meta, folderName: folderName ?? 'General' } } : { ...input.model }; + return (
- undefined} /> + undefined} />
); })} diff --git a/public/app/features/manage-dashboards/state/actions.ts b/public/app/features/manage-dashboards/state/actions.ts index 0969bad4959..1579cd6306b 100644 --- a/public/app/features/manage-dashboards/state/actions.ts +++ b/public/app/features/manage-dashboards/state/actions.ts @@ -101,8 +101,6 @@ function processElements(dashboardJson?: { __elements?: Record