mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Dashboard/Links: Fixes dashboard links by tags not working (#24773)
* Fixes dashboard links by tags not working * removes code duplication
This commit is contained in:
parent
793299af14
commit
e2368e623e
@ -1,7 +1,7 @@
|
|||||||
import React, { FC } from 'react';
|
import React, { FC } from 'react';
|
||||||
import { Icon, IconName, Tooltip } from '@grafana/ui';
|
import { Icon, IconName, Tooltip } from '@grafana/ui';
|
||||||
import { sanitize, sanitizeUrl } from '@grafana/data/src/text/sanitize';
|
import { sanitize, sanitizeUrl } from '@grafana/data/src/text/sanitize';
|
||||||
import { DashboardsDropdown } from './DashboardsDropdown';
|
import { DashboardLinksDashboard } from './DashboardLinksDashboard';
|
||||||
import { getLinkSrv } from '../../../panel/panellinks/link_srv';
|
import { getLinkSrv } from '../../../panel/panellinks/link_srv';
|
||||||
|
|
||||||
import { DashboardModel } from '../../state';
|
import { DashboardModel } from '../../state';
|
||||||
@ -20,8 +20,8 @@ export const DashboardLinks: FC<Props> = ({ dashboard }) => {
|
|||||||
const linkInfo = getLinkSrv().getAnchorInfo(link);
|
const linkInfo = getLinkSrv().getAnchorInfo(link);
|
||||||
const key = `${link.title}-$${index}`;
|
const key = `${link.title}-$${index}`;
|
||||||
|
|
||||||
if (link.asDropdown) {
|
if (link.type === 'dashboards') {
|
||||||
return <DashboardsDropdown key={key} link={link} linkInfo={linkInfo} dashboardId={dashboard.id} />;
|
return <DashboardLinksDashboard key={key} link={link} linkInfo={linkInfo} dashboardId={dashboard.id} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
const linkElement = (
|
const linkElement = (
|
||||||
@ -30,7 +30,7 @@ export const DashboardLinks: FC<Props> = ({ dashboard }) => {
|
|||||||
href={sanitizeUrl(linkInfo.href)}
|
href={sanitizeUrl(linkInfo.href)}
|
||||||
target={link.targetBlank ? '_blank' : '_self'}
|
target={link.targetBlank ? '_blank' : '_self'}
|
||||||
>
|
>
|
||||||
<Icon name={iconMap[link.icon] as IconName} />
|
<Icon name={iconMap[link.icon] as IconName} style={{ marginRight: '4px' }} />
|
||||||
<span>{sanitize(linkInfo.title)}</span>
|
<span>{sanitize(linkInfo.title)}</span>
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,128 @@
|
|||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import { Icon, Tooltip } from '@grafana/ui';
|
||||||
|
import { sanitize, sanitizeUrl } from '@grafana/data/src/text/sanitize';
|
||||||
|
import { getBackendSrv } from 'app/core/services/backend_srv';
|
||||||
|
import { getLinkSrv } from '../../../panel/panellinks/link_srv';
|
||||||
|
import { DashboardLink } from '../../state/DashboardModel';
|
||||||
|
import { DashboardSearchHit } from 'app/features/search/types';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
link: DashboardLink;
|
||||||
|
linkInfo: { title: string; href: string };
|
||||||
|
dashboardId: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
searchHits: DashboardSearchHit[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export class DashboardLinksDashboard extends PureComponent<Props, State> {
|
||||||
|
state = { searchHits: [] as DashboardSearchHit[] };
|
||||||
|
componentDidMount() {
|
||||||
|
if (!this.props.link.asDropdown) {
|
||||||
|
this.onDropDownClick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onDropDownClick = () => {
|
||||||
|
const { dashboardId, link } = this.props;
|
||||||
|
|
||||||
|
const limit = 7;
|
||||||
|
getBackendSrv()
|
||||||
|
.search({ tag: link.tags, limit })
|
||||||
|
.then((dashboards: DashboardSearchHit[]) => {
|
||||||
|
const processed = dashboards
|
||||||
|
.filter(dash => dash.id !== dashboardId)
|
||||||
|
.map(dash => {
|
||||||
|
return {
|
||||||
|
...dash,
|
||||||
|
url: getLinkSrv().getLinkUrl(dash),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
searchHits: processed,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
renderElement = (linkElement: JSX.Element) => {
|
||||||
|
const { link } = this.props;
|
||||||
|
|
||||||
|
if (link.tooltip) {
|
||||||
|
return (
|
||||||
|
<div className="gf-form">
|
||||||
|
<Tooltip content={link.tooltip}>{linkElement}</Tooltip>;
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return <div className="gf-form">{linkElement}</div>;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
renderList = () => {
|
||||||
|
const { link } = this.props;
|
||||||
|
const { searchHits } = this.state;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{searchHits.length > 0 &&
|
||||||
|
searchHits.map((dashboard: any, index: number) => {
|
||||||
|
const linkElement = (
|
||||||
|
<a
|
||||||
|
key={`${dashboard.id}-${index}`}
|
||||||
|
className="gf-form-label"
|
||||||
|
href={sanitizeUrl(dashboard.url)}
|
||||||
|
target={link.targetBlank ? '_blank' : '_self'}
|
||||||
|
>
|
||||||
|
<Icon name="apps" style={{ marginRight: '4px' }} />
|
||||||
|
<span>{sanitize(dashboard.title)}</span>
|
||||||
|
</a>
|
||||||
|
);
|
||||||
|
return this.renderElement(linkElement);
|
||||||
|
})}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
renderDropdown = () => {
|
||||||
|
const { link, linkInfo } = this.props;
|
||||||
|
const { searchHits } = this.state;
|
||||||
|
|
||||||
|
const linkElement = (
|
||||||
|
<>
|
||||||
|
<a
|
||||||
|
className="gf-form-label pointer"
|
||||||
|
onClick={this.onDropDownClick}
|
||||||
|
data-placement="bottom"
|
||||||
|
data-toggle="dropdown"
|
||||||
|
>
|
||||||
|
<Icon name="bars" />
|
||||||
|
<span>{linkInfo.title}</span>
|
||||||
|
</a>
|
||||||
|
<ul className="dropdown-menu pull-right" role="menu">
|
||||||
|
{searchHits.length > 0 &&
|
||||||
|
searchHits.map((dashboard: any, index: number) => {
|
||||||
|
return (
|
||||||
|
<li key={`${dashboard.id}-${index}`}>
|
||||||
|
<a href={sanitizeUrl(dashboard.url)} target={link.targetBlank ? '_blank' : '_self'}>
|
||||||
|
{sanitize(dashboard.title)}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
return this.renderElement(linkElement);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (this.props.link.asDropdown) {
|
||||||
|
return this.renderDropdown();
|
||||||
|
} else {
|
||||||
|
return this.renderList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,71 +0,0 @@
|
|||||||
import React, { PureComponent } from 'react';
|
|
||||||
import { Icon } from '@grafana/ui';
|
|
||||||
import { sanitize, sanitizeUrl } from '@grafana/data/src/text/sanitize';
|
|
||||||
import { getBackendSrv } from 'app/core/services/backend_srv';
|
|
||||||
import { DashboardSearchHit } from 'app/features/search/types';
|
|
||||||
import { getLinkSrv } from '../../../panel/panellinks/link_srv';
|
|
||||||
import { DashboardLink } from '../../state/DashboardModel';
|
|
||||||
|
|
||||||
interface Props {
|
|
||||||
link: DashboardLink;
|
|
||||||
linkInfo: { title: string; href: string };
|
|
||||||
dashboardId: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface State {
|
|
||||||
searchHits: DashboardSearchHit[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export class DashboardsDropdown extends PureComponent<Props, State> {
|
|
||||||
state = { searchHits: [] as DashboardSearchHit[] };
|
|
||||||
onDropDownClick = async () => {
|
|
||||||
const { dashboardId, link } = this.props;
|
|
||||||
|
|
||||||
const limit = 7;
|
|
||||||
const dashboards = await getBackendSrv().search({ tag: link.tags, limit });
|
|
||||||
const processed = dashboards
|
|
||||||
.filter(dash => dash.id !== dashboardId)
|
|
||||||
.map(dash => {
|
|
||||||
return {
|
|
||||||
...dash,
|
|
||||||
url: getLinkSrv().getLinkUrl(dash),
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
searchHits: processed,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { link, linkInfo } = this.props;
|
|
||||||
const { searchHits } = this.state;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="gf-form">
|
|
||||||
<a
|
|
||||||
className="gf-form-label pointer"
|
|
||||||
target={link.targetBlank ? '_blank' : '_self'}
|
|
||||||
onClick={this.onDropDownClick}
|
|
||||||
data-placement="bottom"
|
|
||||||
data-toggle="dropdown"
|
|
||||||
>
|
|
||||||
<Icon name="bars" />
|
|
||||||
<span>{linkInfo.title}</span>
|
|
||||||
</a>
|
|
||||||
<ul className="dropdown-menu pull-right" role="menu">
|
|
||||||
{searchHits.length > 1 &&
|
|
||||||
searchHits.map((dashboard: any, index: number) => {
|
|
||||||
return (
|
|
||||||
<li key={`${dashboard.id}-${index}`}>
|
|
||||||
<a href={sanitizeUrl(dashboard.url)} target={dashboard.target}>
|
|
||||||
{sanitize(dashboard.title)}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user