grafana/public/app/features/library-panels/components/PanelLibraryOptionsGroup/PanelLibraryOptionsGroup.tsx
Torkel Ödegaard d62ca1283c
PanelState: Introduce a new separate redux panel state not keyed by panel.id (#40302)
* Initial pass to move panel state to it's own, and make it by key not panel.id

* Progress

* Not making much progress, having panel.key be mutable is causing a lot of issues

* Think this is starting to work

* Began fixing tests

* Add selector

* Bug fixes and changes to cleanup, and fixing all flicking when switching library panels

* Removed console.log

* fixes after merge

* fixing tests

* fixing tests

* Added new test for changePlugin thunk
2021-10-13 08:53:36 +02:00

102 lines
3.1 KiB
TypeScript

import React, { FC, useCallback, useState } from 'react';
import { useDispatch } from 'react-redux';
import { css } from '@emotion/css';
import { GrafanaTheme2, PanelPluginMeta } from '@grafana/data';
import { Button, useStyles2, VerticalGroup } from '@grafana/ui';
import { PanelModel } from 'app/features/dashboard/state';
import { AddLibraryPanelModal } from '../AddLibraryPanelModal/AddLibraryPanelModal';
import { LibraryPanelsView } from '../LibraryPanelsView/LibraryPanelsView';
import { LibraryElementDTO } from '../../types';
import { changeToLibraryPanel } from 'app/features/panel/state/actions';
import { getDashboardSrv } from 'app/features/dashboard/services/DashboardSrv';
import { ChangeLibraryPanelModal } from '../ChangeLibraryPanelModal/ChangeLibraryPanelModal';
import { PanelTypeFilter } from '../../../../core/components/PanelTypeFilter/PanelTypeFilter';
interface Props {
panel: PanelModel;
searchQuery: string;
}
export const PanelLibraryOptionsGroup: FC<Props> = ({ panel, searchQuery }) => {
const styles = useStyles2(getStyles);
const [showingAddPanelModal, setShowingAddPanelModal] = useState(false);
const [changeToPanel, setChangeToPanel] = useState<LibraryElementDTO | undefined>(undefined);
const [panelFilter, setPanelFilter] = useState<string[]>([]);
const onPanelFilterChange = useCallback(
(plugins: PanelPluginMeta[]) => {
setPanelFilter(plugins.map((p) => p.id));
},
[setPanelFilter]
);
const dashboard = getDashboardSrv().getCurrent();
const dispatch = useDispatch();
const useLibraryPanel = async () => {
if (!changeToPanel) {
return;
}
setChangeToPanel(undefined);
dispatch(changeToLibraryPanel(panel, changeToPanel));
};
const onAddToPanelLibrary = () => {
setShowingAddPanelModal(true);
};
const onChangeLibraryPanel = (panel: LibraryElementDTO) => {
setChangeToPanel(panel);
};
const onDismissChangeToPanel = () => {
setChangeToPanel(undefined);
};
return (
<VerticalGroup spacing="md">
{!panel.libraryPanel && (
<VerticalGroup align="center">
<Button icon="plus" onClick={onAddToPanelLibrary} variant="secondary" fullWidth>
Create new library panel
</Button>
</VerticalGroup>
)}
<PanelTypeFilter onChange={onPanelFilterChange} />
<div className={styles.libraryPanelsView}>
<LibraryPanelsView
currentPanelId={panel.libraryPanel?.uid}
searchString={searchQuery}
panelFilter={panelFilter}
onClickCard={onChangeLibraryPanel}
showSecondaryActions
/>
</div>
{showingAddPanelModal && (
<AddLibraryPanelModal
panel={panel}
onDismiss={() => setShowingAddPanelModal(false)}
initialFolderId={dashboard?.meta.folderId}
isOpen={showingAddPanelModal}
/>
)}
{changeToPanel && (
<ChangeLibraryPanelModal panel={panel} onDismiss={onDismissChangeToPanel} onConfirm={useLibraryPanel} />
)}
</VerticalGroup>
);
};
const getStyles = (theme: GrafanaTheme2) => {
return {
libraryPanelsView: css`
width: 100%;
`,
};
};