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 { /** * 数据是否在加载中 */ 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 { getInfo: () => ({ name: "autotip" }), 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 = ( {tableFoundText => ( )} ); } 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; query?: QueryState; 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, }); };