mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
LibraryPanels: Load library panels in the frontend rather than the backend (#50560)
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
@@ -27,7 +27,7 @@ export const AddLibraryPanelContents = ({ panel, initialFolderId, onDismiss }: A
|
||||
|
||||
const { saveLibraryPanel } = usePanelSave();
|
||||
const onCreate = useCallback(() => {
|
||||
panel.libraryPanel = { uid: undefined, name: panelName };
|
||||
panel.libraryPanel = { uid: '', name: panelName };
|
||||
saveLibraryPanel(panel, folderId!).then((res) => {
|
||||
if (!(res instanceof Error)) {
|
||||
onDismiss();
|
||||
|
||||
@@ -4,7 +4,6 @@ import React from 'react';
|
||||
import { DateTimeInput, GrafanaTheme } from '@grafana/data';
|
||||
import { useStyles } from '@grafana/ui';
|
||||
|
||||
import { isPanelModelLibraryPanel } from '../../guard';
|
||||
import { PanelModelWithLibraryPanel } from '../../types';
|
||||
|
||||
interface Props {
|
||||
@@ -15,28 +14,29 @@ interface Props {
|
||||
export const LibraryPanelInformation = ({ panel, formatDate }: Props) => {
|
||||
const styles = useStyles(getStyles);
|
||||
|
||||
if (!isPanelModelLibraryPanel(panel)) {
|
||||
const meta = panel.libraryPanel?.meta;
|
||||
if (!meta) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.info}>
|
||||
<div className={styles.libraryPanelInfo}>
|
||||
{`Used on ${panel.libraryPanel.meta.connectedDashboards} `}
|
||||
{panel.libraryPanel.meta.connectedDashboards === 1 ? 'dashboard' : 'dashboards'}
|
||||
{`Used on ${meta.connectedDashboards} `}
|
||||
{meta.connectedDashboards === 1 ? 'dashboard' : 'dashboards'}
|
||||
</div>
|
||||
<div className={styles.libraryPanelInfo}>
|
||||
Last edited on {formatDate?.(panel.libraryPanel.meta.updated, 'L') ?? panel.libraryPanel.meta.updated} by
|
||||
{panel.libraryPanel.meta.updatedBy.avatarUrl && (
|
||||
Last edited on {formatDate?.(meta.updated, 'L') ?? meta.updated} by
|
||||
{meta.updatedBy.avatarUrl && (
|
||||
<img
|
||||
width="22"
|
||||
height="22"
|
||||
className={styles.userAvatar}
|
||||
src={panel.libraryPanel.meta.updatedBy.avatarUrl}
|
||||
alt={`Avatar for ${panel.libraryPanel.meta.updatedBy.name}`}
|
||||
src={meta.updatedBy.avatarUrl}
|
||||
alt={`Avatar for ${meta.updatedBy.name}`}
|
||||
/>
|
||||
)}
|
||||
{panel.libraryPanel.meta.updatedBy.name}
|
||||
{meta.updatedBy.name}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { lastValueFrom } from 'rxjs';
|
||||
|
||||
import { DashboardModel } from 'app/features/dashboard/state';
|
||||
|
||||
import { getBackendSrv } from '../../../core/services/backend_srv';
|
||||
import { DashboardSearchItem } from '../../search/types';
|
||||
import {
|
||||
@@ -54,7 +56,18 @@ export async function getLibraryPanel(uid: string, isHandled = false): Promise<L
|
||||
showErrorAlert: !isHandled,
|
||||
})
|
||||
);
|
||||
return response.data.result;
|
||||
// kinda heavy weight migration process!!!
|
||||
const { result } = response.data;
|
||||
const dash = new DashboardModel({
|
||||
schemaVersion: 35, // should be saved in the library panel
|
||||
panels: [result.model],
|
||||
});
|
||||
const model = dash.panels[0].getSaveModel(); // migrated panel
|
||||
dash.destroy(); // kill event listeners
|
||||
return {
|
||||
...result,
|
||||
model,
|
||||
};
|
||||
}
|
||||
|
||||
export async function getLibraryPanelByName(name: string): Promise<LibraryElementDTO[]> {
|
||||
@@ -76,9 +89,9 @@ export async function addLibraryPanel(
|
||||
}
|
||||
|
||||
export async function updateLibraryPanel(panelSaveModel: PanelModelWithLibraryPanel): Promise<LibraryElementDTO> {
|
||||
const { uid, name, version } = panelSaveModel.libraryPanel;
|
||||
const { libraryPanel, ...model } = panelSaveModel;
|
||||
const { uid, name, version } = libraryPanel;
|
||||
const kind = LibraryElementKind.Panel;
|
||||
const model = panelSaveModel;
|
||||
const { result } = await getBackendSrv().patch(`/api/library-elements/${uid}`, {
|
||||
name,
|
||||
model,
|
||||
|
||||
@@ -59,10 +59,13 @@ export interface LibraryElementDTOMetaUser {
|
||||
avatarUrl: string;
|
||||
}
|
||||
|
||||
export type PanelModelLibraryPanel = Pick<LibraryElementDTO, 'uid' | 'name' | 'meta' | 'version'>;
|
||||
export interface LibraryPanelRef {
|
||||
name: string;
|
||||
uid: string;
|
||||
}
|
||||
|
||||
export interface PanelModelWithLibraryPanel extends PanelModel {
|
||||
libraryPanel: PanelModelLibraryPanel;
|
||||
libraryPanel: LibraryElementDTO;
|
||||
}
|
||||
|
||||
export type DispatchResult = (dispatch: Dispatch<AnyAction>) => void;
|
||||
|
||||
@@ -3,7 +3,7 @@ import { AppNotification } from '../../types';
|
||||
import { PanelModel } from '../dashboard/state';
|
||||
|
||||
import { addLibraryPanel, updateLibraryPanel } from './state/api';
|
||||
import { LibraryElementDTO, PanelModelLibraryPanel } from './types';
|
||||
import { LibraryElementDTO } from './types';
|
||||
|
||||
export function createPanelLibraryErrorNotification(message: string): AppNotification {
|
||||
return createErrorNotification(message);
|
||||
@@ -13,11 +13,6 @@ export function createPanelLibrarySuccessNotification(message: string): AppNotif
|
||||
return createSuccessNotification(message);
|
||||
}
|
||||
|
||||
export function toPanelModelLibraryPanel(libraryPanelDto: LibraryElementDTO): PanelModelLibraryPanel {
|
||||
const { uid, name, meta, version } = libraryPanelDto;
|
||||
return { uid, name, meta, version };
|
||||
}
|
||||
|
||||
export async function saveAndRefreshLibraryPanel(panel: PanelModel, folderId: number): Promise<LibraryElementDTO> {
|
||||
const panelSaveModel = toPanelSaveModel(panel);
|
||||
const savedPanel = await saveOrUpdateLibraryPanel(panelSaveModel, folderId);
|
||||
@@ -42,7 +37,7 @@ function updatePanelModelWithUpdate(panel: PanelModel, updated: LibraryElementDT
|
||||
panel.restoreModel({
|
||||
...updated.model,
|
||||
configRev: 0, // reset config rev, since changes have been saved
|
||||
libraryPanel: toPanelModelLibraryPanel(updated),
|
||||
libraryPanel: updated,
|
||||
title: panel.title,
|
||||
});
|
||||
panel.hasSavedPanelEditChange = true;
|
||||
@@ -54,7 +49,7 @@ function saveOrUpdateLibraryPanel(panel: any, folderId: number): Promise<Library
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
if (panel.libraryPanel && panel.libraryPanel.uid === undefined) {
|
||||
if (panel.libraryPanel && panel.libraryPanel.uid === '') {
|
||||
return addLibraryPanel(panel, folderId!);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user