@ant-design/icons#ExclamationCircleTwoTone TypeScript Examples

The following examples show how to use @ant-design/icons#ExclamationCircleTwoTone. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.tsx    From drip-table with MIT License 4 votes vote down vote up
AttributeLayout = (props: Props & { store: GlobalStore }) => {
  const { dataFields, mockDataSource: isDemo, slots } = useGlobalData();

  const [state, setState] = props.store;
  const store = { state, setState };

  const [activeKey, setActiveKey] = React.useState('0');

  const [formDisplayMode, setFormDisplayMode] = React.useState('tabs' as 'collapse' | 'tabs');

  const [codeErrorMessage, setCodeErrorMessage] = React.useState('');

  const [code, setCode] = React.useState(JSON.stringify(state.previewDataSource, null, 4));

  const getActiveKey = () => {
    if (activeKey === '0') {
      return state.currentColumn ? '1' : '2';
    }
    return activeKey;
  };

  const getComponents = () => {
    let componentsToUse = components;
    if (props.customComponentPanel) {
      const customComponents = props.customComponentPanel.configs;
      componentsToUse = props.customComponentPanel.mode === 'add' ? [...components, ...customComponents] : [...customComponents];
    }
    return [...componentsToUse];
  };

  /**
   * 将全局配置转换成FormData
   * @param {GlobalSchema} globalConfigs 全局配置
   * @returns {Record<string, unknown>} 表单数据
   */
  const decodeGlobalConfigs = (globalConfigs?: GlobalSchema) => {
    const formData: Record<string, unknown> = { ...filterAttributes(globalConfigs, 'header') };
    if (typeof globalConfigs?.header === 'object') {
      formData.header = true;
      const headerElements = globalConfigs?.header?.elements || [];
      for (const headerItem of headerElements) {
        if (headerItem.type === 'spacer') {
          headerItem['style.width'] = headerItem.style?.width;
        }
        if (headerItem.type === 'search') {
          headerItem['wrapperStyle.width'] = headerItem.wrapperStyle?.width;
        }
      }
      formData['header.items'] = headerElements;
    }
    if (typeof globalConfigs?.footer === 'object') {
      formData.footer = true;
      const footerElements = globalConfigs?.footer?.elements || [];
      for (const footerItem of footerElements) {
        if (footerItem.type === 'text') {
          footerItem['style.width'] = footerItem.style?.width;
        }
        if (footerItem.type === 'search') {
          footerItem['wrapperStyle.width'] = footerItem.wrapperStyle?.width;
        }
      }
      formData['footer.items'] = footerElements;
    }
    if (typeof globalConfigs?.pagination === 'object') {
      formData.pagination = true;
      Object.keys(globalConfigs?.pagination || {}).forEach((key) => {
        formData[`pagination.${key}`] = globalConfigs?.pagination?.[key];
      });
    }
    return formData;
  };

  const encodeGlobalConfigs = (formData: { [key: string]: unknown }): GlobalSchema => {
    const formatElement = (element) => {
      if (element.type === 'display-column-selector') {
        return {
          type: 'display-column-selector',
          selectorButtonType: element.selectorButtonType,
          selectorButtonText: element.selectorButtonText,
        };
      }
      if (element.type === 'spacer') {
        const width = element['style.width'];
        element['style.width'] = void 0;
        return {
          type: 'spacer',
          style: { width },
        };
      }
      if (element.type === 'text') {
        return {
          type: 'text',
          span: element.span,
          align: element.align,
          text: element.text,
        };
      }
      if (element.type === 'search') {
        const width = element['wrapperStyle.width'];
        element['wrapperStyle.width'] = void 0;
        return {
          type: 'search',
          wrapperStyle: { width },
          align: element.align,
          placeholder: element.placeholder,
          allowClear: element.allowClear,
          searchButtonText: element.searchButtonText,
          searchKeys: element.searchKeys,
          searchKeyDefaultValue: element.searchKeyDefaultValue,
        };
      }
      if (element.type === 'insert-button') {
        return {
          type: 'insert-button',
          align: element.align,
          insertButtonText: element.insertButtonText,
          showIcon: element.showIcon,
        };
      }
      return { ...element };
    };
    return {
      ...filterAttributesByRegExp(formData, /^(footer|header|pagination)\./u),
      $version: formData.$version as number,
      bordered: formData.bordered as boolean,
      size: formData.size as 'small' | 'middle' | 'large' | undefined,
      ellipsis: formData.ellipsis as boolean,
      sticky: formData.sticky as boolean,
      rowSelection: formData.rowSelection as boolean,
      virtual: formData.virtual as boolean,
      scroll: {
        x: formData.scrollX as number,
        y: formData.scrollY as number,
      },
      header: formData.header
        ? {
          style: { margin: '0', padding: '12px 0' },
          elements: (formData['header.items'] as DripTableGenericRenderElement[] || []).map(item => ({ ...formatElement(item) })),
        }
        : false,
      footer: formData.footer
        ? {
          style: { margin: '0', padding: '12px 0' },
          elements: (formData['footer.items'] as DripTableGenericRenderElement[] || []).map(item => ({ ...formatElement(item) })),
        }
        : void 0,
      pagination: formData.pagination
        ? {
          size: formData['pagination.size'] as 'small' | 'default',
          pageSize: formData['pagination.pageSize'] as number,
          position: formData['pagination.position'] as 'bottomLeft' | 'bottomCenter' | 'bottomRight',
          showQuickJumper: formData['pagination.showQuickJumper'] as boolean,
          showSizeChanger: formData['pagination.showSizeChanger'] as boolean,
          showTotal: formData['pagination.showTotal'] as string,
        }
        : false,
    };
  };

  const encodeColumnConfigs = (formData: { [key: string]: unknown }): DripTableColumn => {
    const uiProps: Record<string, unknown> = {};
    const dataProps = {};
    Object.keys(formData).forEach((key) => {
      if (key.startsWith('options.')) {
        uiProps[key.replace('options.', '')] = formData[key];
      } else if (key.startsWith('ui:props.')) {
        uiProps[key.replace('ui:props.', '')] = formData[key];
      } else {
        dataProps[key] = formData[key];
      }
    });
    if (state.currentColumn?.component === 'group') {
      const length = (uiProps.layout as number[])?.reduce((p, v) => p + v, 0) || 0;
      uiProps.items = Array.from({ length }, _ => null);
      if (state.currentColumn.options.items) {
        (state.currentColumn.options.items as Record<string, unknown>[])
          .slice(0, length)
          .forEach((item, i) => { (uiProps.items as Record<string, unknown>[])[i] = item; });
      }
    }
    // const columnConfig = getComponents().find(item => item['ui:type'] === state.currentColumn?.component);
    return {
      ...filterAttributes(dataProps, [
        'options',
        'component',
        'ui:props',
        'ui:type',
        'type',
        'name',
        'dataIndex',
        'title',
        'width',
        'group',
      ]),
      key: state.currentColumn?.key ?? '',
      index: state.currentColumn?.index ?? 0,
      sort: state.currentColumn?.sort ?? 0,
      dataIndex: formData.dataIndex as string | string[],
      title: formData.title as string,
      width: formData.width as string,
      component: state.currentColumn?.component ?? '',
      options: uiProps,
    };
  };

  const encodeColumnConfigsByPath = (formData: { [key: string]: unknown }): DripTableColumnSchema | DripTableBuiltInColumnSchema | null => {
    const uiProps: Record<string, unknown> = {};
    const dataProps = {};
    Object.keys(formData).forEach((key) => {
      if (key.startsWith('options.')) {
        uiProps[key.replace('options.', '')] = formData[key];
      } else if (key.startsWith('ui:props.')) {
        uiProps[key.replace('ui:props.', '')] = formData[key];
      } else {
        dataProps[key] = formData[key];
      }
    });
    if (state.currentColumn) {
      const currentColumnItem = getColumnItemByPath(state.currentColumn, state.currentColumnPath || []);
      if (currentColumnItem?.component === 'group') {
        const length = (uiProps.layout as number[])?.reduce((p, v) => p + v, 0) || 0;
        uiProps.items = Array.from({ length }, _ => null);
        if (currentColumnItem.options.items) {
          currentColumnItem.options.items.slice(0, length).forEach((item, i) => {
            (uiProps.items as Record<string, unknown>[])[i] = item;
          });
        }
      }

      return {
        ...filterAttributes(dataProps, [
          'options',
          'component',
          'ui:props',
          'ui:type',
          'type',
          'name',
          'dataIndex',
          'title',
          'width',
          'group',
        ]),
        key: currentColumnItem.key,
        title: '',
        dataIndex: formData.dataIndex as string | string[],
        component: currentColumnItem.component ?? '',
        options: uiProps,
      };
    }
    return null;
  };

  const submitTableData = (codeValue?: string) => {
    setCodeErrorMessage('');
    setCode(codeValue || '');
    try {
      state.previewDataSource = JSON.parse(codeValue || '');
      setState({ ...state });
      globalActions.updatePreviewDataSource(store);
    } catch (error) {
      setCodeErrorMessage((error as Error).message);
    }
  };

  const getGlobalFormConfigs = () => {
    let globalFormConfigs = GlobalAttrFormConfigs;
    if (props.customGlobalConfigPanel) {
      globalFormConfigs = props.customGlobalConfigPanel?.mode === 'add'
        ? [
          ...GlobalAttrFormConfigs,
          ...props.customGlobalConfigPanel?.configs || [],
        ]
        : [...props.customGlobalConfigPanel?.configs || []];
    }
    globalFormConfigs = globalFormConfigs.map((config) => {
      const uiProps = config['ui:props'];
      if (uiProps?.optionsParam === '$$SLOT_NAME_OPTIONS$$') {
        config = {
          ...config,
          'ui:props': {
            ...uiProps,
            options: Object.keys(slots || {}).map(key => ({ label: key, value: key })),
          },
        };
      }
      if (uiProps?.items) {
        const uiPropsItems = (uiProps.items as DTGComponentPropertySchema[])?.map((item, index) => {
          const itemUiProps = item['ui:props'];
          if (itemUiProps?.optionsParam === '$$SLOT_NAME_OPTIONS$$') {
            itemUiProps.options = Object.keys(slots || {}).map(key => ({ label: key, value: key }));
          }
          return {
            ...item,
            'ui:props': itemUiProps,
          };
        });
        config = {
          ...config,
          'ui:props': {
            ...uiProps,
            items: [...uiPropsItems],
          },
        };
      }
      return config;
    });
    return globalFormConfigs;
  };

  const renderGlobalForm = () => (
    <CustomForm<GlobalSchema>
      primaryKey="$version"
      configs={getGlobalFormConfigs()}
      data={cloneDeep(state.globalConfigs)}
      decodeData={decodeGlobalConfigs}
      encodeData={encodeGlobalConfigs}
      groupType={formDisplayMode}
      theme={props.driver}
      onChange={(data) => {
        store.state.globalConfigs = cloneDeep({ ...data });
        globalActions.updateGlobalConfig(store);
      }}
    />
  );

  const getColumnConfigs = (componentType: string) => {
    const columnConfig = getComponents().find(schema => schema['ui:type'] === componentType);
    columnConfig?.attrSchema.forEach((schema) => {
      const uiProps = schema['ui:props'];
      if (!uiProps) {
        return;
      }
      if (uiProps.optionsParam === '$$FIELD_KEY_OPTIONS$$') {
        uiProps.options = isDemo
          ? Object.keys(state.previewDataSource[0] || {}).map(key => ({ label: key, value: key }))
          : dataFields?.map(key => ({ label: key, value: key })) || [];
      }
      if (uiProps.items) {
        (uiProps.items as DTGComponentPropertySchema[])?.forEach((item, index) => {
          const itemUiProps = item['ui:props'];
          if (!itemUiProps) {
            return;
          }
          if (itemUiProps.optionsParam === '$$FIELD_KEY_OPTIONS$$') {
            itemUiProps.options = isDemo
              ? Object.keys(state.previewDataSource[0] || {}).map(key => ({ label: key, value: key }))
              : dataFields?.map(key => ({ label: key, value: key })) || [];
          }
        });
      }
    });
    return columnConfig;
  };

  const errorBoundary = (message?: string) => (
    <Result
      icon={<ExclamationCircleTwoTone />}
      title={<div style={{ color: '#999' }}>{ message }</div>}
    />
  );

  const renderColumnForm = () => {
    if (!state.currentColumn) {
      return errorBoundary('请点击选择要编辑的列');
    }
    const columnConfig = getColumnConfigs(state.currentColumn?.component || '');
    return (
      <CustomForm<DripTableColumn>
        primaryKey="key"
        configs={columnConfig ? columnConfig.attrSchema || [] : []}
        data={state.currentColumn}
        encodeData={encodeColumnConfigs}
        extendKeys={['ui:props', 'options']}
        groupType={formDisplayMode}
        theme={props.driver}
        onChange={(data) => {
          state.currentColumn = Object.assign(state.currentColumn, data);
          const idx = state.columns.findIndex(item => item.key === state.currentColumn?.key);
          if (idx > -1 && state.currentColumn) {
            state.columns[idx] = state.currentColumn;
          }
          globalActions.editColumns(store);
          globalActions.checkColumn(store);
        }}
      />
    );
  };

  const renderColumnFormItem = () => {
    if (!state.currentColumn || (state.currentColumnPath?.length || 0) <= 0) {
      return errorBoundary('请点击选择要编辑的子元素');
    }
    const currentColumnItem = getColumnItemByPath(state.currentColumn, state.currentColumnPath || []);
    const columnConfig = getColumnConfigs(currentColumnItem?.component || '');
    const tableCellBaseProps = new Set(basicColumnAttrComponents.map(prop => prop.name));
    if (columnConfig) {
      columnConfig.attrSchema = columnConfig.attrSchema.filter(item => !tableCellBaseProps.has(item.name));
    }
    if (!currentColumnItem || !currentColumnItem.component) {
      return errorBoundary('子元素暂未配置组件');
    }
    return (
      <CustomForm<DripTableColumnSchema | DripTableBuiltInColumnSchema | null>
        primaryKey="key"
        configs={columnConfig ? columnConfig.attrSchema || [] : []}
        data={currentColumnItem}
        encodeData={encodeColumnConfigsByPath}
        extendKeys={['ui:props', 'options']}
        groupType={formDisplayMode}
        theme={props.driver}
        onChange={(data) => {
          if (data && state.currentColumn) {
            const schema = { ...filterAttributes(data, ['index', 'sort', 'title']) };
            updateColumnItemByPath(state.currentColumn, state.currentColumnPath || [], schema);
            globalActions.editColumns(store);
          }
        }}
      />
    );
  };

  return (
    <div className={styles['attributes-wrapper']}>
      <div className={styles['attributes-container']}>
        <Tabs
          activeKey={getActiveKey()}
          type="card"
          onChange={(key) => { setActiveKey(key); }}
          tabBarExtraContent={activeKey !== '3'
            ? (
              <Tooltip title={formDisplayMode === 'tabs' ? '折叠面板' : '标签面板'}>
                <Button
                  style={{ borderRadius: 2 }}
                  size="small"
                  onClick={() => { setFormDisplayMode(formDisplayMode === 'collapse' ? 'tabs' : 'collapse'); }}
                  icon={formDisplayMode === 'tabs' ? <CollapseIcon style={{ marginTop: 4 }} /> : <TabsIcon style={{ marginTop: 4 }} />}
                />
              </Tooltip>
            )
            : null}
        >
          <TabPane tab="属性配置" key="1" className={styles['attribute-panel']}>
            <div className={styles['attributes-form-panel']}>
              { renderColumnForm() }
            </div>
          </TabPane>
          { (state.currentColumnPath?.length || 0) > 0 && (
          <TabPane tab="子组件属性" key="4" className={styles['attribute-panel']}>
            <div className={styles['attributes-form-panel']}>
              { renderColumnFormItem() }
            </div>
          </TabPane>
          ) }
          <TabPane tab="全局设置" key="2" className={styles['attribute-panel']}>
            <div className={styles['attributes-form-panel']}>
              { renderGlobalForm() }
            </div>
          </TabPane>
          { isDemo && (
          <TabPane tab="表格数据" key="3" className={styles['attribute-panel']}>
            <div className={styles['attributes-code-panel']}>
              { codeErrorMessage && <Alert style={{ margin: '8px 0' }} message={codeErrorMessage} type="error" showIcon /> }
              <MonacoEditor
                width="100%"
                height={428}
                language="json"
                theme="vs-dark"
                value={code || ''}
                onChange={(value) => { submitTableData(value); }}
              />
            </div>
          </TabPane>
          ) }
        </Tabs>
      </div>
    </div>
  );
}
Example #2
Source File: index.tsx    From nanolooker with MIT License 4 votes vote down vote up
AccountPendingHistory: React.FC<Props> = ({
  socketTransactions,
  pendingSocketTransactions,
}) => {
  const { t } = useTranslation();
  const [knownExchangesList, setKnownExchangesList] = React.useState<
    undefined | string[]
  >();
  const { account } = React.useContext(AccountInfoContext);
  const {
    pending: { blocks = {} } = {},
    isLoading: isAccountHistoryLoading,
  } = usePending(
    typeof knownExchangesList?.length === "number" ? account : "",
    {
      count: String(MAX_PENDING_TRANSACTIONS),
      sorting: true,
      source: true,
      threshold: knownExchangesList?.includes(account)
        ? PENDING_MIN_EXCHANGE_THRESHOLD
        : PENDING_MIN_THRESHOLD,
      include_only_confirmed: false,
    },
  );
  const {
    knownExchangeAccounts,
    isLoading: isKnownAccountsLoading,
  } = React.useContext(KnownAccountsContext);

  React.useEffect(() => {
    if (!isKnownAccountsLoading) {
      setKnownExchangesList(
        knownExchangeAccounts.filter(Boolean).map(({ account }) => account),
      );
    }
  }, [knownExchangeAccounts, isKnownAccountsLoading]);

  const [hashes, setHashes] = React.useState<string[]>([]);
  const { blocks: blocksInfo } = useBlocksInfo(hashes);

  const totalPending = Object.keys(blocks).length;
  const isPaginated = true;
  const showPaginate = totalPending > TRANSACTIONS_PER_PAGE;
  const [currentPage, setCurrentPage] = React.useState<number>(1);

  let pendingHistory: PendingHistoryBlock[] | undefined = undefined;

  if (totalPending) {
    pendingHistory = Object.entries(blocks).map(
      // @ts-ignore
      ([block, { amount, source }]): PendingHistoryBlock => ({
        hash: block,
        // @NOTE "hack" to easily filter out socketTransactions
        // @ts-ignore
        link: block,
        amount,
        local_timestamp: blocksInfo.blocks?.[block]?.local_timestamp,
        confirmed: toBoolean(blocksInfo.blocks?.[block]?.confirmed),
        account: source,
        subtype: "pending",
      }),
    );

    pendingHistory = differenceBy(pendingHistory, socketTransactions, "link");
  }

  const start = 0 + (currentPage - 1) * TRANSACTIONS_PER_PAGE;
  let data = pendingHistory?.slice(start, start + TRANSACTIONS_PER_PAGE) || [];
  if (currentPage === 1) {
    // @ts-ignore
    data = pendingSocketTransactions.concat(data);
  }

  React.useEffect(() => {
    const hashes = Object.keys(blocks);
    if (!hashes.length) return;
    setHashes(hashes?.slice(start, start + TRANSACTIONS_PER_PAGE));
  }, [blocks, start]);

  // const accountPending = accountInfo?.pending
  //   ? new BigNumber(rawToRai(accountInfo?.pending)).toNumber()
  //   : 0;

  // return accountPending > PENDING_MIN_THRESHOLD ? (

  let count = (pendingHistory?.length || 0) + pendingSocketTransactions.length;

  return count ? (
    <>
      <div
        style={{
          display: "flex",
          alignItems: "baseline",
        }}
      >
        <Title level={3}>
          {count}{" "}
          {t(`pages.account.pendingTransaction${count !== 1 ? "s" : ""}`)}
        </Title>

        <Tooltip placement="right" title={t("tooltips.pendingTransaction")}>
          <QuestionCircle />
        </Tooltip>

        {pendingHistory?.length === MAX_PENDING_TRANSACTIONS ? (
          <Tooltip
            placement="right"
            title={t("tooltips.pendingTransactionCount", {
              count: MAX_PENDING_TRANSACTIONS,
            })}
          >
            <ExclamationCircleTwoTone twoToneColor={"orange"} />
          </Tooltip>
        ) : null}
      </div>

      <TransactionsTable
        data={data}
        isLoading={isAccountHistoryLoading}
        isPaginated={isPaginated}
        showPaginate={showPaginate}
        pageSize={TRANSACTIONS_PER_PAGE}
        currentPage={currentPage}
        totalPages={pendingHistory?.length}
        setCurrentPage={setCurrentPage}
      />
    </>
  ) : null;
}