mirror of
https://github.com/grafana/grafana.git
synced 2025-08-01 18:13:09 +08:00
DashboardLinks: do not over-query search endpoint (#26311)
* DashboardLinks: WIP fix for dashboard links issue * Make the dashboard links update on change(hacky) * Replace dashboard links with new array when updating/adding dash links * Update snaps * Deep clone dashboard links on save Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
This commit is contained in:
@ -54,7 +54,7 @@ export class DashLinksEditorCtrl {
|
|||||||
};
|
};
|
||||||
|
|
||||||
addLink() {
|
addLink() {
|
||||||
this.dashboard.links.push(this.link);
|
this.dashboard.links = [...this.dashboard.links, this.link];
|
||||||
this.mode = 'list';
|
this.mode = 'list';
|
||||||
this.dashboard.updateSubmenuVisibility();
|
this.dashboard.updateSubmenuVisibility();
|
||||||
}
|
}
|
||||||
@ -65,6 +65,7 @@ export class DashLinksEditorCtrl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
saveLink() {
|
saveLink() {
|
||||||
|
this.dashboard.links = _.cloneDeep(this.dashboard.links);
|
||||||
this.backToList();
|
this.backToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,16 +10,17 @@ import { iconMap } from '../DashLinks/DashLinksEditorCtrl';
|
|||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
dashboard: DashboardModel;
|
dashboard: DashboardModel;
|
||||||
|
links: DashboardLink[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DashboardLinks: FC<Props> = ({ dashboard }) => {
|
export const DashboardLinks: FC<Props> = ({ dashboard, links }) => {
|
||||||
if (!dashboard.links.length) {
|
if (!links.length) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{dashboard.links.map((link: DashboardLink, index: number) => {
|
{links.map((link: DashboardLink, index: number) => {
|
||||||
const linkInfo = getLinkSrv().getAnchorInfo(link);
|
const linkInfo = getLinkSrv().getAnchorInfo(link);
|
||||||
const key = `${link.title}-$${index}`;
|
const key = `${link.title}-$${index}`;
|
||||||
|
|
||||||
|
@ -19,13 +19,17 @@ interface State {
|
|||||||
export class DashboardLinksDashboard extends PureComponent<Props, State> {
|
export class DashboardLinksDashboard extends PureComponent<Props, State> {
|
||||||
state: State = { resolvedLinks: [] };
|
state: State = { resolvedLinks: [] };
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.searchForDashboards();
|
||||||
|
}
|
||||||
|
|
||||||
componentDidUpdate(prevProps: Readonly<Props>) {
|
componentDidUpdate(prevProps: Readonly<Props>) {
|
||||||
if (!this.props.link.asDropdown && prevProps.linkInfo !== this.props.linkInfo) {
|
if (this.props.link !== prevProps.link) {
|
||||||
this.onResolveLinks();
|
this.searchForDashboards();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onResolveLinks = async () => {
|
searchForDashboards = async () => {
|
||||||
const { dashboardId, link } = this.props;
|
const { dashboardId, link } = this.props;
|
||||||
|
|
||||||
const searchHits = await searchForTags(link);
|
const searchHits = await searchForTags(link);
|
||||||
@ -73,7 +77,7 @@ export class DashboardLinksDashboard extends PureComponent<Props, State> {
|
|||||||
<>
|
<>
|
||||||
<a
|
<a
|
||||||
className="gf-form-label pointer"
|
className="gf-form-label pointer"
|
||||||
onClick={this.onResolveLinks}
|
onClick={this.searchForDashboards}
|
||||||
data-placement="bottom"
|
data-placement="bottom"
|
||||||
data-toggle="dropdown"
|
data-toggle="dropdown"
|
||||||
>
|
>
|
||||||
|
@ -7,9 +7,11 @@ import { DashboardModel } from '../../state';
|
|||||||
import { DashboardLinks } from './DashboardLinks';
|
import { DashboardLinks } from './DashboardLinks';
|
||||||
import { Annotations } from './Annotations';
|
import { Annotations } from './Annotations';
|
||||||
import { SubMenuItems } from './SubMenuItems';
|
import { SubMenuItems } from './SubMenuItems';
|
||||||
|
import { DashboardLink } from '../../state/DashboardModel';
|
||||||
|
|
||||||
interface OwnProps {
|
interface OwnProps {
|
||||||
dashboard: DashboardModel;
|
dashboard: DashboardModel;
|
||||||
|
links: DashboardLink[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ConnectedProps {
|
interface ConnectedProps {
|
||||||
@ -49,7 +51,8 @@ class SubMenuUnConnected extends PureComponent<Props> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { dashboard, variables } = this.props;
|
const { dashboard, variables, links } = this.props;
|
||||||
|
|
||||||
if (!this.isSubMenuVisible()) {
|
if (!this.isSubMenuVisible()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -59,16 +62,18 @@ class SubMenuUnConnected extends PureComponent<Props> {
|
|||||||
<SubMenuItems variables={variables} />
|
<SubMenuItems variables={variables} />
|
||||||
<Annotations annotations={dashboard.annotations.list} onAnnotationChanged={this.onAnnotationStateChanged} />
|
<Annotations annotations={dashboard.annotations.list} onAnnotationChanged={this.onAnnotationStateChanged} />
|
||||||
<div className="gf-form gf-form--grow" />
|
<div className="gf-form gf-form--grow" />
|
||||||
{dashboard && <DashboardLinks dashboard={dashboard} />}
|
{dashboard && <DashboardLinks dashboard={dashboard} links={links} />}
|
||||||
<div className="clearfix" />
|
<div className="clearfix" />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const mapStateToProps: MapStateToProps<ConnectedProps, OwnProps, StoreState> = state => ({
|
const mapStateToProps: MapStateToProps<ConnectedProps, OwnProps, StoreState> = state => {
|
||||||
variables: getSubMenuVariables(state),
|
return {
|
||||||
});
|
variables: getSubMenuVariables(state.templating.variables),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export const SubMenu = connect(mapStateToProps)(SubMenuUnConnected);
|
export const SubMenu = connect(mapStateToProps)(SubMenuUnConnected);
|
||||||
SubMenu.displayName = 'SubMenu';
|
SubMenu.displayName = 'SubMenu';
|
||||||
|
@ -309,7 +309,7 @@ export class DashboardPage extends PureComponent<Props, State> {
|
|||||||
>
|
>
|
||||||
<div className="dashboard-content">
|
<div className="dashboard-content">
|
||||||
{initError && this.renderInitFailedState()}
|
{initError && this.renderInitFailedState()}
|
||||||
{!editPanel && <SubMenu dashboard={dashboard} />}
|
{!editPanel && <SubMenu dashboard={dashboard} links={dashboard.links} />}
|
||||||
|
|
||||||
<DashboardGrid
|
<DashboardGrid
|
||||||
dashboard={dashboard}
|
dashboard={dashboard}
|
||||||
|
@ -211,6 +211,7 @@ exports[`DashboardPage Dashboard init completed Should render dashboard grid 1`
|
|||||||
"version": 0,
|
"version": 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
links={Array []}
|
||||||
/>
|
/>
|
||||||
<DashboardGrid
|
<DashboardGrid
|
||||||
dashboard={
|
dashboard={
|
||||||
@ -569,6 +570,7 @@ exports[`DashboardPage When dashboard has editview url state should render setti
|
|||||||
"version": 0,
|
"version": 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
links={Array []}
|
||||||
/>
|
/>
|
||||||
<DashboardGrid
|
<DashboardGrid
|
||||||
dashboard={
|
dashboard={
|
||||||
|
@ -2,6 +2,7 @@ import { StoreState } from '../../../types';
|
|||||||
import { VariableModel } from '../types';
|
import { VariableModel } from '../types';
|
||||||
import { getState } from '../../../store/store';
|
import { getState } from '../../../store/store';
|
||||||
import { NEW_VARIABLE_ID } from './types';
|
import { NEW_VARIABLE_ID } from './types';
|
||||||
|
import memoizeOne from 'memoize-one';
|
||||||
|
|
||||||
export const getVariable = <T extends VariableModel = VariableModel>(
|
export const getVariable = <T extends VariableModel = VariableModel>(
|
||||||
id: string,
|
id: string,
|
||||||
@ -42,9 +43,9 @@ export const getVariables = (state: StoreState = getState(), includeNewVariable
|
|||||||
return getFilteredVariables(filter, state);
|
return getFilteredVariables(filter, state);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getSubMenuVariables = (state: StoreState): VariableModel[] => {
|
export const getSubMenuVariables = memoizeOne((variables: Record<string, VariableModel>): VariableModel[] => {
|
||||||
return getVariables(state);
|
return getVariables(getState());
|
||||||
};
|
});
|
||||||
|
|
||||||
export const getEditorVariables = (state: StoreState): VariableModel[] => {
|
export const getEditorVariables = (state: StoreState): VariableModel[] => {
|
||||||
return getVariables(state, true);
|
return getVariables(state, true);
|
||||||
|
Reference in New Issue
Block a user