<commit_before>import { FilterOutlined } from "@ant-design/icons";
import { Button, Dropdown, Menu, Select } from "antd";
import React, { useMemo } from "react";
import {
  fetchMetadataTemplateFieldsThunk,
  selectAllTerms,
  setFieldVisibility,
} from "../../redux/treeSlice";
import { useAppDispatch, useAppSelector } from "../../store";
import { MetadataFieldSelect } from "./MetadataFieldToggle";
import { MetadataSelectAll } from "./MetadataSelectAll";
const { Option } = Select;

/**
 * React component to display a drop-down menu for selecting the metadata that
 * is displayed with the tree.
 */
export function MetadataMenu(): JSX.Element {
  const { templates, terms, treeProps } = useAppSelector((state) => state.tree);
  const dispatch = useAppDispatch();
  const width = 300;

  const metadataTemplateOptions: JSX.Element[] = useMemo(() => {
    const options = templates.map((template, index) => (
      <Option
        className="t-template-field"
        key={`template-${template.id}`}
        value={index}
      >
        {template.label}
      </Option>
    ));

    options.unshift(
      <Option key="template-default" value={-1}>
        {i18n("visualization.phylogenomics.select-template.all-field")}
      </Option>
    );

    return options;
  }, [templates]);

  const allFieldsSelected: boolean = useMemo(
    () =>
      JSON.stringify(terms.slice().sort()) ===
      JSON.stringify(treeProps.blocks.slice().sort()),
    [terms, treeProps.blocks]
  );

  const menu = (
    <Menu className="t-metadata-dd">
      <Menu.Item key="templates">
        <Select
          className="t-metadata-select"
          defaultValue={-1}
          style={{ width }}
          onChange={(templateIdx) =>
            dispatch(fetchMetadataTemplateFieldsThunk(templateIdx))
          }
          onClick={(e) => e.stopPropagation()}
        >
          {metadataTemplateOptions}
        </Select>
      </Menu.Item>
      {terms.length > 0 ? (
        <Menu.Item key="select-all-fields" className="t-fields-all">
          <MetadataSelectAll
            checked={allFieldsSelected}
            onChange={(checked: boolean) =>
              dispatch(selectAllTerms({ checked }))
            }
          />
        </Menu.Item>
      ) : null}
      {terms.map((field) => (
        <Menu.Item key={field}>
          <MetadataFieldSelect
            checked={treeProps.blocks.includes(field)}
            field={field}
            width={width}
            onChange={(visible, only) =>
              dispatch(setFieldVisibility({ field, visible, only }))
            }
          />
        </Menu.Item>
      ))}
    </Menu>
  );

  return (
    <Dropdown overlay={menu} placement="bottomRight" trigger={["click"]}>
      <Button
        title={i18n("PhylocanvasShapeDropDown.metadata.tooltip")}
        shape="circle"
        icon={<FilterOutlined />}
      />
    </Dropdown>
  );
}
<commit_msg>fix: Hide metadata menu if no metadata exists on the samples<commit_after>import { FilterOutlined } from "@ant-design/icons";
import { Button, Dropdown, Menu, Select } from "antd";
import React, { useMemo } from "react";
import {
  fetchMetadataTemplateFieldsThunk,
  selectAllTerms,
  setFieldVisibility,
} from "../../redux/treeSlice";
import { useAppDispatch, useAppSelector } from "../../store";
import { MetadataFieldSelect } from "./MetadataFieldToggle";
import { MetadataSelectAll } from "./MetadataSelectAll";
const { Option } = Select;

/**
 * React component to display a drop-down menu for selecting the metadata that
 * is displayed with the tree.
 */
export function MetadataMenu(): JSX.Element {
  const { templates, terms, treeProps } = useAppSelector((state) => state.tree);
  const dispatch = useAppDispatch();
  const width = 300;

  const metadataTemplateOptions: JSX.Element[] = useMemo(() => {
    const options = templates.map((template, index) => (
      <Option
        className="t-template-field"
        key={`template-${template.id}`}
        value={index}
      >
        {template.label}
      </Option>
    ));

    options.unshift(
      <Option key="template-default" value={-1}>
        {i18n("visualization.phylogenomics.select-template.all-field")}
      </Option>
    );

    return options;
  }, [templates]);

  const allFieldsSelected: boolean = useMemo(
    () =>
      JSON.stringify(terms.slice().sort()) ===
      JSON.stringify(treeProps.blocks.slice().sort()),
    [terms, treeProps.blocks]
  );

  const menu = (
    <Menu className="t-metadata-dd">
      <Menu.Item key="templates">
        <Select
          className="t-metadata-select"
          defaultValue={-1}
          style={{ width }}
          onChange={(templateIdx) =>
            dispatch(fetchMetadataTemplateFieldsThunk(templateIdx))
          }
          onClick={(e) => e.stopPropagation()}
        >
          {metadataTemplateOptions}
        </Select>
      </Menu.Item>
      {terms.length > 0 ? (
        <Menu.Item key="select-all-fields" className="t-fields-all">
          <MetadataSelectAll
            checked={allFieldsSelected}
            onChange={(checked: boolean) =>
              dispatch(selectAllTerms({ checked }))
            }
          />
        </Menu.Item>
      ) : null}
      {terms.map((field) => (
        <Menu.Item key={field}>
          <MetadataFieldSelect
            checked={treeProps.blocks.includes(field)}
            field={field}
            width={width}
            onChange={(visible, only) =>
              dispatch(setFieldVisibility({ field, visible, only }))
            }
          />
        </Menu.Item>
      ))}
    </Menu>
  );

  return terms.length > 0 ? (
    <Dropdown overlay={menu} placement="bottomRight" trigger={["click"]}>
      <Button
        title={i18n("PhylocanvasShapeDropDown.metadata.tooltip")}
        shape="circle"
        icon={<FilterOutlined />}
      />
    </Dropdown>
  ) : null;
}

{'fraction_non_alphanumeric': 0.14683415379392292, 'fraction_numerical': 0.0035647598030894585, 'mean_word_length': 2.429569266589057, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 64, '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': '6038339', 'n_tokens_mistral': 1689, 'n_tokens_neox': 1666, 'n_words': 329}