mirror of https://github.com/grafana/grafana.git
				
				
				
			Schema: Add schema for library panels (#62169)
This commit is contained in:
		
							parent
							
								
									13159d03ba
								
							
						
					
					
						commit
						0d2a786816
					
				|  | @ -3106,8 +3106,10 @@ exports[`better eslint`] = { | ||||||
|       [0, 0, 0, "Do not use any type assertions.", "6"], |       [0, 0, 0, "Do not use any type assertions.", "6"], | ||||||
|       [0, 0, 0, "Unexpected any. Specify a different type.", "7"], |       [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.", "8"], | ||||||
|       [0, 0, 0, "Do not use any type assertions.", "9"], |       [0, 0, 0, "Unexpected any. Specify a different type.", "9"], | ||||||
|       [0, 0, 0, "Unexpected any. Specify a different type.", "10"] |       [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": [ |     "public/app/features/dashboard/components/DashboardPrompt/DashboardPrompt.test.tsx:5381": [ | ||||||
|       [0, 0, 0, "Unexpected any. Specify a different type.", "0"], |       [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": [ |     "public/app/features/library-panels/components/LibraryPanelsView/actions.ts:5381": [ | ||||||
|       [0, 0, 0, "Unexpected any. Specify a different type.", "0"] |       [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": [ |     "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.", "0"], | ||||||
|       [0, 0, 0, "Unexpected any. Specify a different type.", "1"] |       [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, "Do not use any type assertions.", "4"], | ||||||
|       [0, 0, 0, "Unexpected any. Specify a different type.", "5"] |       [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": [ |     "public/app/features/manage-dashboards/components/SnapshotListTable.test.tsx:5381": [ | ||||||
|       [0, 0, 0, "Unexpected any. Specify a different type.", "0"] |       [0, 0, 0, "Unexpected any. Specify a different type.", "0"] | ||||||
|     ], |     ], | ||||||
|  |  | ||||||
|  | @ -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<br/>Typescript: Omit<Panel, 'gridPos' | 'id' | 'libraryPanel'>; | | ||||||
|  | | `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<Panel, 'gridPos' | 'id' | 'libraryPanel'>; | ||||||
|  | 
 | ||||||
|  | | Property | Type | Required | Description | | ||||||
|  | |----------|------|----------|-------------| | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @ -397,6 +397,9 @@ lineage: seqs: [ | ||||||
| 					// TODO tighter constraint | 					// TODO tighter constraint | ||||||
| 					timeShift?: string @grafanamaturity(NeedsExpertReview) | 					timeShift?: string @grafanamaturity(NeedsExpertReview) | ||||||
| 
 | 
 | ||||||
|  | 					// Dynamically load the panel | ||||||
|  | 					libraryPanel?: #LibraryPanelRef | ||||||
|  | 
 | ||||||
| 					// options is specified by the PanelOptions field in panel | 					// options is specified by the PanelOptions field in panel | ||||||
| 					// plugin schemas. | 					// plugin schemas. | ||||||
| 					options: {...} @grafanamaturity(NeedsExpertReview) | 					options: {...} @grafanamaturity(NeedsExpertReview) | ||||||
|  | @ -412,6 +415,11 @@ lineage: seqs: [ | ||||||
| 					}] @grafanamaturity(NeedsExpertReview) | 					}] @grafanamaturity(NeedsExpertReview) | ||||||
| 				} @cuetsy(kind="interface") @grafana(TSVeneer="type") @grafanamaturity(NeedsExpertReview) | 				} @cuetsy(kind="interface") @grafana(TSVeneer="type") @grafanamaturity(NeedsExpertReview) | ||||||
| 
 | 
 | ||||||
|  | 				#LibraryPanelRef: { | ||||||
|  | 					name: string | ||||||
|  | 					uid:  string | ||||||
|  | 				} @cuetsy(kind="interface") | ||||||
|  | 
 | ||||||
| 				#MatcherConfig: { | 				#MatcherConfig: { | ||||||
| 					id:       string | *"" @grafanamaturity(NeedsExpertReview)
 | 					id:       string | *"" @grafanamaturity(NeedsExpertReview)
 | ||||||
| 					options?: _            @grafanamaturity(NeedsExpertReview) | 					options?: _            @grafanamaturity(NeedsExpertReview) | ||||||
|  |  | ||||||
|  | @ -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<Panel, 'gridPos' | 'id' | 'libraryPanel'>; | ||||||
|  | 				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) | ||||||
|  | 			}, | ||||||
|  | 		] | ||||||
|  | 	}, | ||||||
|  | ] | ||||||
|  | @ -26,6 +26,7 @@ export type { | ||||||
|   SpecialValueMap, |   SpecialValueMap, | ||||||
|   ValueMappingResult, |   ValueMappingResult, | ||||||
|   Transformation, |   Transformation, | ||||||
|  |   LibraryPanelRef, | ||||||
|   RowPanel, |   RowPanel, | ||||||
|   GraphPanel, |   GraphPanel, | ||||||
|   HeatmapPanel |   HeatmapPanel | ||||||
|  | @ -86,6 +87,23 @@ export { | ||||||
|   defaultFieldConfig |   defaultFieldConfig | ||||||
| } from './veneer/dashboard.types'; | } 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.
 | // Raw generated types from Playlist kind.
 | ||||||
| export type { | export type { | ||||||
|   Playlist, |   Playlist, | ||||||
|  |  | ||||||
|  | @ -404,6 +404,10 @@ export interface Panel { | ||||||
|    * TODO tighter constraint |    * TODO tighter constraint | ||||||
|    */ |    */ | ||||||
|   interval?: string; |   interval?: string; | ||||||
|  |   /** | ||||||
|  |    * Dynamically load the panel | ||||||
|  |    */ | ||||||
|  |   libraryPanel?: LibraryPanelRef; | ||||||
|   /** |   /** | ||||||
|    * Panel links. |    * Panel links. | ||||||
|    * TODO fill this out - seems there are a couple variants? |    * TODO fill this out - seems there are a couple variants? | ||||||
|  | @ -503,6 +507,11 @@ export const defaultFieldConfigSource: Partial<FieldConfigSource> = { | ||||||
|   overrides: [], |   overrides: [], | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | export interface LibraryPanelRef { | ||||||
|  |   name: string; | ||||||
|  |   uid: string; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| export interface MatcherConfig { | export interface MatcherConfig { | ||||||
|   id: string; |   id: string; | ||||||
|   options?: unknown; |   options?: unknown; | ||||||
|  |  | ||||||
|  | @ -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<Panel, 'gridPos' | 'id' | 'libraryPanel'>; | ||||||
|  |    */ | ||||||
|  |   model: Record<string, unknown>; | ||||||
|  |   /** | ||||||
|  |    * 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; | ||||||
|  | } | ||||||
|  | @ -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<Panel, 'gridPos' | 'id' | 'libraryPanel'>; | ||||||
|  | } | ||||||
|  | @ -458,6 +458,12 @@ type HeatmapPanel struct { | ||||||
| // HeatmapPanelType defines model for HeatmapPanel.Type.
 | // HeatmapPanelType defines model for HeatmapPanel.Type.
 | ||||||
| type HeatmapPanelType string | type HeatmapPanelType string | ||||||
| 
 | 
 | ||||||
|  | // LibraryPanelRef defines model for LibraryPanelRef.
 | ||||||
|  | type LibraryPanelRef struct { | ||||||
|  | 	Name string `json:"name"` | ||||||
|  | 	Uid  string `json:"uid"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // LoadingState defines model for LoadingState.
 | // LoadingState defines model for LoadingState.
 | ||||||
| type LoadingState string | type LoadingState string | ||||||
| 
 | 
 | ||||||
|  | @ -490,7 +496,8 @@ type Panel struct { | ||||||
| 
 | 
 | ||||||
| 	// TODO docs
 | 	// TODO docs
 | ||||||
| 	// TODO tighter constraint
 | 	// TODO tighter constraint
 | ||||||
| 	Interval *string `json:"interval,omitempty"` | 	Interval     *string          `json:"interval,omitempty"` | ||||||
|  | 	LibraryPanel *LibraryPanelRef `json:"libraryPanel,omitempty"` | ||||||
| 
 | 
 | ||||||
| 	// Panel links.
 | 	// Panel links.
 | ||||||
| 	// TODO fill this out - seems there are a couple variants?
 | 	// TODO fill this out - seems there are a couple variants?
 | ||||||
|  |  | ||||||
|  | @ -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 | ||||||
|  | } | ||||||
|  | @ -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<Panel, 'gridPos' | 'id' | 'libraryPanel'>;
 | ||||||
|  | 	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"` | ||||||
|  | } | ||||||
|  | @ -807,6 +807,32 @@ | ||||||
|       "pluralName": "JaegerDataSourceCfgs", |       "pluralName": "JaegerDataSourceCfgs", | ||||||
|       "schemaInterface": "DataSourceCfg" |       "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": { |     "livepanelcfg": { | ||||||
|       "category": "composable", |       "category": "composable", | ||||||
|       "codeowners": [], |       "codeowners": [], | ||||||
|  | @ -1846,6 +1872,7 @@ | ||||||
|           "dashboard", |           "dashboard", | ||||||
|           "datasource", |           "datasource", | ||||||
|           "folder", |           "folder", | ||||||
|  |           "librarypanel", | ||||||
|           "playlist", |           "playlist", | ||||||
|           "preferences", |           "preferences", | ||||||
|           "publicdashboard", |           "publicdashboard", | ||||||
|  | @ -1856,7 +1883,7 @@ | ||||||
|           "thumb", |           "thumb", | ||||||
|           "user" |           "user" | ||||||
|         ], |         ], | ||||||
|         "count": 13 |         "count": 14 | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     "maturity": { |     "maturity": { | ||||||
|  | @ -1870,6 +1897,7 @@ | ||||||
|           "dashboardlistpanelcfg", |           "dashboardlistpanelcfg", | ||||||
|           "gaugepanelcfg", |           "gaugepanelcfg", | ||||||
|           "histogrampanelcfg", |           "histogrampanelcfg", | ||||||
|  |           "librarypanel", | ||||||
|           "newspanelcfg", |           "newspanelcfg", | ||||||
|           "nodegraphpanelcfg", |           "nodegraphpanelcfg", | ||||||
|           "piechartpanelcfg", |           "piechartpanelcfg", | ||||||
|  | @ -1880,7 +1908,7 @@ | ||||||
|           "textpanelcfg", |           "textpanelcfg", | ||||||
|           "xychartpanelcfg" |           "xychartpanelcfg" | ||||||
|         ], |         ], | ||||||
|         "count": 16 |         "count": 17 | ||||||
|       }, |       }, | ||||||
|       "mature": { |       "mature": { | ||||||
|         "name": "mature", |         "name": "mature", | ||||||
|  |  | ||||||
|  | @ -13,6 +13,7 @@ import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 
 | 
 | ||||||
| 	"github.com/grafana/grafana/pkg/kinds/dashboard" | 	"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/playlist" | ||||||
| 	"github.com/grafana/grafana/pkg/kinds/preferences" | 	"github.com/grafana/grafana/pkg/kinds/preferences" | ||||||
| 	"github.com/grafana/grafana/pkg/kinds/publicdashboard" | 	"github.com/grafana/grafana/pkg/kinds/publicdashboard" | ||||||
|  | @ -35,6 +36,7 @@ import ( | ||||||
| type Base struct { | type Base struct { | ||||||
| 	all             []kindsys.Core | 	all             []kindsys.Core | ||||||
| 	dashboard       *dashboard.Kind | 	dashboard       *dashboard.Kind | ||||||
|  | 	librarypanel    *librarypanel.Kind | ||||||
| 	playlist        *playlist.Kind | 	playlist        *playlist.Kind | ||||||
| 	preferences     *preferences.Kind | 	preferences     *preferences.Kind | ||||||
| 	publicdashboard *publicdashboard.Kind | 	publicdashboard *publicdashboard.Kind | ||||||
|  | @ -45,6 +47,7 @@ type Base struct { | ||||||
| // type guards
 | // type guards
 | ||||||
| var ( | var ( | ||||||
| 	_ kindsys.Core = &dashboard.Kind{} | 	_ kindsys.Core = &dashboard.Kind{} | ||||||
|  | 	_ kindsys.Core = &librarypanel.Kind{} | ||||||
| 	_ kindsys.Core = &playlist.Kind{} | 	_ kindsys.Core = &playlist.Kind{} | ||||||
| 	_ kindsys.Core = &preferences.Kind{} | 	_ kindsys.Core = &preferences.Kind{} | ||||||
| 	_ kindsys.Core = &publicdashboard.Kind{} | 	_ kindsys.Core = &publicdashboard.Kind{} | ||||||
|  | @ -57,6 +60,11 @@ func (b *Base) Dashboard() *dashboard.Kind { | ||||||
| 	return b.dashboard | 	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.
 | // Playlist returns the [kindsys.Interface] implementation for the playlist kind.
 | ||||||
| func (b *Base) Playlist() *playlist.Kind { | func (b *Base) Playlist() *playlist.Kind { | ||||||
| 	return b.playlist | 	return b.playlist | ||||||
|  | @ -92,6 +100,12 @@ func doNewBase(rt *thema.Runtime) *Base { | ||||||
| 	} | 	} | ||||||
| 	reg.all = append(reg.all, reg.dashboard) | 	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) | 	reg.playlist, err = playlist.NewKind(rt) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		panic(fmt.Sprintf("error while initializing the playlist Kind: %s", err)) | 		panic(fmt.Sprintf("error while initializing the playlist Kind: %s", err)) | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"github.com/grafana/grafana/pkg/api/dtos" | 	"github.com/grafana/grafana/pkg/api/dtos" | ||||||
| 	"github.com/grafana/grafana/pkg/infra/db" | 	"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/models" | ||||||
| 	"github.com/grafana/grafana/pkg/services/dashboards" | 	"github.com/grafana/grafana/pkg/services/dashboards" | ||||||
| 	"github.com/grafana/grafana/pkg/services/org" | 	"github.com/grafana/grafana/pkg/services/org" | ||||||
|  | @ -166,15 +167,15 @@ func (l *LibraryElementService) createLibraryElement(c context.Context, signedIn | ||||||
| 			ConnectedDashboards: 0, | 			ConnectedDashboards: 0, | ||||||
| 			Created:             element.Created, | 			Created:             element.Created, | ||||||
| 			Updated:             element.Updated, | 			Updated:             element.Updated, | ||||||
| 			CreatedBy: LibraryElementDTOMetaUser{ | 			CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 				ID:        element.CreatedBy, | 				Id:        element.CreatedBy, | ||||||
| 				Name:      signedInUser.Login, | 				Name:      signedInUser.Login, | ||||||
| 				AvatarURL: dtos.GetGravatarUrl(signedInUser.Email), | 				AvatarUrl: dtos.GetGravatarUrl(signedInUser.Email), | ||||||
| 			}, | 			}, | ||||||
| 			UpdatedBy: LibraryElementDTOMetaUser{ | 			UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 				ID:        element.UpdatedBy, | 				Id:        element.UpdatedBy, | ||||||
| 				Name:      signedInUser.Login, | 				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, | 				ConnectedDashboards: libraryElement.ConnectedDashboards, | ||||||
| 				Created:             libraryElement.Created, | 				Created:             libraryElement.Created, | ||||||
| 				Updated:             libraryElement.Updated, | 				Updated:             libraryElement.Updated, | ||||||
| 				CreatedBy: LibraryElementDTOMetaUser{ | 				CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 					ID:        libraryElement.CreatedBy, | 					Id:        libraryElement.CreatedBy, | ||||||
| 					Name:      libraryElement.CreatedByName, | 					Name:      libraryElement.CreatedByName, | ||||||
| 					AvatarURL: dtos.GetGravatarUrl(libraryElement.CreatedByEmail), | 					AvatarUrl: dtos.GetGravatarUrl(libraryElement.CreatedByEmail), | ||||||
| 				}, | 				}, | ||||||
| 				UpdatedBy: LibraryElementDTOMetaUser{ | 				UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 					ID:        libraryElement.UpdatedBy, | 					Id:        libraryElement.UpdatedBy, | ||||||
| 					Name:      libraryElement.UpdatedByName, | 					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, | 					ConnectedDashboards: element.ConnectedDashboards, | ||||||
| 					Created:             element.Created, | 					Created:             element.Created, | ||||||
| 					Updated:             element.Updated, | 					Updated:             element.Updated, | ||||||
| 					CreatedBy: LibraryElementDTOMetaUser{ | 					CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 						ID:        element.CreatedBy, | 						Id:        element.CreatedBy, | ||||||
| 						Name:      element.CreatedByName, | 						Name:      element.CreatedByName, | ||||||
| 						AvatarURL: dtos.GetGravatarUrl(element.CreatedByEmail), | 						AvatarUrl: dtos.GetGravatarUrl(element.CreatedByEmail), | ||||||
| 					}, | 					}, | ||||||
| 					UpdatedBy: LibraryElementDTOMetaUser{ | 					UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 						ID:        element.UpdatedBy, | 						Id:        element.UpdatedBy, | ||||||
| 						Name:      element.UpdatedByName, | 						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, | 				ConnectedDashboards: elementInDB.ConnectedDashboards, | ||||||
| 				Created:             libraryElement.Created, | 				Created:             libraryElement.Created, | ||||||
| 				Updated:             libraryElement.Updated, | 				Updated:             libraryElement.Updated, | ||||||
| 				CreatedBy: LibraryElementDTOMetaUser{ | 				CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 					ID:        elementInDB.CreatedBy, | 					Id:        elementInDB.CreatedBy, | ||||||
| 					Name:      elementInDB.CreatedByName, | 					Name:      elementInDB.CreatedByName, | ||||||
| 					AvatarURL: dtos.GetGravatarUrl(elementInDB.CreatedByEmail), | 					AvatarUrl: dtos.GetGravatarUrl(elementInDB.CreatedByEmail), | ||||||
| 				}, | 				}, | ||||||
| 				UpdatedBy: LibraryElementDTOMetaUser{ | 				UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 					ID:        libraryElement.UpdatedBy, | 					Id:        libraryElement.UpdatedBy, | ||||||
| 					Name:      signedInUser.Login, | 					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, | 				ConnectionID:  connection.ConnectionID, | ||||||
| 				ConnectionUID: connection.ConnectionUID, | 				ConnectionUID: connection.ConnectionUID, | ||||||
| 				Created:       connection.Created, | 				Created:       connection.Created, | ||||||
| 				CreatedBy: LibraryElementDTOMetaUser{ | 				CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 					ID:        connection.CreatedBy, | 					Id:        connection.CreatedBy, | ||||||
| 					Name:      connection.CreatedByName, | 					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, | 					ConnectedDashboards: element.ConnectedDashboards, | ||||||
| 					Created:             element.Created, | 					Created:             element.Created, | ||||||
| 					Updated:             element.Updated, | 					Updated:             element.Updated, | ||||||
| 					CreatedBy: LibraryElementDTOMetaUser{ | 					CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 						ID:        element.CreatedBy, | 						Id:        element.CreatedBy, | ||||||
| 						Name:      element.CreatedByName, | 						Name:      element.CreatedByName, | ||||||
| 						AvatarURL: dtos.GetGravatarUrl(element.CreatedByEmail), | 						AvatarUrl: dtos.GetGravatarUrl(element.CreatedByEmail), | ||||||
| 					}, | 					}, | ||||||
| 					UpdatedBy: LibraryElementDTOMetaUser{ | 					UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 						ID:        element.UpdatedBy, | 						Id:        element.UpdatedBy, | ||||||
| 						Name:      element.UpdatedByName, | 						Name:      element.UpdatedByName, | ||||||
| 						AvatarURL: dtos.GetGravatarUrl(element.UpdatedByEmail), | 						AvatarUrl: dtos.GetGravatarUrl(element.UpdatedByEmail), | ||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -6,6 +6,7 @@ import ( | ||||||
| 	"github.com/google/go-cmp/cmp" | 	"github.com/google/go-cmp/cmp" | ||||||
| 	"github.com/stretchr/testify/require" | 	"github.com/stretchr/testify/require" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/grafana/grafana/pkg/kinds/librarypanel" | ||||||
| 	"github.com/grafana/grafana/pkg/models" | 	"github.com/grafana/grafana/pkg/models" | ||||||
| 	"github.com/grafana/grafana/pkg/util" | 	"github.com/grafana/grafana/pkg/util" | ||||||
| ) | ) | ||||||
|  | @ -45,15 +46,15 @@ func TestCreateLibraryElement(t *testing.T) { | ||||||
| 						ConnectedDashboards: 0, | 						ConnectedDashboards: 0, | ||||||
| 						Created:             sc.initialResult.Result.Meta.Created, | 						Created:             sc.initialResult.Result.Meta.Created, | ||||||
| 						Updated:             sc.initialResult.Result.Meta.Updated, | 						Updated:             sc.initialResult.Result.Meta.Updated, | ||||||
| 						CreatedBy: LibraryElementDTOMetaUser{ | 						CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 							ID:        1, | 							Id:        1, | ||||||
| 							Name:      "signed_in_user", | 							Name:      "signed_in_user", | ||||||
| 							AvatarURL: "/avatar/37524e1eb8b3e32850b57db0a19af93b", | 							AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b", | ||||||
| 						}, | 						}, | ||||||
| 						UpdatedBy: LibraryElementDTOMetaUser{ | 						UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 							ID:        1, | 							Id:        1, | ||||||
| 							Name:      "signed_in_user", | 							Name:      "signed_in_user", | ||||||
| 							AvatarURL: "/avatar/37524e1eb8b3e32850b57db0a19af93b", | 							AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b", | ||||||
| 						}, | 						}, | ||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
|  | @ -94,15 +95,15 @@ func TestCreateLibraryElement(t *testing.T) { | ||||||
| 						ConnectedDashboards: 0, | 						ConnectedDashboards: 0, | ||||||
| 						Created:             result.Result.Meta.Created, | 						Created:             result.Result.Meta.Created, | ||||||
| 						Updated:             result.Result.Meta.Updated, | 						Updated:             result.Result.Meta.Updated, | ||||||
| 						CreatedBy: LibraryElementDTOMetaUser{ | 						CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 							ID:        1, | 							Id:        1, | ||||||
| 							Name:      "signed_in_user", | 							Name:      "signed_in_user", | ||||||
| 							AvatarURL: "/avatar/37524e1eb8b3e32850b57db0a19af93b", | 							AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b", | ||||||
| 						}, | 						}, | ||||||
| 						UpdatedBy: LibraryElementDTOMetaUser{ | 						UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 							ID:        1, | 							Id:        1, | ||||||
| 							Name:      "signed_in_user", | 							Name:      "signed_in_user", | ||||||
| 							AvatarURL: "/avatar/37524e1eb8b3e32850b57db0a19af93b", | 							AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b", | ||||||
| 						}, | 						}, | ||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
|  | @ -169,15 +170,15 @@ func TestCreateLibraryElement(t *testing.T) { | ||||||
| 						ConnectedDashboards: 0, | 						ConnectedDashboards: 0, | ||||||
| 						Created:             result.Result.Meta.Created, | 						Created:             result.Result.Meta.Created, | ||||||
| 						Updated:             result.Result.Meta.Updated, | 						Updated:             result.Result.Meta.Updated, | ||||||
| 						CreatedBy: LibraryElementDTOMetaUser{ | 						CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 							ID:        1, | 							Id:        1, | ||||||
| 							Name:      "signed_in_user", | 							Name:      "signed_in_user", | ||||||
| 							AvatarURL: "/avatar/37524e1eb8b3e32850b57db0a19af93b", | 							AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b", | ||||||
| 						}, | 						}, | ||||||
| 						UpdatedBy: LibraryElementDTOMetaUser{ | 						UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 							ID:        1, | 							Id:        1, | ||||||
| 							Name:      "signed_in_user", | 							Name:      "signed_in_user", | ||||||
| 							AvatarURL: "/avatar/37524e1eb8b3e32850b57db0a19af93b", | 							AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b", | ||||||
| 						}, | 						}, | ||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
|  |  | ||||||
|  | @ -8,6 +8,7 @@ import ( | ||||||
| 	"github.com/google/go-cmp/cmp" | 	"github.com/google/go-cmp/cmp" | ||||||
| 	"github.com/stretchr/testify/require" | 	"github.com/stretchr/testify/require" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/grafana/grafana/pkg/kinds/librarypanel" | ||||||
| 	"github.com/grafana/grafana/pkg/models" | 	"github.com/grafana/grafana/pkg/models" | ||||||
| 	"github.com/grafana/grafana/pkg/services/org" | 	"github.com/grafana/grafana/pkg/services/org" | ||||||
| 	"github.com/grafana/grafana/pkg/services/search" | 	"github.com/grafana/grafana/pkg/services/search" | ||||||
|  | @ -81,15 +82,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[0].Meta.Created, | 								Created:             result.Result.Elements[0].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[0].Meta.Updated, | 								Updated:             result.Result.Elements[0].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -146,15 +147,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[0].Meta.Created, | 								Created:             result.Result.Elements[0].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[0].Meta.Updated, | 								Updated:             result.Result.Elements[0].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -208,15 +209,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[0].Meta.Created, | 								Created:             result.Result.Elements[0].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[0].Meta.Updated, | 								Updated:             result.Result.Elements[0].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -243,15 +244,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[1].Meta.Created, | 								Created:             result.Result.Elements[1].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[1].Meta.Updated, | 								Updated:             result.Result.Elements[1].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -308,15 +309,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[0].Meta.Created, | 								Created:             result.Result.Elements[0].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[0].Meta.Updated, | 								Updated:             result.Result.Elements[0].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -343,15 +344,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[1].Meta.Created, | 								Created:             result.Result.Elements[1].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[1].Meta.Updated, | 								Updated:             result.Result.Elements[1].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -429,15 +430,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[0].Meta.Created, | 								Created:             result.Result.Elements[0].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[0].Meta.Updated, | 								Updated:             result.Result.Elements[0].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -464,15 +465,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[1].Meta.Created, | 								Created:             result.Result.Elements[1].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[1].Meta.Updated, | 								Updated:             result.Result.Elements[1].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -568,15 +569,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[0].Meta.Created, | 								Created:             result.Result.Elements[0].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[0].Meta.Updated, | 								Updated:             result.Result.Elements[0].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -665,15 +666,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[0].Meta.Created, | 								Created:             result.Result.Elements[0].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[0].Meta.Updated, | 								Updated:             result.Result.Elements[0].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -700,15 +701,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[1].Meta.Created, | 								Created:             result.Result.Elements[1].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[1].Meta.Updated, | 								Updated:             result.Result.Elements[1].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -765,15 +766,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[0].Meta.Created, | 								Created:             result.Result.Elements[0].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[0].Meta.Updated, | 								Updated:             result.Result.Elements[0].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -830,15 +831,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[0].Meta.Created, | 								Created:             result.Result.Elements[0].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[0].Meta.Updated, | 								Updated:             result.Result.Elements[0].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -896,15 +897,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[0].Meta.Created, | 								Created:             result.Result.Elements[0].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[0].Meta.Updated, | 								Updated:             result.Result.Elements[0].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -971,15 +972,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[0].Meta.Created, | 								Created:             result.Result.Elements[0].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[0].Meta.Updated, | 								Updated:             result.Result.Elements[0].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -1044,15 +1045,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[0].Meta.Created, | 								Created:             result.Result.Elements[0].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[0].Meta.Updated, | 								Updated:             result.Result.Elements[0].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -1079,15 +1080,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[1].Meta.Created, | 								Created:             result.Result.Elements[1].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[1].Meta.Updated, | 								Updated:             result.Result.Elements[1].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  | @ -1146,15 +1147,15 @@ func TestGetAllLibraryElements(t *testing.T) { | ||||||
| 								ConnectedDashboards: 0, | 								ConnectedDashboards: 0, | ||||||
| 								Created:             result.Result.Elements[0].Meta.Created, | 								Created:             result.Result.Elements[0].Meta.Created, | ||||||
| 								Updated:             result.Result.Elements[0].Meta.Updated, | 								Updated:             result.Result.Elements[0].Meta.Updated, | ||||||
| 								CreatedBy: LibraryElementDTOMetaUser{ | 								CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 								UpdatedBy: LibraryElementDTOMetaUser{ | 								UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 									ID:        1, | 									Id:        1, | ||||||
| 									Name:      userInDbName, | 									Name:      userInDbName, | ||||||
| 									AvatarURL: userInDbAvatar, | 									AvatarUrl: userInDbAvatar, | ||||||
| 								}, | 								}, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"github.com/google/go-cmp/cmp" | 	"github.com/google/go-cmp/cmp" | ||||||
| 	"github.com/grafana/grafana/pkg/components/simplejson" | 	"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/dashboards" | ||||||
| 	"github.com/grafana/grafana/pkg/services/org" | 	"github.com/grafana/grafana/pkg/services/org" | ||||||
| 	"github.com/grafana/grafana/pkg/web" | 	"github.com/grafana/grafana/pkg/web" | ||||||
|  | @ -54,15 +55,15 @@ func TestGetLibraryElement(t *testing.T) { | ||||||
| 							ConnectedDashboards: 0, | 							ConnectedDashboards: 0, | ||||||
| 							Created:             res.Result.Meta.Created, | 							Created:             res.Result.Meta.Created, | ||||||
| 							Updated:             res.Result.Meta.Updated, | 							Updated:             res.Result.Meta.Updated, | ||||||
| 							CreatedBy: LibraryElementDTOMetaUser{ | 							CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 								ID:        1, | 								Id:        1, | ||||||
| 								Name:      userInDbName, | 								Name:      userInDbName, | ||||||
| 								AvatarURL: userInDbAvatar, | 								AvatarUrl: userInDbAvatar, | ||||||
| 							}, | 							}, | ||||||
| 							UpdatedBy: LibraryElementDTOMetaUser{ | 							UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 								ID:        1, | 								Id:        1, | ||||||
| 								Name:      userInDbName, | 								Name:      userInDbName, | ||||||
| 								AvatarURL: userInDbAvatar, | 								AvatarUrl: userInDbAvatar, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
| 					}, | 					}, | ||||||
|  | @ -149,15 +150,15 @@ func TestGetLibraryElement(t *testing.T) { | ||||||
| 							ConnectedDashboards: 1, | 							ConnectedDashboards: 1, | ||||||
| 							Created:             res.Result.Meta.Created, | 							Created:             res.Result.Meta.Created, | ||||||
| 							Updated:             res.Result.Meta.Updated, | 							Updated:             res.Result.Meta.Updated, | ||||||
| 							CreatedBy: LibraryElementDTOMetaUser{ | 							CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 								ID:        1, | 								Id:        1, | ||||||
| 								Name:      userInDbName, | 								Name:      userInDbName, | ||||||
| 								AvatarURL: userInDbAvatar, | 								AvatarUrl: userInDbAvatar, | ||||||
| 							}, | 							}, | ||||||
| 							UpdatedBy: LibraryElementDTOMetaUser{ | 							UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 								ID:        1, | 								Id:        1, | ||||||
| 								Name:      userInDbName, | 								Name:      userInDbName, | ||||||
| 								AvatarURL: userInDbAvatar, | 								AvatarUrl: userInDbAvatar, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
| 					}, | 					}, | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ package libraryelements | ||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/grafana/grafana/pkg/kinds/librarypanel" | ||||||
| 	"github.com/grafana/grafana/pkg/util" | 	"github.com/grafana/grafana/pkg/util" | ||||||
| 
 | 
 | ||||||
| 	"github.com/google/go-cmp/cmp" | 	"github.com/google/go-cmp/cmp" | ||||||
|  | @ -68,15 +69,15 @@ func TestPatchLibraryElement(t *testing.T) { | ||||||
| 						ConnectedDashboards: 0, | 						ConnectedDashboards: 0, | ||||||
| 						Created:             sc.initialResult.Result.Meta.Created, | 						Created:             sc.initialResult.Result.Meta.Created, | ||||||
| 						Updated:             result.Result.Meta.Updated, | 						Updated:             result.Result.Meta.Updated, | ||||||
| 						CreatedBy: LibraryElementDTOMetaUser{ | 						CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 							ID:        1, | 							Id:        1, | ||||||
| 							Name:      userInDbName, | 							Name:      userInDbName, | ||||||
| 							AvatarURL: userInDbAvatar, | 							AvatarUrl: userInDbAvatar, | ||||||
| 						}, | 						}, | ||||||
| 						UpdatedBy: LibraryElementDTOMetaUser{ | 						UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 							ID:        1, | 							Id:        1, | ||||||
| 							Name:      "signed_in_user", | 							Name:      "signed_in_user", | ||||||
| 							AvatarURL: "/avatar/37524e1eb8b3e32850b57db0a19af93b", | 							AvatarUrl: "/avatar/37524e1eb8b3e32850b57db0a19af93b", | ||||||
| 						}, | 						}, | ||||||
| 					}, | 					}, | ||||||
| 				}, | 				}, | ||||||
|  | @ -101,7 +102,7 @@ func TestPatchLibraryElement(t *testing.T) { | ||||||
| 			var result = validateAndUnMarshalResponse(t, resp) | 			var result = validateAndUnMarshalResponse(t, resp) | ||||||
| 			sc.initialResult.Result.FolderID = newFolder.ID | 			sc.initialResult.Result.FolderID = newFolder.ID | ||||||
| 			sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName | 			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.Meta.Updated = result.Result.Meta.Updated | ||||||
| 			sc.initialResult.Result.Version = 2 | 			sc.initialResult.Result.Version = 2 | ||||||
| 			sc.initialResult.Result.Meta.FolderName = "NewFolder" | 			sc.initialResult.Result.Meta.FolderName = "NewFolder" | ||||||
|  | @ -125,7 +126,7 @@ func TestPatchLibraryElement(t *testing.T) { | ||||||
| 			var result = validateAndUnMarshalResponse(t, resp) | 			var result = validateAndUnMarshalResponse(t, resp) | ||||||
| 			sc.initialResult.Result.Name = "New Name" | 			sc.initialResult.Result.Name = "New Name" | ||||||
| 			sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName | 			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.Meta.Updated = result.Result.Meta.Updated | ||||||
| 			sc.initialResult.Result.Model["title"] = "Text - Library Panel" | 			sc.initialResult.Result.Model["title"] = "Text - Library Panel" | ||||||
| 			sc.initialResult.Result.Version = 2 | 			sc.initialResult.Result.Version = 2 | ||||||
|  | @ -148,7 +149,7 @@ func TestPatchLibraryElement(t *testing.T) { | ||||||
| 			var result = validateAndUnMarshalResponse(t, resp) | 			var result = validateAndUnMarshalResponse(t, resp) | ||||||
| 			sc.initialResult.Result.UID = cmd.UID | 			sc.initialResult.Result.UID = cmd.UID | ||||||
| 			sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName | 			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.Meta.Updated = result.Result.Meta.Updated | ||||||
| 			sc.initialResult.Result.Model["title"] = "Text - Library Panel" | 			sc.initialResult.Result.Model["title"] = "Text - Library Panel" | ||||||
| 			sc.initialResult.Result.Version = 2 | 			sc.initialResult.Result.Version = 2 | ||||||
|  | @ -225,7 +226,7 @@ func TestPatchLibraryElement(t *testing.T) { | ||||||
| 				"description": "New description", | 				"description": "New description", | ||||||
| 			} | 			} | ||||||
| 			sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName | 			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.Meta.Updated = result.Result.Meta.Updated | ||||||
| 			sc.initialResult.Result.Version = 2 | 			sc.initialResult.Result.Version = 2 | ||||||
| 			if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" { | 			if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" { | ||||||
|  | @ -252,7 +253,7 @@ func TestPatchLibraryElement(t *testing.T) { | ||||||
| 				"description": "New description", | 				"description": "New description", | ||||||
| 			} | 			} | ||||||
| 			sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName | 			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.Meta.Updated = result.Result.Meta.Updated | ||||||
| 			sc.initialResult.Result.Version = 2 | 			sc.initialResult.Result.Version = 2 | ||||||
| 			if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" { | 			if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" { | ||||||
|  | @ -279,7 +280,7 @@ func TestPatchLibraryElement(t *testing.T) { | ||||||
| 				"description": "A description", | 				"description": "A description", | ||||||
| 			} | 			} | ||||||
| 			sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName | 			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.Meta.Updated = result.Result.Meta.Updated | ||||||
| 			sc.initialResult.Result.Version = 2 | 			sc.initialResult.Result.Version = 2 | ||||||
| 			if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" { | 			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) | 			sc.ctx.Req.Body = mockRequestBody(cmd) | ||||||
| 			resp := sc.service.patchHandler(sc.reqContext) | 			resp := sc.service.patchHandler(sc.reqContext) | ||||||
| 			var result = validateAndUnMarshalResponse(t, resp) | 			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.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.Meta.Updated = result.Result.Meta.Updated | ||||||
| 			sc.initialResult.Result.Version = 2 | 			sc.initialResult.Result.Version = 2 | ||||||
| 			if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" { | 			if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" { | ||||||
|  | @ -393,7 +394,7 @@ func TestPatchLibraryElement(t *testing.T) { | ||||||
| 				"description": "A description", | 				"description": "A description", | ||||||
| 			} | 			} | ||||||
| 			sc.initialResult.Result.Meta.CreatedBy.Name = userInDbName | 			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.Meta.Updated = result.Result.Meta.Updated | ||||||
| 			sc.initialResult.Result.Version = 2 | 			sc.initialResult.Result.Version = 2 | ||||||
| 			if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" { | 			if diff := cmp.Diff(sc.initialResult.Result, result.Result, getCompareOptions()...); diff != "" { | ||||||
|  |  | ||||||
|  | @ -252,9 +252,9 @@ func TestLibraryElementPermissions(t *testing.T) { | ||||||
| 					resp := sc.service.createHandler(sc.reqContext) | 					resp := sc.service.createHandler(sc.reqContext) | ||||||
| 					result := validateAndUnMarshalResponse(t, resp) | 					result := validateAndUnMarshalResponse(t, resp) | ||||||
| 					result.Result.Meta.CreatedBy.Name = userInDbName | 					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.Name = userInDbName | ||||||
| 					result.Result.Meta.UpdatedBy.AvatarURL = userInDbAvatar | 					result.Result.Meta.UpdatedBy.AvatarUrl = userInDbAvatar | ||||||
| 					result.Result.Meta.FolderName = folder.Title | 					result.Result.Meta.FolderName = folder.Title | ||||||
| 					result.Result.Meta.FolderUID = folder.UID | 					result.Result.Meta.FolderUID = folder.UID | ||||||
| 					results = append(results, result.Result) | 					results = append(results, result.Result) | ||||||
|  | @ -275,9 +275,9 @@ func TestLibraryElementPermissions(t *testing.T) { | ||||||
| 				resp := sc.service.createHandler(sc.reqContext) | 				resp := sc.service.createHandler(sc.reqContext) | ||||||
| 				result := validateAndUnMarshalResponse(t, resp) | 				result := validateAndUnMarshalResponse(t, resp) | ||||||
| 				result.Result.Meta.CreatedBy.Name = userInDbName | 				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.Name = userInDbName | ||||||
| 				result.Result.Meta.UpdatedBy.AvatarURL = userInDbAvatar | 				result.Result.Meta.UpdatedBy.AvatarUrl = userInDbAvatar | ||||||
| 				result.Result.Meta.FolderName = "General" | 				result.Result.Meta.FolderName = "General" | ||||||
| 				result.Result.Meta.FolderUID = "" | 				result.Result.Meta.FolderUID = "" | ||||||
| 				sc.reqContext.SignedInUser.OrgRole = testCase.role | 				sc.reqContext.SignedInUser.OrgRole = testCase.role | ||||||
|  | @ -315,9 +315,9 @@ func TestLibraryElementPermissions(t *testing.T) { | ||||||
| 					resp := sc.service.createHandler(sc.reqContext) | 					resp := sc.service.createHandler(sc.reqContext) | ||||||
| 					result := validateAndUnMarshalResponse(t, resp) | 					result := validateAndUnMarshalResponse(t, resp) | ||||||
| 					result.Result.Meta.CreatedBy.Name = userInDbName | 					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.Name = userInDbName | ||||||
| 					result.Result.Meta.UpdatedBy.AvatarURL = userInDbAvatar | 					result.Result.Meta.UpdatedBy.AvatarUrl = userInDbAvatar | ||||||
| 					result.Result.Meta.FolderName = folder.Title | 					result.Result.Meta.FolderName = folder.Title | ||||||
| 					result.Result.Meta.FolderUID = folder.UID | 					result.Result.Meta.FolderUID = folder.UID | ||||||
| 					results = append(results, result.Result) | 					results = append(results, result.Result) | ||||||
|  | @ -367,9 +367,9 @@ func TestLibraryElementPermissions(t *testing.T) { | ||||||
| 				resp := sc.service.createHandler(sc.reqContext) | 				resp := sc.service.createHandler(sc.reqContext) | ||||||
| 				result := validateAndUnMarshalResponse(t, resp) | 				result := validateAndUnMarshalResponse(t, resp) | ||||||
| 				result.Result.Meta.CreatedBy.Name = userInDbName | 				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.Name = userInDbName | ||||||
| 				result.Result.Meta.UpdatedBy.AvatarURL = userInDbAvatar | 				result.Result.Meta.UpdatedBy.AvatarUrl = userInDbAvatar | ||||||
| 				result.Result.Meta.FolderName = "General" | 				result.Result.Meta.FolderName = "General" | ||||||
| 				sc.reqContext.SignedInUser.OrgRole = testCase.role | 				sc.reqContext.SignedInUser.OrgRole = testCase.role | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -19,6 +19,7 @@ import ( | ||||||
| 	"github.com/grafana/grafana/pkg/infra/db" | 	"github.com/grafana/grafana/pkg/infra/db" | ||||||
| 	"github.com/grafana/grafana/pkg/infra/db/dbtest" | 	"github.com/grafana/grafana/pkg/infra/db/dbtest" | ||||||
| 	"github.com/grafana/grafana/pkg/infra/tracing" | 	"github.com/grafana/grafana/pkg/infra/tracing" | ||||||
|  | 	"github.com/grafana/grafana/pkg/kinds/librarypanel" | ||||||
| 	"github.com/grafana/grafana/pkg/models" | 	"github.com/grafana/grafana/pkg/models" | ||||||
| 	acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" | 	acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" | ||||||
| 	"github.com/grafana/grafana/pkg/services/alerting" | 	"github.com/grafana/grafana/pkg/services/alerting" | ||||||
|  | @ -165,10 +166,10 @@ func TestGetLibraryPanelConnections(t *testing.T) { | ||||||
| 							ConnectionID:  dashInDB.ID, | 							ConnectionID:  dashInDB.ID, | ||||||
| 							ConnectionUID: dashInDB.UID, | 							ConnectionUID: dashInDB.UID, | ||||||
| 							Created:       res.Result[0].Created, | 							Created:       res.Result[0].Created, | ||||||
| 							CreatedBy: LibraryElementDTOMetaUser{ | 							CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 								ID:        1, | 								Id:        1, | ||||||
| 								Name:      userInDbName, | 								Name:      userInDbName, | ||||||
| 								AvatarURL: userInDbAvatar, | 								AvatarUrl: userInDbAvatar, | ||||||
| 							}, | 							}, | ||||||
| 						}, | 						}, | ||||||
| 					}, | 					}, | ||||||
|  |  | ||||||
|  | @ -4,6 +4,8 @@ import ( | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"time" | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/grafana/grafana/pkg/kinds/librarypanel" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type LibraryConnectionKind int | type LibraryConnectionKind int | ||||||
|  | @ -93,15 +95,8 @@ type LibraryElementDTOMeta struct { | ||||||
| 	Created time.Time `json:"created"` | 	Created time.Time `json:"created"` | ||||||
| 	Updated time.Time `json:"updated"` | 	Updated time.Time `json:"updated"` | ||||||
| 
 | 
 | ||||||
| 	CreatedBy LibraryElementDTOMetaUser `json:"createdBy"` | 	CreatedBy librarypanel.LibraryElementDTOMetaUser `json:"createdBy"` | ||||||
| 	UpdatedBy LibraryElementDTOMetaUser `json:"updatedBy"` | 	UpdatedBy librarypanel.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"` |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // libraryElementConnection is the model for library element connections.
 | // libraryElementConnection is the model for library element connections.
 | ||||||
|  | @ -129,13 +124,13 @@ type libraryElementConnectionWithMeta struct { | ||||||
| 
 | 
 | ||||||
| // LibraryElementConnectionDTO is the frontend DTO for element connections.
 | // LibraryElementConnectionDTO is the frontend DTO for element connections.
 | ||||||
| type LibraryElementConnectionDTO struct { | type LibraryElementConnectionDTO struct { | ||||||
| 	ID            int64                     `json:"id"` | 	ID            int64                                  `json:"id"` | ||||||
| 	Kind          int64                     `json:"kind"` | 	Kind          int64                                  `json:"kind"` | ||||||
| 	ElementID     int64                     `json:"elementId"` | 	ElementID     int64                                  `json:"elementId"` | ||||||
| 	ConnectionID  int64                     `json:"connectionId"` | 	ConnectionID  int64                                  `json:"connectionId"` | ||||||
| 	ConnectionUID string                    `json:"connectionUid"` | 	ConnectionUID string                                 `json:"connectionUid"` | ||||||
| 	Created       time.Time                 `json:"created"` | 	Created       time.Time                              `json:"created"` | ||||||
| 	CreatedBy     LibraryElementDTOMetaUser `json:"createdBy"` | 	CreatedBy     librarypanel.LibraryElementDTOMetaUser `json:"createdBy"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
|  |  | ||||||
|  | @ -18,6 +18,7 @@ import ( | ||||||
| 	"github.com/grafana/grafana/pkg/infra/db/dbtest" | 	"github.com/grafana/grafana/pkg/infra/db/dbtest" | ||||||
| 	"github.com/grafana/grafana/pkg/infra/slugify" | 	"github.com/grafana/grafana/pkg/infra/slugify" | ||||||
| 	"github.com/grafana/grafana/pkg/infra/tracing" | 	"github.com/grafana/grafana/pkg/infra/tracing" | ||||||
|  | 	"github.com/grafana/grafana/pkg/kinds/librarypanel" | ||||||
| 	"github.com/grafana/grafana/pkg/models" | 	"github.com/grafana/grafana/pkg/models" | ||||||
| 	acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" | 	acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock" | ||||||
| 	"github.com/grafana/grafana/pkg/services/alerting" | 	"github.com/grafana/grafana/pkg/services/alerting" | ||||||
|  | @ -634,15 +635,15 @@ func toLibraryElement(t *testing.T, res libraryelements.LibraryElementDTO) libra | ||||||
| 			ConnectedDashboards: res.Meta.ConnectedDashboards, | 			ConnectedDashboards: res.Meta.ConnectedDashboards, | ||||||
| 			Created:             res.Meta.Created, | 			Created:             res.Meta.Created, | ||||||
| 			Updated:             res.Meta.Updated, | 			Updated:             res.Meta.Updated, | ||||||
| 			CreatedBy: libraryelements.LibraryElementDTOMetaUser{ | 			CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 				ID:        res.Meta.CreatedBy.ID, | 				Id:        res.Meta.CreatedBy.Id, | ||||||
| 				Name:      res.Meta.CreatedBy.Name, | 				Name:      res.Meta.CreatedBy.Name, | ||||||
| 				AvatarURL: res.Meta.CreatedBy.AvatarURL, | 				AvatarUrl: res.Meta.CreatedBy.AvatarUrl, | ||||||
| 			}, | 			}, | ||||||
| 			UpdatedBy: libraryelements.LibraryElementDTOMetaUser{ | 			UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 				ID:        res.Meta.UpdatedBy.ID, | 				Id:        res.Meta.UpdatedBy.Id, | ||||||
| 				Name:      res.Meta.UpdatedBy.Name, | 				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, | 			ConnectedDashboards: 0, | ||||||
| 			Created:             res.Meta.Created, | 			Created:             res.Meta.Created, | ||||||
| 			Updated:             res.Meta.Updated, | 			Updated:             res.Meta.Updated, | ||||||
| 			CreatedBy: libraryelements.LibraryElementDTOMetaUser{ | 			CreatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 				ID:        1, | 				Id:        1, | ||||||
| 				Name:      userInDbName, | 				Name:      userInDbName, | ||||||
| 				AvatarURL: userInDbAvatar, | 				AvatarUrl: userInDbAvatar, | ||||||
| 			}, | 			}, | ||||||
| 			UpdatedBy: libraryelements.LibraryElementDTOMetaUser{ | 			UpdatedBy: librarypanel.LibraryElementDTOMetaUser{ | ||||||
| 				ID:        1, | 				Id:        1, | ||||||
| 				Name:      userInDbName, | 				Name:      userInDbName, | ||||||
| 				AvatarURL: userInDbAvatar, | 				AvatarUrl: userInDbAvatar, | ||||||
| 			}, | 			}, | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -113,7 +113,7 @@ export const AddPanelWidgetUnconnected = ({ panel, dashboard }: Props) => { | ||||||
|   const onAddLibraryPanel = (panelInfo: LibraryElementDTO) => { |   const onAddLibraryPanel = (panelInfo: LibraryElementDTO) => { | ||||||
|     const { gridPos } = panel; |     const { gridPos } = panel; | ||||||
| 
 | 
 | ||||||
|     const newPanel: PanelModel = { |     const newPanel = { | ||||||
|       ...panelInfo.model, |       ...panelInfo.model, | ||||||
|       gridPos, |       gridPos, | ||||||
|       libraryPanel: panelInfo, |       libraryPanel: panelInfo, | ||||||
|  |  | ||||||
|  | @ -177,7 +177,7 @@ export class DashboardExporter { | ||||||
|           model = libPanel.model; |           model = libPanel.model; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const { gridPos, id, ...rest } = model; |         const { gridPos, id, ...rest } = model as any; | ||||||
|         if (!libraryPanels.has(uid)) { |         if (!libraryPanels.has(uid)) { | ||||||
|           libraryPanels.set(uid, { name, uid, kind: LibraryElementKind.Panel, model: rest }); |           libraryPanels.set(uid, { name, uid, kind: LibraryElementKind.Panel, model: rest }); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  | @ -23,6 +23,7 @@ import { | ||||||
|   restoreCustomOverrideRules, |   restoreCustomOverrideRules, | ||||||
| } from '@grafana/data'; | } from '@grafana/data'; | ||||||
| import { getTemplateSrv, RefreshEvent } from '@grafana/runtime'; | import { getTemplateSrv, RefreshEvent } from '@grafana/runtime'; | ||||||
|  | import { LibraryPanel, LibraryPanelRef } from '@grafana/schema'; | ||||||
| import config from 'app/core/config'; | import config from 'app/core/config'; | ||||||
| import { safeStringifyValue } from 'app/core/utils/explore'; | import { safeStringifyValue } from 'app/core/utils/explore'; | ||||||
| import { getNextRefIdChar } from 'app/core/utils/query'; | import { getNextRefIdChar } from 'app/core/utils/query'; | ||||||
|  | @ -35,7 +36,6 @@ import { | ||||||
|   RenderEvent, |   RenderEvent, | ||||||
| } from 'app/types/events'; | } from 'app/types/events'; | ||||||
| 
 | 
 | ||||||
| import { LibraryElementDTO, LibraryPanelRef } from '../../library-panels/types'; |  | ||||||
| import { PanelQueryRunner } from '../../query/state/PanelQueryRunner'; | import { PanelQueryRunner } from '../../query/state/PanelQueryRunner'; | ||||||
| import { getVariablesUrlParams } from '../../variables/getAllVariableValuesForUrl'; | import { getVariablesUrlParams } from '../../variables/getAllVariableValuesForUrl'; | ||||||
| import { getTimeSrv } from '../services/TimeSrv'; | import { getTimeSrv } from '../services/TimeSrv'; | ||||||
|  | @ -172,7 +172,7 @@ export class PanelModel implements DataConfigSource, IPanelModel { | ||||||
|   links?: DataLink[]; |   links?: DataLink[]; | ||||||
|   declare transparent: boolean; |   declare transparent: boolean; | ||||||
| 
 | 
 | ||||||
|   libraryPanel?: LibraryPanelRef | LibraryElementDTO; |   libraryPanel?: LibraryPanelRef | LibraryPanel; | ||||||
| 
 | 
 | ||||||
|   autoMigrateFrom?: string; |   autoMigrateFrom?: string; | ||||||
| 
 | 
 | ||||||
|  | @ -680,7 +680,7 @@ export class PanelModel implements DataConfigSource, IPanelModel { | ||||||
|     return this.replaceVariables(this.title, undefined, 'text'); |     return this.replaceVariables(this.title, undefined, 'text'); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   initLibraryPanel(libPanel: LibraryElementDTO) { |   initLibraryPanel(libPanel: LibraryPanel) { | ||||||
|     for (const [key, val] of Object.entries(libPanel.model)) { |     for (const [key, val] of Object.entries(libPanel.model)) { | ||||||
|       switch (key) { |       switch (key) { | ||||||
|         case 'id': |         case 'id': | ||||||
|  |  | ||||||
|  | @ -62,7 +62,7 @@ interface FolderLinkProps { | ||||||
| function FolderLink({ libraryPanel }: FolderLinkProps): ReactElement | null { | function FolderLink({ libraryPanel }: FolderLinkProps): ReactElement | null { | ||||||
|   const styles = useStyles2(getStyles); |   const styles = useStyles2(getStyles); | ||||||
| 
 | 
 | ||||||
|   if (!libraryPanel.meta.folderUid && !libraryPanel.meta.folderName) { |   if (!libraryPanel.meta?.folderUid && !libraryPanel.meta?.folderName) { | ||||||
|     return null; |     return null; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,11 +4,12 @@ import userEvent from '@testing-library/user-event'; | ||||||
| import React from 'react'; | import React from 'react'; | ||||||
| 
 | 
 | ||||||
| import { PanelPluginMeta, PluginType } from '@grafana/data'; | import { PanelPluginMeta, PluginType } from '@grafana/data'; | ||||||
|  | import { Panel } from '@grafana/schema'; | ||||||
| 
 | 
 | ||||||
| import { backendSrv } from '../../../../core/services/backend_srv'; | import { backendSrv } from '../../../../core/services/backend_srv'; | ||||||
| import * as panelUtils from '../../../panel/state/util'; | import * as panelUtils from '../../../panel/state/util'; | ||||||
| import * as api from '../../state/api'; | import * as api from '../../state/api'; | ||||||
| import { LibraryElementKind, LibraryElementsSearchResult } from '../../types'; | import { LibraryElementsSearchResult } from '../../types'; | ||||||
| 
 | 
 | ||||||
| import { LibraryPanelsSearch, LibraryPanelsSearchProps } from './LibraryPanelsSearch'; | import { LibraryPanelsSearch, LibraryPanelsSearchProps } from './LibraryPanelsSearch'; | ||||||
| 
 | 
 | ||||||
|  | @ -182,15 +183,12 @@ describe('LibraryPanelsSearch', () => { | ||||||
|           { |           { | ||||||
|             elements: [ |             elements: [ | ||||||
|               { |               { | ||||||
|                 id: 1, |  | ||||||
|                 name: 'Library Panel Name', |                 name: 'Library Panel Name', | ||||||
|                 kind: LibraryElementKind.Panel, |  | ||||||
|                 uid: 'uid', |                 uid: 'uid', | ||||||
|                 description: 'Library Panel Description', |                 description: 'Library Panel Description', | ||||||
|                 folderUid: '', |                 folderUid: '', | ||||||
|                 model: { type: 'timeseries', title: 'A title' }, |                 model: { type: 'timeseries', title: 'A title' } as Panel, | ||||||
|                 type: 'timeseries', |                 type: 'timeseries', | ||||||
|                 orgId: 1, |  | ||||||
|                 version: 1, |                 version: 1, | ||||||
|                 meta: { |                 meta: { | ||||||
|                   folderName: 'General', |                   folderName: 'General', | ||||||
|  | @ -237,15 +235,12 @@ describe('LibraryPanelsSearch', () => { | ||||||
|           perPage: 40, |           perPage: 40, | ||||||
|           elements: [ |           elements: [ | ||||||
|             { |             { | ||||||
|               id: 1, |  | ||||||
|               name: 'Library Panel Name', |               name: 'Library Panel Name', | ||||||
|               kind: LibraryElementKind.Panel, |  | ||||||
|               uid: 'uid', |               uid: 'uid', | ||||||
|               description: 'Library Panel Description', |               description: 'Library Panel Description', | ||||||
|               folderUid: '', |               folderUid: '', | ||||||
|               model: { type: 'timeseries', title: 'A title' }, |               model: { type: 'timeseries', title: 'A title' } as Panel, | ||||||
|               type: 'timeseries', |               type: 'timeseries', | ||||||
|               orgId: 1, |  | ||||||
|               version: 1, |               version: 1, | ||||||
|               meta: { |               meta: { | ||||||
|                 folderName: 'General', |                 folderName: 'General', | ||||||
|  | @ -281,15 +276,12 @@ describe('LibraryPanelsSearch', () => { | ||||||
|           perPage: 40, |           perPage: 40, | ||||||
|           elements: [ |           elements: [ | ||||||
|             { |             { | ||||||
|               id: 1, |  | ||||||
|               name: 'Library Panel Name', |               name: 'Library Panel Name', | ||||||
|               kind: LibraryElementKind.Panel, |  | ||||||
|               uid: 'uid', |               uid: 'uid', | ||||||
|               description: 'Library Panel Description', |               description: 'Library Panel Description', | ||||||
|               folderUid: '', |               folderUid: '', | ||||||
|               model: { type: 'timeseries', title: 'A title' }, |               model: { type: 'timeseries', title: 'A title' } as Panel, | ||||||
|               type: 'timeseries', |               type: 'timeseries', | ||||||
|               orgId: 1, |  | ||||||
|               version: 1, |               version: 1, | ||||||
|               meta: { |               meta: { | ||||||
|                 folderName: 'General', |                 folderName: 'General', | ||||||
|  |  | ||||||
|  | @ -1,7 +1,8 @@ | ||||||
| import { LoadingState } from '@grafana/data'; | import { LoadingState } from '@grafana/data'; | ||||||
|  | import { Panel } from '@grafana/schema'; | ||||||
| 
 | 
 | ||||||
| import { reducerTester } from '../../../../../test/core/redux/reducerTester'; | import { reducerTester } from '../../../../../test/core/redux/reducerTester'; | ||||||
| import { LibraryElementDTO, LibraryElementKind } from '../../types'; | import { LibraryElementDTO } from '../../types'; | ||||||
| 
 | 
 | ||||||
| import { | import { | ||||||
|   changePage, |   changePage, | ||||||
|  | @ -93,7 +94,6 @@ function getLibraryPanelMocks(count: number): LibraryElementDTO[] { | ||||||
|     mocks.push( |     mocks.push( | ||||||
|       mockLibraryPanel({ |       mockLibraryPanel({ | ||||||
|         uid: i.toString(10), |         uid: i.toString(10), | ||||||
|         id: i, |  | ||||||
|         name: `Test Panel ${i}`, |         name: `Test Panel ${i}`, | ||||||
|       }) |       }) | ||||||
|     ); |     ); | ||||||
|  | @ -104,11 +104,9 @@ function getLibraryPanelMocks(count: number): LibraryElementDTO[] { | ||||||
| 
 | 
 | ||||||
| function mockLibraryPanel({ | function mockLibraryPanel({ | ||||||
|   uid = '1', |   uid = '1', | ||||||
|   id = 1, |  | ||||||
|   orgId = 1, |  | ||||||
|   folderUid = '', |   folderUid = '', | ||||||
|   name = 'Test Panel', |   name = 'Test Panel', | ||||||
|   model = { type: 'text', title: 'Test Panel' }, |   model = { type: 'text', title: 'Test Panel' } as Panel, | ||||||
|   meta = { |   meta = { | ||||||
|     folderName: 'General', |     folderName: 'General', | ||||||
|     folderUid: '', |     folderUid: '', | ||||||
|  | @ -124,11 +122,8 @@ function mockLibraryPanel({ | ||||||
| }: Partial<LibraryElementDTO> = {}): LibraryElementDTO { | }: Partial<LibraryElementDTO> = {}): LibraryElementDTO { | ||||||
|   return { |   return { | ||||||
|     uid, |     uid, | ||||||
|     id, |  | ||||||
|     orgId, |  | ||||||
|     folderUid, |     folderUid, | ||||||
|     name, |     name, | ||||||
|     kind: LibraryElementKind.Panel, |  | ||||||
|     model, |     model, | ||||||
|     version, |     version, | ||||||
|     meta, |     meta, | ||||||
|  |  | ||||||
|  | @ -64,8 +64,8 @@ export const SaveLibraryPanelModal = ({ | ||||||
|         <p className={styles.textInfo}> |         <p className={styles.textInfo}> | ||||||
|           {'This update will affect '} |           {'This update will affect '} | ||||||
|           <strong> |           <strong> | ||||||
|             {panel.libraryPanel.meta.connectedDashboards}{' '} |             {panel.libraryPanel.meta?.connectedDashboards}{' '} | ||||||
|             {panel.libraryPanel.meta.connectedDashboards === 1 ? 'dashboard' : 'dashboards'}. |             {panel.libraryPanel.meta?.connectedDashboards === 1 ? 'dashboard' : 'dashboards'}. | ||||||
|           </strong> |           </strong> | ||||||
|           The following dashboards using the panel will be affected: |           The following dashboards using the panel will be affected: | ||||||
|         </p> |         </p> | ||||||
|  |  | ||||||
|  | @ -1,17 +1,22 @@ | ||||||
| import { AnyAction } from '@reduxjs/toolkit'; | import { AnyAction } from '@reduxjs/toolkit'; | ||||||
| import { Dispatch } from 'react'; | 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'; | import { PanelModel } from '../dashboard/state'; | ||||||
| 
 | 
 | ||||||
| export enum LibraryElementKind { | export enum LibraryElementKind { | ||||||
|   Panel = 1, |   Panel = 1, | ||||||
|   Variable, |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export enum LibraryElementConnectionKind { | export enum LibraryElementConnectionKind { | ||||||
|   Dashboard = 1, |   Dashboard = 1, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /** @deprecated use LibraryPanel */ | ||||||
|  | export interface LibraryElementDTO extends LibraryPanel {} | ||||||
|  | 
 | ||||||
| export interface LibraryElementConnectionDTO { | export interface LibraryElementConnectionDTO { | ||||||
|   id: number; |   id: number; | ||||||
|   kind: LibraryElementConnectionKind; |   kind: LibraryElementConnectionKind; | ||||||
|  | @ -24,48 +29,13 @@ export interface LibraryElementConnectionDTO { | ||||||
| 
 | 
 | ||||||
| export interface LibraryElementsSearchResult { | export interface LibraryElementsSearchResult { | ||||||
|   totalCount: number; |   totalCount: number; | ||||||
|   elements: LibraryElementDTO[]; |   elements: LibraryPanel[]; | ||||||
|   perPage: number; |   perPage: number; | ||||||
|   page: 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 { | export interface PanelModelWithLibraryPanel extends PanelModel { | ||||||
|   libraryPanel: LibraryElementDTO; |   libraryPanel: LibraryPanel; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export type DispatchResult = (dispatch: Dispatch<AnyAction>) => void; | export type DispatchResult = (dispatch: Dispatch<AnyAction>) => void; | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ import { css } from '@emotion/css'; | ||||||
| import React, { ReactElement } from 'react'; | import React, { ReactElement } from 'react'; | ||||||
| 
 | 
 | ||||||
| import { GrafanaTheme2 } from '@grafana/data'; | import { GrafanaTheme2 } from '@grafana/data'; | ||||||
|  | import { LibraryPanel } from '@grafana/schema'; | ||||||
| import { Field, useStyles2 } from '@grafana/ui'; | import { Field, useStyles2 } from '@grafana/ui'; | ||||||
| 
 | 
 | ||||||
| import { LibraryPanelCard } from '../../library-panels/components/LibraryPanelCard/LibraryPanelCard'; | import { LibraryPanelCard } from '../../library-panels/components/LibraryPanelCard/LibraryPanelCard'; | ||||||
|  | @ -36,9 +37,10 @@ export function ImportDashboardLibraryPanelsList({ | ||||||
|               input.state === LibraryPanelInputState.New |               input.state === LibraryPanelInputState.New | ||||||
|                 ? { ...input.model, meta: { ...input.model.meta, folderName: folderName ?? 'General' } } |                 ? { ...input.model, meta: { ...input.model.meta, folderName: folderName ?? 'General' } } | ||||||
|                 : { ...input.model }; |                 : { ...input.model }; | ||||||
|  | 
 | ||||||
|             return ( |             return ( | ||||||
|               <div className={styles.item} key={libraryPanelIndex}> |               <div className={styles.item} key={libraryPanelIndex}> | ||||||
|                 <LibraryPanelCard libraryPanel={libraryPanel} onClick={() => undefined} /> |                 <LibraryPanelCard libraryPanel={libraryPanel as LibraryPanel} onClick={() => undefined} /> | ||||||
|               </div> |               </div> | ||||||
|             ); |             ); | ||||||
|           })} |           })} | ||||||
|  |  | ||||||
|  | @ -101,8 +101,6 @@ function processElements(dashboardJson?: { __elements?: Record<string, LibraryEl | ||||||
|           uid, |           uid, | ||||||
|           name, |           name, | ||||||
|           version: 0, |           version: 0, | ||||||
|           meta: {}, |  | ||||||
|           id: 0, |  | ||||||
|           type, |           type, | ||||||
|           kind: LibraryElementKind.Panel, |           kind: LibraryElementKind.Panel, | ||||||
|           description, |           description, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue