2021-03-02 16:37:36 +01:00
|
|
|
import React, { useState } from 'react';
|
|
|
|
|
import { css } from 'emotion';
|
|
|
|
|
import pick from 'lodash/pick';
|
2021-03-04 13:17:57 +00:00
|
|
|
import omit from 'lodash/omit';
|
2021-02-25 10:26:28 +00:00
|
|
|
import { GrafanaTheme } from '@grafana/data';
|
|
|
|
|
import { Button, stylesFactory, useStyles } from '@grafana/ui';
|
2021-03-02 16:37:36 +01:00
|
|
|
|
2021-02-25 10:26:28 +00:00
|
|
|
import { OptionsGroup } from 'app/features/dashboard/components/PanelEditor/OptionsGroup';
|
|
|
|
|
import { DashboardModel, PanelModel } from 'app/features/dashboard/state';
|
|
|
|
|
import { AddLibraryPanelModal } from '../AddLibraryPanelModal/AddLibraryPanelModal';
|
|
|
|
|
import { LibraryPanelsView } from '../LibraryPanelsView/LibraryPanelsView';
|
|
|
|
|
import { PanelQueriesChangedEvent } from 'app/types/events';
|
2021-03-02 16:37:36 +01:00
|
|
|
import { LibraryPanelDTO } from '../../types';
|
|
|
|
|
import { toPanelModelLibraryPanel } from '../../utils';
|
2021-03-04 13:17:57 +00:00
|
|
|
import { useDispatch } from 'react-redux';
|
|
|
|
|
import { changePanelPlugin } from 'app/features/dashboard/state/actions';
|
2021-02-25 10:26:28 +00:00
|
|
|
|
|
|
|
|
interface Props {
|
|
|
|
|
panel: PanelModel;
|
|
|
|
|
dashboard: DashboardModel;
|
2021-03-04 13:17:57 +00:00
|
|
|
onChange: () => void;
|
2021-02-25 10:26:28 +00:00
|
|
|
}
|
|
|
|
|
|
2021-03-04 13:17:57 +00:00
|
|
|
export const PanelLibraryOptionsGroup: React.FC<Props> = ({ panel, dashboard, onChange }) => {
|
2021-02-25 10:26:28 +00:00
|
|
|
const styles = useStyles(getStyles);
|
|
|
|
|
const [showingAddPanelModal, setShowingAddPanelModal] = useState(false);
|
2021-03-04 13:17:57 +00:00
|
|
|
const dispatch = useDispatch();
|
2021-02-25 10:26:28 +00:00
|
|
|
|
|
|
|
|
const useLibraryPanel = (panelInfo: LibraryPanelDTO) => {
|
2021-03-04 13:17:57 +00:00
|
|
|
const panelTypeChanged = panel.type !== panelInfo.model.type;
|
2021-02-25 10:26:28 +00:00
|
|
|
panel.restoreModel({
|
2021-03-04 13:17:57 +00:00
|
|
|
...omit(panelInfo.model, 'type'),
|
2021-02-25 10:26:28 +00:00
|
|
|
...pick(panel, 'gridPos', 'id'),
|
2021-03-02 16:37:36 +01:00
|
|
|
libraryPanel: toPanelModelLibraryPanel(panelInfo),
|
2021-02-25 10:26:28 +00:00
|
|
|
});
|
|
|
|
|
|
2021-03-04 13:17:57 +00:00
|
|
|
if (panelTypeChanged) {
|
|
|
|
|
dispatch(changePanelPlugin(panel, panelInfo.model.type));
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-03 14:16:54 +00:00
|
|
|
// Though the panel model has changed, since we're switching to an existing
|
|
|
|
|
// library panel, we reset the "hasChanged" state.
|
|
|
|
|
panel.hasChanged = false;
|
2021-02-25 10:26:28 +00:00
|
|
|
panel.refresh();
|
|
|
|
|
panel.events.publish(PanelQueriesChangedEvent);
|
2021-03-04 13:17:57 +00:00
|
|
|
|
|
|
|
|
// onChange is called here to force the panel editor to re-render
|
|
|
|
|
onChange();
|
2021-02-25 10:26:28 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onAddToPanelLibrary = (e: React.MouseEvent) => {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
e.stopPropagation();
|
|
|
|
|
|
|
|
|
|
setShowingAddPanelModal(true);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<OptionsGroup
|
|
|
|
|
renderTitle={(isExpanded) => {
|
|
|
|
|
return isExpanded && !panel.libraryPanel ? (
|
|
|
|
|
<div className={styles.panelLibraryTitle}>
|
|
|
|
|
<span>Panel library</span>
|
|
|
|
|
<Button size="sm" onClick={onAddToPanelLibrary}>
|
|
|
|
|
Add this panel to the panel library
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
'Panel library'
|
|
|
|
|
);
|
|
|
|
|
}}
|
|
|
|
|
id="panel-library"
|
|
|
|
|
key="panel-library"
|
|
|
|
|
defaultToClosed
|
|
|
|
|
>
|
|
|
|
|
<LibraryPanelsView
|
|
|
|
|
formatDate={(dateString: string) => dashboard.formatDate(dateString, 'L')}
|
2021-02-25 13:20:02 +00:00
|
|
|
currentPanelId={panel.libraryPanel?.uid}
|
2021-02-25 10:26:28 +00:00
|
|
|
showSecondaryActions
|
|
|
|
|
>
|
|
|
|
|
{(panel) => (
|
|
|
|
|
<Button variant="secondary" onClick={() => useLibraryPanel(panel)}>
|
|
|
|
|
Use instead of current panel
|
|
|
|
|
</Button>
|
|
|
|
|
)}
|
|
|
|
|
</LibraryPanelsView>
|
|
|
|
|
{showingAddPanelModal && (
|
|
|
|
|
<AddLibraryPanelModal
|
|
|
|
|
panel={panel}
|
|
|
|
|
onDismiss={() => setShowingAddPanelModal(false)}
|
|
|
|
|
initialFolderId={dashboard.meta.folderId}
|
|
|
|
|
isOpen={showingAddPanelModal}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</OptionsGroup>
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getStyles = stylesFactory((theme: GrafanaTheme) => {
|
|
|
|
|
return {
|
|
|
|
|
panelLibraryTitle: css`
|
|
|
|
|
display: flex;
|
|
|
|
|
gap: 10px;
|
|
|
|
|
`,
|
|
|
|
|
};
|
|
|
|
|
});
|