<commit_before>import React, { useRef, useState } 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';
import { selectors } from '@grafana/e2e-selectors';
import { useAsync } from 'react-use';

interface Props {
  link: DashboardLink;
  linkInfo: { title: string; href: string };
  dashboardId: any;
}

export const DashboardLinksDashboard: React.FC<Props> = (props) => {
  const { link, linkInfo } = props;
  const listRef = useRef<HTMLUListElement>(null);
  const [opened, setOpened] = useState(0);
  const resolvedLinks = useResolvedLinks(props, opened);

  if (link.asDropdown) {
    return (
      <LinkElement link={link} key="dashlinks-dropdown" aria-label={selectors.components.DashboardLinks.dropDown}>
        <>
          <a
            onClick={() => setOpened(Date.now())}
            className="gf-form-label gf-form-label--dashlink"
            data-placement="bottom"
            data-toggle="dropdown"
          >
            <Icon name="bars" style={{ marginRight: '4px' }} />
            <span>{linkInfo.title}</span>
          </a>
          <ul className={`dropdown-menu ${getDropdownLocationCssClass(listRef.current)}`} role="menu" ref={listRef}>
            {resolvedLinks.length > 0 &&
              resolvedLinks.map((resolvedLink, index) => {
                return (
                  <li key={`dashlinks-dropdown-item-${resolvedLink.id}-${index}`}>
                    <a
                      href={resolvedLink.url}
                      target={link.targetBlank ? '_blank' : undefined}
                      rel="noreferrer"
                      aria-label={selectors.components.DashboardLinks.link}
                    >
                      {resolvedLink.title}
                    </a>
                  </li>
                );<commit_msg>DashboardLinks: Fix dropdown positioning (#34909)<commit_after>import React, { useRef, useState, useLayoutEffect } 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';
import { selectors } from '@grafana/e2e-selectors';
import { useAsync } from 'react-use';

interface Props {
  link: DashboardLink;
  linkInfo: { title: string; href: string };
  dashboardId: any;
}

export const DashboardLinksDashboard: React.FC<Props> = (props) => {
  const { link, linkInfo } = props;
  const listRef = useRef<HTMLUListElement>(null);
  const [dropdownCssClass, setDropdownCssClass] = useState('invisible');
  const [opened, setOpened] = useState(0);
  const resolvedLinks = useResolvedLinks(props, opened);

  useLayoutEffect(() => {
    setDropdownCssClass(getDropdownLocationCssClass(listRef.current));
  }, [resolvedLinks]);

  if (link.asDropdown) {
    return (
      <LinkElement link={link} key="dashlinks-dropdown" aria-label={selectors.components.DashboardLinks.dropDown}>
        <>
          <a
            onClick={() => setOpened(Date.now())}
            className="gf-form-label gf-form-label--dashlink"
            data-placement="bottom"
            data-toggle="dropdown"
          >
            <Icon name="bars" style={{ marginRight: '4px' }} />
            <span>{linkInfo.title}</span>
          </a>
          <ul className={`dropdown-menu ${dropdownCssClass}`} role="menu" ref={listRef}>
            {resolvedLinks.length > 0 &&
              resolvedLinks.map((resolvedLink, index) => {
                return (
                  <li key={`dashlinks-dropdown-item-${resolvedLink.id}-${index}`}>
                    <a
                      href={resolvedLink.url}
                      target={link.targetBlank ? '_blank' : undefined}
                      rel="noreferrer"
                      aria-label={selectors.components.DashboardLinks.link}
                    >
                      {resolvedLink.title}
                    </a>
                  </li>
                );
{'fraction_non_alphanumeric': 0.141439205955335, 'fraction_numerical': 0.002932551319648094, 'mean_word_length': 2.374429223744292, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2279399', 'n_tokens_mistral': 1296, 'n_tokens_neox': 1282, 'n_words': 240}