mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
LibraryPanels: No save modal when user is on same dashboard (#31606)
This commit is contained in:
parent
a8bf1d68e3
commit
d306f417d3
@ -14,8 +14,9 @@ import { updateLocation } from 'app/core/actions';
|
|||||||
import { addPanel } from 'app/features/dashboard/state/reducers';
|
import { addPanel } from 'app/features/dashboard/state/reducers';
|
||||||
import { DashboardModel, PanelModel } from '../../state';
|
import { DashboardModel, PanelModel } from '../../state';
|
||||||
import { LibraryPanelsView } from '../../../library-panels/components/LibraryPanelsView/LibraryPanelsView';
|
import { LibraryPanelsView } from '../../../library-panels/components/LibraryPanelsView/LibraryPanelsView';
|
||||||
import { LibraryPanelDTO } from 'app/features/library-panels/state/api';
|
|
||||||
import { LS_PANEL_COPY_KEY } from 'app/core/constants';
|
import { LS_PANEL_COPY_KEY } from 'app/core/constants';
|
||||||
|
import { LibraryPanelDTO } from '../../../library-panels/types';
|
||||||
|
import { toPanelModelLibraryPanel } from '../../../library-panels/utils';
|
||||||
|
|
||||||
export type PanelPluginInfo = { id: any; defaults: { gridPos: { w: any; h: any }; title: any } };
|
export type PanelPluginInfo = { id: any; defaults: { gridPos: { w: any; h: any }; title: any } };
|
||||||
|
|
||||||
@ -119,7 +120,7 @@ export const AddPanelWidgetUnconnected: React.FC<Props> = ({ panel, dashboard, u
|
|||||||
const newPanel: PanelModel = {
|
const newPanel: PanelModel = {
|
||||||
...panelInfo.model,
|
...panelInfo.model,
|
||||||
gridPos,
|
gridPos,
|
||||||
libraryPanel: _.pick(panelInfo, 'name', 'uid', 'meta'),
|
libraryPanel: toPanelModelLibraryPanel(panelInfo),
|
||||||
};
|
};
|
||||||
|
|
||||||
dashboard.addPanel(newPanel);
|
dashboard.addPanel(newPanel);
|
||||||
|
@ -29,10 +29,10 @@ import { DashboardPanel } from '../../dashgrid/DashboardPanel';
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
exitPanelEditor,
|
exitPanelEditor,
|
||||||
updateSourcePanel,
|
|
||||||
initPanelEditor,
|
initPanelEditor,
|
||||||
panelEditorCleanUp,
|
panelEditorCleanUp,
|
||||||
updatePanelEditorUIState,
|
updatePanelEditorUIState,
|
||||||
|
updateSourcePanel,
|
||||||
} from './state/actions';
|
} from './state/actions';
|
||||||
|
|
||||||
import { updateTimeZoneForSession } from 'app/features/profile/state/reducers';
|
import { updateTimeZoneForSession } from 'app/features/profile/state/reducers';
|
||||||
@ -49,6 +49,14 @@ import { DashboardModel, PanelModel } from '../../state';
|
|||||||
import { PanelOptionsChangedEvent } from 'app/types/events';
|
import { PanelOptionsChangedEvent } from 'app/types/events';
|
||||||
import { UnlinkModal } from '../../../library-panels/components/UnlinkModal/UnlinkModal';
|
import { UnlinkModal } from '../../../library-panels/components/UnlinkModal/UnlinkModal';
|
||||||
import { SaveLibraryPanelModal } from 'app/features/library-panels/components/SaveLibraryPanelModal/SaveLibraryPanelModal';
|
import { SaveLibraryPanelModal } from 'app/features/library-panels/components/SaveLibraryPanelModal/SaveLibraryPanelModal';
|
||||||
|
import { isPanelModelLibraryPanel } from '../../../library-panels/guard';
|
||||||
|
import { getLibraryPanelConnectedDashboards } from '../../../library-panels/state/api';
|
||||||
|
import {
|
||||||
|
createPanelLibraryErrorNotification,
|
||||||
|
createPanelLibrarySuccessNotification,
|
||||||
|
saveAndRefreshLibraryPanel,
|
||||||
|
} from '../../../library-panels/utils';
|
||||||
|
import { notifyApp } from '../../../../core/actions';
|
||||||
|
|
||||||
interface OwnProps {
|
interface OwnProps {
|
||||||
dashboard: DashboardModel;
|
dashboard: DashboardModel;
|
||||||
@ -79,6 +87,7 @@ const mapDispatchToProps = {
|
|||||||
setDiscardChanges,
|
setDiscardChanges,
|
||||||
updatePanelEditorUIState,
|
updatePanelEditorUIState,
|
||||||
updateTimeZoneForSession,
|
updateTimeZoneForSession,
|
||||||
|
notifyApp,
|
||||||
};
|
};
|
||||||
|
|
||||||
const connector = connect(mapStateToProps, mapDispatchToProps);
|
const connector = connect(mapStateToProps, mapDispatchToProps);
|
||||||
@ -129,13 +138,28 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onSavePanel = () => {
|
onSaveLibraryPanel = async () => {
|
||||||
const panelId = this.props.panel.libraryPanel?.uid;
|
if (!isPanelModelLibraryPanel(this.props.panel)) {
|
||||||
if (!panelId) {
|
|
||||||
// New library panel, no need to display modal
|
// New library panel, no need to display modal
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.props.panel.libraryPanel.meta.connectedDashboards === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const connectedDashboards = await getLibraryPanelConnectedDashboards(this.props.panel.libraryPanel.uid);
|
||||||
|
if (connectedDashboards.length === 1 && connectedDashboards.indexOf(this.props.dashboard.id) !== -1) {
|
||||||
|
try {
|
||||||
|
await saveAndRefreshLibraryPanel(this.props.panel, this.props.dashboard.meta.folderId!);
|
||||||
|
this.props.updateSourcePanel(this.props.panel);
|
||||||
|
this.props.notifyApp(createPanelLibrarySuccessNotification('Library panel saved'));
|
||||||
|
} catch (err) {
|
||||||
|
this.props.notifyApp(createPanelLibraryErrorNotification(`Error saving library panel: "${err.statusText}"`));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
appEvents.emit(CoreEvents.showModalReact, {
|
appEvents.emit(CoreEvents.showModalReact, {
|
||||||
component: SaveLibraryPanelModal,
|
component: SaveLibraryPanelModal,
|
||||||
props: {
|
props: {
|
||||||
@ -289,7 +313,7 @@ export class PanelEditorUnconnected extends PureComponent<Props> {
|
|||||||
</ToolbarButton>,
|
</ToolbarButton>,
|
||||||
this.props.panel.libraryPanel ? (
|
this.props.panel.libraryPanel ? (
|
||||||
<ToolbarButton
|
<ToolbarButton
|
||||||
onClick={this.onSavePanel}
|
onClick={this.onSaveLibraryPanel}
|
||||||
variant="primary"
|
variant="primary"
|
||||||
title="Apply changes and save library panel"
|
title="Apply changes and save library panel"
|
||||||
key="save-panel"
|
key="save-panel"
|
||||||
|
@ -6,17 +6,17 @@ import { getNextRefIdChar } from 'app/core/utils/query';
|
|||||||
// Types
|
// Types
|
||||||
import {
|
import {
|
||||||
DataConfigSource,
|
DataConfigSource,
|
||||||
|
DataFrameDTO,
|
||||||
DataLink,
|
DataLink,
|
||||||
|
DataLinkBuiltInVars,
|
||||||
DataQuery,
|
DataQuery,
|
||||||
DataTransformerConfig,
|
DataTransformerConfig,
|
||||||
|
EventBus,
|
||||||
|
EventBusSrv,
|
||||||
FieldConfigSource,
|
FieldConfigSource,
|
||||||
PanelPlugin,
|
PanelPlugin,
|
||||||
ScopedVars,
|
ScopedVars,
|
||||||
EventBus,
|
|
||||||
EventBusSrv,
|
|
||||||
DataFrameDTO,
|
|
||||||
urlUtil,
|
urlUtil,
|
||||||
DataLinkBuiltInVars,
|
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { EDIT_PANEL_ID } from 'app/core/constants';
|
import { EDIT_PANEL_ID } from 'app/core/constants';
|
||||||
import config from 'app/core/config';
|
import config from 'app/core/config';
|
||||||
@ -36,7 +36,7 @@ import {
|
|||||||
isStandardFieldProp,
|
isStandardFieldProp,
|
||||||
restoreCustomOverrideRules,
|
restoreCustomOverrideRules,
|
||||||
} from './getPanelOptionsWithDefaults';
|
} from './getPanelOptionsWithDefaults';
|
||||||
import { LibraryPanelDTO } from 'app/features/library-panels/state/api';
|
import { PanelModelLibraryPanel } from '../../library-panels/types';
|
||||||
|
|
||||||
export interface GridPos {
|
export interface GridPos {
|
||||||
x: number;
|
x: number;
|
||||||
@ -151,7 +151,7 @@ export class PanelModel implements DataConfigSource {
|
|||||||
links?: DataLink[];
|
links?: DataLink[];
|
||||||
transparent: boolean;
|
transparent: boolean;
|
||||||
|
|
||||||
libraryPanel?: { uid: undefined; name: string } | Pick<LibraryPanelDTO, 'uid' | 'name' | 'meta'>;
|
libraryPanel?: { uid: undefined; name: string } | PanelModelLibraryPanel;
|
||||||
|
|
||||||
// non persisted
|
// non persisted
|
||||||
isViewing: boolean;
|
isViewing: boolean;
|
||||||
|
@ -2,7 +2,7 @@ import React, { useState } from 'react';
|
|||||||
import { Icon, IconButton, ConfirmModal, Tooltip, useStyles, Card } from '@grafana/ui';
|
import { Icon, IconButton, ConfirmModal, Tooltip, useStyles, Card } from '@grafana/ui';
|
||||||
import { css } from 'emotion';
|
import { css } from 'emotion';
|
||||||
import { GrafanaTheme } from '@grafana/data';
|
import { GrafanaTheme } from '@grafana/data';
|
||||||
import { LibraryPanelDTO } from '../../state/api';
|
import { LibraryPanelDTO } from '../../types';
|
||||||
|
|
||||||
export interface LibraryPanelCardProps {
|
export interface LibraryPanelCardProps {
|
||||||
libraryPanel: LibraryPanelDTO;
|
libraryPanel: LibraryPanelDTO;
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import { Icon, Input, Button, stylesFactory, useStyles } from '@grafana/ui';
|
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useDebounce } from 'react-use';
|
import { useDebounce } from 'react-use';
|
||||||
import { cx, css } from 'emotion';
|
import { css, cx } from 'emotion';
|
||||||
import { LibraryPanelCard } from '../LibraryPanelCard/LibraryPanelCard';
|
import { Button, Icon, Input, stylesFactory, useStyles } from '@grafana/ui';
|
||||||
import { DateTimeInput, GrafanaTheme } from '@grafana/data';
|
import { DateTimeInput, GrafanaTheme } from '@grafana/data';
|
||||||
import { deleteLibraryPanel, getLibraryPanels, LibraryPanelDTO } from '../../state/api';
|
|
||||||
|
import { LibraryPanelCard } from '../LibraryPanelCard/LibraryPanelCard';
|
||||||
|
import { deleteLibraryPanel, getLibraryPanels } from '../../state/api';
|
||||||
|
import { LibraryPanelDTO } from '../../types';
|
||||||
|
|
||||||
interface LibraryPanelViewProps {
|
interface LibraryPanelViewProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
|
import React, { useState } from 'react';
|
||||||
|
import { css } from 'emotion';
|
||||||
|
import pick from 'lodash/pick';
|
||||||
import { GrafanaTheme } from '@grafana/data';
|
import { GrafanaTheme } from '@grafana/data';
|
||||||
import { Button, stylesFactory, useStyles } from '@grafana/ui';
|
import { Button, stylesFactory, useStyles } from '@grafana/ui';
|
||||||
|
|
||||||
import { OptionsGroup } from 'app/features/dashboard/components/PanelEditor/OptionsGroup';
|
import { OptionsGroup } from 'app/features/dashboard/components/PanelEditor/OptionsGroup';
|
||||||
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
||||||
import { css } from 'emotion';
|
|
||||||
import React, { useState } from 'react';
|
|
||||||
import { AddLibraryPanelModal } from '../AddLibraryPanelModal/AddLibraryPanelModal';
|
import { AddLibraryPanelModal } from '../AddLibraryPanelModal/AddLibraryPanelModal';
|
||||||
import { LibraryPanelsView } from '../LibraryPanelsView/LibraryPanelsView';
|
import { LibraryPanelsView } from '../LibraryPanelsView/LibraryPanelsView';
|
||||||
import pick from 'lodash/pick';
|
|
||||||
import { LibraryPanelDTO } from '../../state/api';
|
|
||||||
import { PanelQueriesChangedEvent } from 'app/types/events';
|
import { PanelQueriesChangedEvent } from 'app/types/events';
|
||||||
|
import { LibraryPanelDTO } from '../../types';
|
||||||
|
import { toPanelModelLibraryPanel } from '../../utils';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
panel: PanelModel;
|
panel: PanelModel;
|
||||||
@ -23,7 +25,7 @@ export const PanelLibraryOptionsGroup: React.FC<Props> = ({ panel, dashboard })
|
|||||||
panel.restoreModel({
|
panel.restoreModel({
|
||||||
...panelInfo.model,
|
...panelInfo.model,
|
||||||
...pick(panel, 'gridPos', 'id'),
|
...pick(panel, 'gridPos', 'id'),
|
||||||
libraryPanel: pick(panelInfo, 'uid', 'name', 'meta'),
|
libraryPanel: toPanelModelLibraryPanel(panelInfo),
|
||||||
});
|
});
|
||||||
|
|
||||||
// dummy change for re-render
|
// dummy change for re-render
|
||||||
|
@ -5,7 +5,8 @@ import { css } from 'emotion';
|
|||||||
import { useAsync, useDebounce } from 'react-use';
|
import { useAsync, useDebounce } from 'react-use';
|
||||||
import { getBackendSrv } from 'app/core/services/backend_srv';
|
import { getBackendSrv } from 'app/core/services/backend_srv';
|
||||||
import { usePanelSave } from '../../utils/usePanelSave';
|
import { usePanelSave } from '../../utils/usePanelSave';
|
||||||
import { getLibraryPanelConnectedDashboards, PanelModelWithLibraryPanel } from '../../state/api';
|
import { getLibraryPanelConnectedDashboards } from '../../state/api';
|
||||||
|
import { PanelModelWithLibraryPanel } from '../../types';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
panel: PanelModelWithLibraryPanel;
|
panel: PanelModelWithLibraryPanel;
|
||||||
|
6
public/app/features/library-panels/guard.ts
Normal file
6
public/app/features/library-panels/guard.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { PanelModel } from '../dashboard/state';
|
||||||
|
import { PanelModelWithLibraryPanel } from './types';
|
||||||
|
|
||||||
|
export function isPanelModelLibraryPanel(panel: PanelModel): panel is PanelModelWithLibraryPanel {
|
||||||
|
return Boolean(panel.libraryPanel?.uid);
|
||||||
|
}
|
@ -1,36 +1,5 @@
|
|||||||
import { getBackendSrv } from '@grafana/runtime';
|
import { getBackendSrv } from '@grafana/runtime';
|
||||||
|
import { LibraryPanelDTO, PanelModelWithLibraryPanel } from '../types';
|
||||||
import { PanelModel } from '../../dashboard/state';
|
|
||||||
|
|
||||||
export interface LibraryPanelDTO {
|
|
||||||
id: number;
|
|
||||||
orgId: number;
|
|
||||||
folderId: number;
|
|
||||||
uid: string;
|
|
||||||
name: string;
|
|
||||||
model: any;
|
|
||||||
version: number;
|
|
||||||
meta: LibraryPanelDTOMeta;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface LibraryPanelDTOMeta {
|
|
||||||
canEdit: boolean;
|
|
||||||
connectedDashboards: number;
|
|
||||||
created: string;
|
|
||||||
updated: string;
|
|
||||||
createdBy: LibraryPanelDTOMetaUser;
|
|
||||||
updatedBy: LibraryPanelDTOMetaUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface LibraryPanelDTOMetaUser {
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
avatarUrl: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface PanelModelWithLibraryPanel extends PanelModel {
|
|
||||||
libraryPanel: Pick<LibraryPanelDTO, 'uid' | 'name' | 'meta' | 'version'>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getLibraryPanels(): Promise<LibraryPanelDTO[]> {
|
export async function getLibraryPanels(): Promise<LibraryPanelDTO[]> {
|
||||||
const { result } = await getBackendSrv().get(`/api/library-panels`);
|
const { result } = await getBackendSrv().get(`/api/library-panels`);
|
||||||
|
33
public/app/features/library-panels/types.ts
Normal file
33
public/app/features/library-panels/types.ts
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import { PanelModel } from '../dashboard/state';
|
||||||
|
|
||||||
|
export interface LibraryPanelDTO {
|
||||||
|
id: number;
|
||||||
|
orgId: number;
|
||||||
|
folderId: number;
|
||||||
|
uid: string;
|
||||||
|
name: string;
|
||||||
|
model: any;
|
||||||
|
version: number;
|
||||||
|
meta: LibraryPanelDTOMeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LibraryPanelDTOMeta {
|
||||||
|
canEdit: boolean;
|
||||||
|
connectedDashboards: number;
|
||||||
|
created: string;
|
||||||
|
updated: string;
|
||||||
|
createdBy: LibraryPanelDTOMetaUser;
|
||||||
|
updatedBy: LibraryPanelDTOMetaUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface LibraryPanelDTOMetaUser {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
avatarUrl: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type PanelModelLibraryPanel = Pick<LibraryPanelDTO, 'uid' | 'name' | 'meta' | 'version'>;
|
||||||
|
|
||||||
|
export interface PanelModelWithLibraryPanel extends PanelModel {
|
||||||
|
libraryPanel: PanelModelLibraryPanel;
|
||||||
|
}
|
59
public/app/features/library-panels/utils.ts
Normal file
59
public/app/features/library-panels/utils.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { LibraryPanelDTO, PanelModelLibraryPanel } from './types';
|
||||||
|
import { PanelModel } from '../dashboard/state';
|
||||||
|
import { addLibraryPanel, updateLibraryPanel } from './state/api';
|
||||||
|
import { createErrorNotification, createSuccessNotification } from '../../core/copy/appNotification';
|
||||||
|
import { AppNotification } from '../../types';
|
||||||
|
|
||||||
|
export function createPanelLibraryErrorNotification(message: string): AppNotification {
|
||||||
|
return createErrorNotification(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createPanelLibrarySuccessNotification(message: string): AppNotification {
|
||||||
|
return createSuccessNotification(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function toPanelModelLibraryPanel(libraryPanelDto: LibraryPanelDTO): PanelModelLibraryPanel {
|
||||||
|
const { uid, name, meta, version } = libraryPanelDto;
|
||||||
|
return { uid, name, meta, version };
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function saveAndRefreshLibraryPanel(panel: PanelModel, folderId: number): Promise<LibraryPanelDTO> {
|
||||||
|
const panelSaveModel = toPanelSaveModel(panel);
|
||||||
|
const savedPanel = await saveOrUpdateLibraryPanel(panelSaveModel, folderId);
|
||||||
|
updatePanelModelWithUpdate(panel, savedPanel);
|
||||||
|
return savedPanel;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toPanelSaveModel(panel: PanelModel): any {
|
||||||
|
let panelSaveModel = panel.getSaveModel();
|
||||||
|
panelSaveModel = {
|
||||||
|
libraryPanel: {
|
||||||
|
name: panel.title,
|
||||||
|
uid: undefined,
|
||||||
|
},
|
||||||
|
...panelSaveModel,
|
||||||
|
};
|
||||||
|
|
||||||
|
return panelSaveModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePanelModelWithUpdate(panel: PanelModel, updated: LibraryPanelDTO): void {
|
||||||
|
panel.restoreModel({
|
||||||
|
...updated.model,
|
||||||
|
libraryPanel: toPanelModelLibraryPanel(updated),
|
||||||
|
});
|
||||||
|
panel.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveOrUpdateLibraryPanel(panel: any, folderId: number): Promise<LibraryPanelDTO> {
|
||||||
|
if (!panel.libraryPanel) {
|
||||||
|
return Promise.reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (panel.libraryPanel && panel.libraryPanel.uid === undefined) {
|
||||||
|
panel.libraryPanel.name = panel.title;
|
||||||
|
return addLibraryPanel(panel, folderId!);
|
||||||
|
}
|
||||||
|
|
||||||
|
return updateLibraryPanel(panel, folderId!);
|
||||||
|
}
|
@ -1,52 +1,27 @@
|
|||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
import { useDispatch } from 'react-redux';
|
||||||
import useAsyncFn from 'react-use/lib/useAsyncFn';
|
import useAsyncFn from 'react-use/lib/useAsyncFn';
|
||||||
import { AppEvents } from '@grafana/data';
|
|
||||||
import appEvents from 'app/core/app_events';
|
|
||||||
import { PanelModel } from 'app/features/dashboard/state';
|
import { PanelModel } from 'app/features/dashboard/state';
|
||||||
import { addLibraryPanel, updateLibraryPanel } from '../state/api';
|
import {
|
||||||
|
createPanelLibraryErrorNotification,
|
||||||
const saveLibraryPanels = (panel: any, folderId: number) => {
|
createPanelLibrarySuccessNotification,
|
||||||
if (!panel.libraryPanel) {
|
saveAndRefreshLibraryPanel,
|
||||||
return Promise.reject();
|
} from '../utils';
|
||||||
}
|
import { notifyApp } from 'app/core/actions';
|
||||||
|
|
||||||
if (panel.libraryPanel && panel.libraryPanel.uid === undefined) {
|
|
||||||
panel.libraryPanel.name = panel.title;
|
|
||||||
return addLibraryPanel(panel, folderId!);
|
|
||||||
}
|
|
||||||
|
|
||||||
return updateLibraryPanel(panel, folderId!);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const usePanelSave = () => {
|
export const usePanelSave = () => {
|
||||||
|
const dispatch = useDispatch();
|
||||||
const [state, saveLibraryPanel] = useAsyncFn(async (panel: PanelModel, folderId: number) => {
|
const [state, saveLibraryPanel] = useAsyncFn(async (panel: PanelModel, folderId: number) => {
|
||||||
let panelSaveModel = panel.getSaveModel();
|
return await saveAndRefreshLibraryPanel(panel, folderId);
|
||||||
panelSaveModel = {
|
|
||||||
libraryPanel: {
|
|
||||||
name: panel.title,
|
|
||||||
uid: undefined,
|
|
||||||
},
|
|
||||||
...panelSaveModel,
|
|
||||||
};
|
|
||||||
const savedPanel = await saveLibraryPanels(panelSaveModel, folderId);
|
|
||||||
panel.restoreModel({
|
|
||||||
...savedPanel.model,
|
|
||||||
libraryPanel: {
|
|
||||||
uid: savedPanel.uid,
|
|
||||||
name: savedPanel.name,
|
|
||||||
meta: savedPanel.meta,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
panel.refresh();
|
|
||||||
return savedPanel;
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (state.error) {
|
if (state.error) {
|
||||||
appEvents.emit(AppEvents.alertError, [`Error saving library panel: "${state.error.message}"`]);
|
dispatch(notifyApp(createPanelLibraryErrorNotification(`Error saving library panel: "${state.error.message}"`)));
|
||||||
}
|
}
|
||||||
if (state.value) {
|
if (state.value) {
|
||||||
appEvents.emit(AppEvents.alertSuccess, ['Library panel saved']);
|
dispatch(notifyApp(createPanelLibrarySuccessNotification('Library panel saved')));
|
||||||
}
|
}
|
||||||
}, [state]);
|
}, [state]);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user