All files / src/table/addons autotip.tsx

3.33% Statements 1/30
0% Branches 0/28
0% Functions 0/5
3.33% Lines 1/30

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 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180                                                                                                                                                                                                                                                                                                                                  3x                                    
import React from "react";
import { TableAddon } from "../TableProps";
import { StatusTip, StatusTipProps } from "../../tips";
import { useTranslation } from "../../i18n";
import { FetcherState, QueryState, Omit } from "../../_type";
 
/**
 * `autotip` 插件用于给定表格数据的状态,自动提供合适的 `topTip` 来显示该状态。
 */
export interface AutoTipOptions extends Omit<StatusTipProps, "status"> {
  /**
   * 数据是否在加载中
   */
  isLoading?: boolean;
 
  /**
   * 数据加载是否异常
   */
  isError?: boolean;
 
  /**
   * 数据是否被筛选
   */
  isFound?: boolean;
 
  /**
   * 用于没有传入 `foundText` 时,默认筛选文案的生成
   *
   * 如果提供了 `foundKeyword`,默认筛选文案将会使用
   */
  foundKeyword?: string;
 
  /**
   * `foundKeyword` 最长展示长度,超出部分将用 '...' 代替
   *
   * @default 20
   */
  foundKeywordMaxLength?: number;
 
  /**
   * 用于没有传入 `foundText` 时,默认筛选文案的生成
   *
   * 如果提供了 `foundCount`,默认筛选文案将会使用,不提供时将使用当前传入的记录条数
   *
   * `foundCount` 为 0 时将使用空数据提示文案
   */
  foundCount?: number;
 
  /**
   * 隐藏图标
   */
  hideIcon?: boolean;
}
 
/**
 * 给定表格数据的状态,自动提供合适的 topTip 来显示该状态
 */
export function autotip(options: AutoTipOptions): TableAddon {
  const {
    isFound,
    isLoading,
    isError,
    foundText,
    emptyText,
    foundKeyword,
    foundCount,
    foundKeywordMaxLength = 20,
    ...tipProps
  } = options;
 
  return {
    onInjectProps(props) {
      // 根据数据情况、加载情况、关键字情况使用不同的 Tips 渲染
      let topTip: React.ReactNode = null;
      let tipStatus: StatusTipProps["status"] = null;
 
      const records = props.records || [];
      const recordCount =
        typeof foundCount === "undefined" ? records.length : foundCount;
 
      if (isLoading) {
        tipStatus = "loading";
      } else if (isError) {
        tipStatus = "error";
      } else if (isFound) {
        tipStatus = "found";
      } else if (recordCount === 0) {
        tipStatus = "empty";
      }
 
      if (tipStatus) {
        topTip = (
          <DefaultFoundTextProvider
            foundText={foundText}
            foundKeyword={foundKeyword}
            recordCount={recordCount}
            foundKeywordMaxLength={foundKeywordMaxLength}
          >
            {tableFoundText => (
              <StatusTip
                status={tipStatus}
                foundText={tableFoundText}
                emptyText={emptyText}
                {...tipProps}
              />
            )}
          </DefaultFoundTextProvider>
        );
      }
 
      return {
        ...props,
        topTip,
      };
    },
  };
}
 
function DefaultFoundTextProvider({
  foundText,
  foundKeyword,
  recordCount,
  foundKeywordMaxLength,
  children,
}: {
  foundText: React.ReactNode;
  foundKeyword: string;
  recordCount: number;
  foundKeywordMaxLength: number;
  children?: (text: React.ReactNode) => any;
}) {
  const t = useTranslation();
 
  if (foundText) {
    return children(foundText);
  }
  if (foundKeyword) {
    if (recordCount === 0) {
      return children(t.foundNothingWithKeyword(foundKeyword));
    }
    // eslint-disable-next-line no-param-reassign
    foundKeyword =
      foundKeyword.slice(0, foundKeywordMaxLength) +
      (foundKeyword.length > foundKeywordMaxLength ? "..." : "");
    return children(t.foundManyTextWithKeyword(foundKeyword, recordCount));
  }
  return children(t.foundManyText(recordCount));
}
 
export interface LegacySmartTipState {
  fetcher: FetcherState<any>;
  query?: QueryState<any>;
  onClearSearch?: () => void;
  onRetry?: () => void;
  emptyTips?: React.ReactNode;
  enableLoading?: boolean;
}
 
/**
 * 从 Tea v1 的 SmartTips.render() 参数构造成新的 autotip 插件
 */
autotip.fromLegacyState = ({
  enableLoading,
  fetcher,
  query,
  onClearSearch,
  onRetry,
  emptyTips,
}: LegacySmartTipState) => {
  const search = query && query.search;
  return autotip({
    isLoading: (enableLoading !== false || search) && fetcher.loading,
    isError: fetcher.fetchState === "Failed",
    foundKeyword: search,
    onClear: onClearSearch,
    onRetry,
    emptyText: emptyTips,
  });
};