* update eslint, tsconfig + esbuild to handle new jsx transform * remove thing that breaks the new jsx transform * remove react imports * adjust grafana-icons build * is this the correct syntax? * try this * well this was much easier than expected... * change grafana-plugin-configs webpack config * fixes * fix lockfile * fix 2 more violations * use path.resolve instead of require.resolve * remove react import * fix react imports * more fixes * remove React import * remove import React from docs * remove another react import
86 lines
2.5 KiB
TypeScript
86 lines
2.5 KiB
TypeScript
import { css } from '@emotion/css';
|
|
import { useMemo, useState } from 'react';
|
|
|
|
import { GrafanaTheme2, PanelPluginMeta } from '@grafana/data';
|
|
import { locationService } from '@grafana/runtime';
|
|
import { CustomScrollbar, Icon, Input, Modal, useStyles2 } from '@grafana/ui';
|
|
import { onCreateNewWidgetPanel } from 'app/features/dashboard/utils/dashboard';
|
|
import { VizTypePickerPlugin } from 'app/features/panel/components/VizTypePicker/VizTypePickerPlugin';
|
|
import { filterPluginList, getWidgetPluginMeta } from 'app/features/panel/state/util';
|
|
import { useSelector } from 'app/types';
|
|
|
|
export const AddWidgetModal = () => {
|
|
const styles = useStyles2(getStyles);
|
|
const [searchQuery, setSearchQuery] = useState('');
|
|
const dashboard = useSelector((state) => state.dashboard.getModel());
|
|
|
|
const widgetsList: PanelPluginMeta[] = useMemo(() => {
|
|
return getWidgetPluginMeta();
|
|
}, []);
|
|
|
|
const filteredWidgetsTypes = useMemo((): PanelPluginMeta[] => {
|
|
return filterPluginList(widgetsList, searchQuery);
|
|
}, [widgetsList, searchQuery]);
|
|
|
|
const onDismiss = () => {
|
|
locationService.partial({ addWidget: null });
|
|
};
|
|
|
|
return (
|
|
<Modal
|
|
title="Select widget type"
|
|
closeOnEscape
|
|
closeOnBackdropClick
|
|
isOpen
|
|
className={styles.modal}
|
|
onClickBackdrop={onDismiss}
|
|
onDismiss={onDismiss}
|
|
>
|
|
<Input
|
|
type="search"
|
|
autoFocus
|
|
className={styles.searchInput}
|
|
value={searchQuery}
|
|
prefix={<Icon name="search" />}
|
|
placeholder="Search widget"
|
|
onChange={(e) => {
|
|
setSearchQuery(e.currentTarget.value);
|
|
}}
|
|
/>
|
|
<CustomScrollbar>
|
|
<div className={styles.grid}>
|
|
{filteredWidgetsTypes.map((plugin, index) => (
|
|
<VizTypePickerPlugin
|
|
disabled={false}
|
|
key={plugin.id}
|
|
isCurrent={false}
|
|
plugin={plugin}
|
|
onClick={(e) => {
|
|
const id = onCreateNewWidgetPanel(dashboard!, plugin.id);
|
|
locationService.partial({ editPanel: id, addWidget: null });
|
|
}}
|
|
/>
|
|
))}
|
|
</div>
|
|
</CustomScrollbar>
|
|
</Modal>
|
|
);
|
|
};
|
|
|
|
const getStyles = (theme: GrafanaTheme2) => ({
|
|
modal: css({
|
|
width: '65%',
|
|
maxWidth: '960px',
|
|
[theme.breakpoints.down('md')]: {
|
|
width: '100%',
|
|
},
|
|
}),
|
|
searchInput: css({
|
|
marginBottom: theme.spacing(2),
|
|
}),
|
|
grid: css({
|
|
display: 'grid',
|
|
gridGap: theme.spacing(1),
|
|
}),
|
|
});
|