util.tsx 3.51 KB
import React, { useEffect, useMemo, useRef, useState } from 'react';

import { Button, Image, message, Modal, Tooltip, Upload } from 'antd';
import { QxIcon } from '@/components';

import defaultImg from '@/components/default/default_cover.png';

const defaultIcon: Record<string, string> = {
  form: 'icon-app-file-fill',
  group: 'icon-app-folder-2-fill',
  report: 'icon-app-performance-fill',
  url: 'icon-app-share-forward-fill',
  page: 'icon-app-tablicon-app-fill',
  dataset: 'icon-app-presentation-2-fill',
  datasetCube: 'icon-app-box-3-fill',
  app: 'icon-app-grid-2-fill',
};

// 数据流 图标展示
export const getIcon = (icon: string, type?: string) => {
  if ((icon as string)?.startsWith('http')) {
    return (
      <Image
        className={'qx-data-flow__img'}
        src={icon}
        fallback={defaultImg}
        preview={false}
        width={'16px'}
        height={'16px'}
        style={{
          width: '16px',
          height: '16px',
          borderRadius: '4px',
        }}
        alt=""
      />
    );
  } else {
    return (
      <QxIcon
        className={'qx-data-flow__icon'}
        type={icon || defaultIcon[type || 'form']}
      />
    );
  }
};

// 表格 Scroll 高度计算
export const useFlowTableScrollY = (
  deps: {
    columns: any[];
    size?: 'small' | 'middle' | 'default';
    tableBoxClassName?: string;
    classNames?: string[]; // 表格DOM内嵌元素 列名 添加在此,
    hasPagination?: boolean;
    listProps?: any;
  } = {
    size: 'small',
    tableBoxClassName: '',
    classNames: [],
    hasPagination: false,
    columns: [],
    listProps: {},
  },
) => {
  const itemHeaderHeight =
    (deps?.size === 'middle' ? 48 : deps?.size === 'default' ? 56 : 40) + 1;
  const TABLE_VIEW_LIST = deps?.tableBoxClassName || 'qx-data-flow-table';
  let tableHeader = itemHeaderHeight;
  const tableViewListDefaultHeight = 400;
  const defaultPagePadding = 0;

  const $ = (selectors: string) =>
    document.querySelector<HTMLElement>(selectors);

  const defaultScrollY = useMemo(
    () => document.body.clientHeight,
    [tableHeader],
  );

  const [scrollY, setScrollY] = useState<number>(defaultScrollY ?? 200);

  const timer = useRef<NodeJS.Timer>();

  const getScrollY = () => {
    const tableViewList = $(`.${TABLE_VIEW_LIST}`);

    const tableViewListClientHeight =
      tableViewList?.clientHeight || tableViewListDefaultHeight;
    // 分页大小 目前已经固定 所以直接用56px
    const antPaginationHeight = deps?.hasPagination ? 56 : 0;

    const _domHeightByClassName = (deps?.classNames || []).map(
      (_v: string) => $(`.${_v}`)?.clientHeight ?? 0,
    );
    let result =
      tableViewListClientHeight -
      tableHeader -
      defaultPagePadding -
      antPaginationHeight;
    if (!!_domHeightByClassName?.length) {
      result = result - eval(_domHeightByClassName.join('+'));
    }

    if (tableViewList) {
      tableViewList.style.overflowY = result < 200 ? 'auto' : 'hidden';
    }

    setScrollY(result < 100 ? 100 : result);
  };

  const observer = () => {
    window.addEventListener('resize', getScrollY);
  };

  const removeObserver = () => {
    if (timer.current) window.clearTimeout(timer.current);
    window.removeEventListener('resize', getScrollY);
  };

  useEffect(() => {
    observer();
    return () => {
      removeObserver();
    };
  }, [tableHeader]);

  useEffect(() => {
    if (deps) {
      timer.current = setTimeout(() => {
        getScrollY();
      }, 100);
    }
  }, [JSON.stringify(deps)]);

  return [scrollY, getScrollY];
};