All files / src/form/fields TreeSelect.tsx

9.09% Statements 3/33
0% Branches 0/9
0% Functions 0/10
9.09% Lines 3/33

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91                      66x                   66x                                                                                                                               66x          
import React, { CSSProperties, ReactElement, useEffect, useState } from "react";
import { useTranslation } from 'react-i18next';
import { TreeSelect as AntdTreeSelect } from 'antd';
import { getSearchConditionsForDomain } from "@kernel/ServerSideSearcher";
import { fetchDomainLabels, fetchTree } from "@utils/FetchUtils";
import { DataNode } from "antd/lib/tree";
import { isObject } from "lodash";
import { ObjectMetaProps } from "@props/RecordProps";
import { mergeChildrenIntoTree } from "@utils/TreeUtils";
import PropTypes from 'prop-types';
 
const { SHOW_ALL } = AntdTreeSelect;
 
interface TreeSelectProps {
  value: string;
  style?: CSSProperties;
  onChange: (value: string) => void;
  columnKey: string;
  updatable: boolean;
}
 
const TreeSelect = (props: TreeSelectProps): ReactElement => {
  const { value, style, onChange } = props;
  const { t } = useTranslation();
  const [treeData, setTreeData] = useState<Array<DataNode>>([]);
  const [prefetchTagData, setPrefetchTagData] = useState<Map<string, string>>();
 
  const domainName = 'Tag';
  const domainFullName = 'tech_muyan_enterprisewiki_Tag';
 
  useEffect(() => {
    (async () => {
      const conditions = getSearchConditionsForDomain(domainName);
      setTreeData(await fetchTree('Tag', -1, conditions, false));
      setPrefetchTagData(await fetchDomainLabels(domainFullName, JSON.parse(value)));
    })();
  }, [value]);
 
  const treeOnChange = (value: number[] | ObjectMetaProps[]): void => {
    const idValues: number[] = value?.map((v: number | ObjectMetaProps) =>
      (isObject(v)) ? v.value : v);
    onChange(JSON.stringify(idValues));
  };
 
  const loadData = (props: DataNode): Promise<void> => {
    const {key} = props;
    return new Promise(resolve => {
      fetchTree(domainName, key, undefined, false).then(json => {
        setTreeData(mergeChildrenIntoTree(treeData, key, json));
      });
      resolve();
    });
  };
 
  const initialValue = (): { label?: string, value?: string }[] => {
    if (treeData.length === 0 || value === "'[ ]'" || value === undefined) {
      return [];
    }
    return (JSON.parse(value) as string[]).map(tagId => {
      if (prefetchTagData?.has(tagId)) {
        return {label: prefetchTagData.get(tagId), value: tagId};
      }
      return {value: tagId};
    });
  };
 
  const tProps = {
    treeData,
    value: initialValue(),
    onChange: treeOnChange,
    loadData: loadData as ((dataNode: DataNode) => Promise<unknown>),
    style,
    treeCheckable: true,
    showCheckedStrategy: SHOW_ALL,
    treeCheckStrictly: true,
    placeholder: t('Please select tag(support multiple select)'),
  };
 
  return (
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    <AntdTreeSelect {...tProps} />
  );
};
 
TreeSelect.propTypes = {
  key: PropTypes.string
};
 
export default TreeSelect;