antd#Empty TypeScript Examples

The following examples show how to use antd#Empty. 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: EmptyStates.tsx    From posthog-foss with MIT License 6 votes vote down vote up
export function InsightEmptyState({ color, isDashboard }: { color?: string; isDashboard?: boolean }): JSX.Element {
    return (
        <div className={clsx('insight-empty-state', { 'is-dashboard': isDashboard }, color)}>
            <div className="empty-state-inner">
                <div className="illustration-main">
                    <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="" />
                </div>
                <h2>There are no matching events for this query</h2>
                <p className="text-center">Try changing the date range or pick another action, event, or breakdown.</p>
            </div>
        </div>
    )
}
Example #2
Source File: panel-search-list.tsx    From XFlow with MIT License 6 votes vote down vote up
SearchResult: React.FC<ISearchList> = props => {
  const { searchResult, prefixClz, onMouseDown, modelService, commandService, graphConfig } = props

  if (searchResult.length === 0) {
    return <Empty style={{ marginTop: '24px' }} />
  }

  return (
    <ul className={`xflow-collapse-search-list`}>
      {searchResult.map(item => (
        <li
          className={`xflow-collapse-search-list-item ${item.isDisabled ? 'disabled' : ''}`}
          key={item.id}
        >
          <PanelNode
            item={item}
            onMouseDown={onMouseDown(item)}
            popoverContent={item.popoverContent}
            prefixClz={prefixClz}
            modelService={modelService}
            commandService={commandService}
            graphConfig={graphConfig}
          />
        </li>
      ))}
    </ul>
  )
}
Example #3
Source File: BrickDocument.spec.tsx    From next-basics with GNU General Public License v3.0 6 votes vote down vote up
describe("BrickDocument", () => {
  const props = {
    storyId: "presentational-bricks.calendar",
    storyType: "bricks",
  };
  it("should work", async () => {
    const wrapper = mount(<BrickDocument {...props} doc={doc} />);
    await (global as any).flushPromises();

    expect(wrapper).toBeTruthy();
  });

  it("should show up empty when docs equal to null", async () => {
    const wrapper = mount(<BrickDocument {...props} doc={null} />);
    await (global as any).flushPromises();
    expect(wrapper.find(Empty).length).toBe(1);
  });

  it("should show up empty when docs equal to null when doc not found", async () => {
    const wrapper = mount(
      <BrickDocument storyId={"test.test-id"} storyType={"brick"} doc={null} />
    );
    await (global as any).flushPromises();
    expect(wrapper.find(Empty).length).toBe(1);
  });
});
Example #4
Source File: BrickWrapper.spec.tsx    From next-core with GNU General Public License v3.0 6 votes vote down vote up
describe("brick wrapper", () => {
  it("should work", () => {
    const wrapper = shallow(
      <BrickWrapper>
        <div>hello, brick-wrapper</div>
      </BrickWrapper>
    );
    expect(wrapper).toMatchSnapshot();
  });

  it("should work", () => {
    const wrapper = mount(
      <BrickWrapper>
        <Table />
      </BrickWrapper>
    );
    expect(wrapper.find(Empty).length).toBe(1);
  });
});
Example #5
Source File: renderEmpty.tsx    From gant-design with MIT License 6 votes vote down vote up
renderEmpty = (componentName?: string): React.ReactNode => (
  <ConfigConsumer>
    {({ getPrefixCls }: ConfigConsumerProps) => {
      const prefix = getPrefixCls('empty');

      switch (componentName) {
        case 'Table':
        case 'List':
          return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />;

        case 'Select':
        case 'TreeSelect':
        case 'Cascader':
        case 'Transfer':
        case 'Mentions':
          return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} className={`${prefix}-small`} />;
        default:
          return <Empty />;
      }
    }}
  </ConfigConsumer>
)
Example #6
Source File: Notifications.tsx    From jitsu with MIT License 6 votes vote down vote up
NotificationsComponent: React.FC<NotificationsProps> = ({ handleCloseContainer }) => {
  const history = useHistory()
  const notifications = inAppNotificationsStore.notifications
  return (
    <div className="h-full">
      {notifications.length ? (
        <>
          {notifications.map(({ id, title, message, type, icon, editEntityRoute }) => (
            <div key={id} className="my-2 w-full">
              <NotificationCard
                title={title}
                message={message}
                icon={makeIcon(type, icon)}
                onClick={() => {
                  handleCloseContainer?.()
                  history.push(editEntityRoute)
                }}
              />
            </div>
          ))}
        </>
      ) : (
        <div>
          <Empty description={`Notifications list is empty`} />
        </div>
      )}
    </div>
  )
}
Example #7
Source File: index.tsx    From scorpio-h5-design with MIT License 6 votes vote down vote up
export default function() {
  const { openCreatePageDrawer } = useModel('page');
  const { pageSchema, selectPageIndex } = useModel('bridge');

  return (
    <div className="page">
      {
        pageSchema.length === 0 ? (
          <>
            <div className="page-empty">
              <div className="page-empty-center">
                <Empty description="请先创建一个页面吧" />
                <Button type="primary" className="page-empty-new-btn" onClick={openCreatePageDrawer}>新增页面</Button>
              </div>
            </div>
          </>
        ) : (
          pageSchema.map((item, index)=>(
            <div
              key={item.props.path}
              className={classnames('page-card', {select: selectPageIndex === index})}
            >
              <img
                className="page-card-cover"
                src={item.coverSnapshot ?? item.cover ?? 'https://carpooling-1256959311.cos.ap-chengdu.myqcloud.com/d6bc039b-04ea-49ca-8ee9-a006aec7c443.png'}
              />
              <div className="title">{item.props.title}</div>
            </div>
          ))
        )
      }
      <CreatePage />
      <PageConfig />
    </div>
  );
}
Example #8
Source File: index.tsx    From condo with MIT License 6 votes vote down vote up
EmptyCommentsContainer = ({ PromptTitleMessage, PromptDescriptionMessage }) => (
    <EmptyContainer>
        <Empty
            image={null}
            description={
                <>
                    <Typography.Paragraph strong style={EMPTY_CONTAINER_TEXT_STYLES}>
                        {PromptTitleMessage}
                    </Typography.Paragraph>
                    <Typography.Paragraph type={'secondary'} style={EMPTY_CONTAINER_TEXT_STYLES}>
                        {PromptDescriptionMessage}
                    </Typography.Paragraph>
                </>
            }
        />
    </EmptyContainer>
)
Example #9
Source File: index.tsx    From nanolooker with MIT License 6 votes vote down vote up
BookmarksPage: React.FC = () => {
  const { t } = useTranslation();
  const { bookmarks } = React.useContext(BookmarksContext);
  const hasAccountBookmarks = !!Object.keys(bookmarks?.account || {}).length;

  return (
    <>
      <Helmet>
        <title>{t("common.bookmarks")}</title>
      </Helmet>
      <Title level={3}>{t("common.bookmarks")}</Title>
      <Card size="small" bordered={false} className="detail-layout">
        {hasAccountBookmarks ? (
          Object.entries(bookmarks?.account).map(([account, alias]) => (
            <Row gutter={6} key={account}>
              <Col xs={24} sm={8} md={6}>
                {alias}
              </Col>
              <Col xs={24} sm={16} md={18}>
                <AccountHeader account={account} isLink />
              </Col>
            </Row>
          ))
        ) : (
          <Row>
            <Col xs={24} style={{ textAlign: "center" }}>
              <Empty
                image={Empty.PRESENTED_IMAGE_SIMPLE}
                description={t("pages.bookmarks.noBookmarksFound")}
                style={{ padding: "12px" }}
              />
            </Col>
          </Row>
        )}
      </Card>
    </>
  );
}
Example #10
Source File: EmptyFiller.tsx    From datart with Apache License 2.0 6 votes vote down vote up
EmptyFiller = memo(
  ({ title, loading, loadingIcon, ...emptyProps }: EmptyFillerProps) => {
    return (
      <Wrapper>
        <Empty {...emptyProps} description="" />
        <h3>
          {loading ? loadingIcon || <LoadingIcon /> : null}
          {title}
        </h3>
      </Wrapper>
    );
  },
)
Example #11
Source File: index.tsx    From Search-Next with GNU General Public License v3.0 6 votes vote down vote up
Table: React.FC<TableProps> = (props) => {
  const { dataSource, columns, size } = props;
  return (
    <TableContainer component={Paper}>
      <MTable sx={{ minWidth: 650 }} size={size}>
        <TableHead>
          <TableRow>
            {columns.map(({ name, field, align = 'left', ...i }) => (
              <StyledTableCell key={field} align={align}>
                {name}
              </StyledTableCell>
            ))}
          </TableRow>
        </TableHead>
        <TableBody>
          {dataSource.map((row, index) => (
            <StyledTableRow
              key={row.name}
              sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
            >
              {columns.map(({ name, field, align = 'left', render, ...i }) => (
                <StyledTableCell key={field} align={align}>
                  {render ? render(row[field], row, index) : row[field]}
                </StyledTableCell>
              ))}
            </StyledTableRow>
          ))}
        </TableBody>
      </MTable>
      {dataSource.length === 0 && (
        <div className="w-full">
          <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
        </div>
      )}
    </TableContainer>
  );
}
Example #12
Source File: HTTPFlowTable.tsx    From yakit with GNU Affero General Public License v3.0 6 votes vote down vote up
onExpandHTTPFlow = (flow: HTTPFlow | undefined, onClosed?: () => any) => {
    if (!flow) {
        return <Empty>找不到该请求详情</Empty>
    }

    return (
        <div style={{width: "100%"}}>
            <HTTPFlowDetail hash={flow.Hash} onClose={onClosed}/>
        </div>
    )
}
Example #13
Source File: PlayerEvents.tsx    From posthog-foss with MIT License 5 votes vote down vote up
function noRowsRenderer(): JSX.Element {
    return (
        <div className="event-list-empty-container">
            <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="No events fired in this recording." />
        </div>
    )
}
Example #14
Source File: collapse.tsx    From XFlow with MIT License 5 votes vote down vote up
CollapseList: React.FC<ISearchList> = props => {
  const {
    onActiveKeyChange,
    collapseData,
    prefixClz,
    onMouseDown,
    modelService,
    commandService,
    graphConfig,
  } = props

  const renderHeader = (item: ICollapsePanel) => {
    const { header, extra, icon, isCollapsed } = item
    const onClick = (e: React.MouseEvent) => {
      e.preventDefault()
      onActiveKeyChange(item.id)
    }
    return (
      <div className={`xflow-collapse-header`} onClick={onClick}>
        <div className={`xflow-collapse-header-icon`}>
          {isReactComponent(icon) ? (
            React.createElement(icon, { isCollapsed })
          ) : (
            <CaretRightOutlined rotate={isCollapsed ? 0 : 90} style={{ fontSize: '12px' }} />
          )}
        </div>
        <div className={`xflow-collapse-header-label`}>
          {isReactComponent(header) ? React.createElement(header, item) : header}
        </div>
        <div className={`xflow-collapse-header-extra`}>
          {isReactComponent(extra) ? React.createElement(extra, item) : extra}
        </div>
      </div>
    )
  }

  const renderChildren = (children: IPanelNode[]) => {
    return (
      <div className={`xflow-collapse-content`}>
        {children.map(item => {
          return (
            <div
              className={`xflow-collapse-content-item ${item.isDisabled ? 'disabled' : ''}`}
              key={item.id}
            >
              <PanelNode
                item={item}
                onMouseDown={onMouseDown(item)}
                popoverContent={item.popoverContent}
                prefixClz={prefixClz}
                modelService={modelService}
                commandService={commandService}
                graphConfig={graphConfig}
              />
            </div>
          )
        })}
      </div>
    )
  }
  return (
    <ul className="xflow-collapse-list">
      {collapseData.length === 0 && <Empty style={{ marginTop: '24px' }} />}
      {collapseData.map(collapseItem => {
        const { children = [], isCollapsed, render } = collapseItem
        const clz = isCollapsed ? 'close' : 'open'
        return (
          <li className={`xflow-collapse-list-item ${clz}`} key={collapseItem.id}>
            {renderHeader(collapseItem)}
            {isReactComponent(render)
              ? React.createElement(render, collapseItem)
              : renderChildren(children)}
          </li>
        )
      })}
    </ul>
  )
}
Example #15
Source File: BrickDoc.spec.tsx    From next-basics with GNU General Public License v3.0 5 votes vote down vote up
describe("BrickDoc", () => {
  const doc = `
This block of Markdown contains <a href="https://en.wikipedia.org/wiki/HTML">HTML</a>, and will require the <code>html-parser</code> AST plugin to be loaded, in addition to setting the <code class="prop">escapeHtml</code> property to false.
`;

  it("should work when shallow rending", () => {
    const props: BrickDocProps = {
      doc,
    };
    const wrapper = shallow(<BrickDoc doc={props.doc} />);
    const reactMarkdownWrapper = wrapper.find(".brickDocContainer");

    expect(wrapper.find(Empty).exists()).toBeFalsy();
    expect(reactMarkdownWrapper.exists()).toBeTruthy();
    expect(reactMarkdownWrapper.prop("escapeHtml")).toBeFalsy();

    expect(wrapper).toBeTruthy();
  });

  it("should work when doc is null", () => {
    const props: BrickDocProps = {
      doc: null,
    };
    const wrapper = shallow(<BrickDoc doc={props.doc} />);
    const reactMarkdownWrapper = wrapper.find(".brickDocContainer");

    expect(wrapper.find(Empty).exists()).toBeTruthy();
    expect(reactMarkdownWrapper.exists()).toBeFalsy();
    expect(wrapper).toBeTruthy();
  });

  it("icon rotate should be 360deg when click create button", () => {
    const props: BrickDocProps = {
      doc: null,
    };
    const wrapper = mount(<BrickDoc doc={props.doc} />);
    const createButton = wrapper.find(Button);
    const icon = () => wrapper.find(SmileTwoTone);

    expect(icon().prop("rotate")).toBe(180);

    createButton.simulate("click");
    wrapper.update();

    expect(icon().prop("rotate")).toBe(360);
  });
});
Example #16
Source File: EasyopsEmpty.spec.tsx    From next-core with GNU General Public License v3.0 5 votes vote down vote up
describe("Empty", () => {
  it("EasyopsEmpty should work", () => {
    const wrapper = mount(<EasyopsEmpty background="grey" />);
    expect(wrapper.find(EasyopsEmpty).length).toBe(1);
  });

  it("EasyopsEmpty should work with illustration", () => {
    const props: EasyopsEmptyProps = {
      description: "No content",
      illustration: {
        name: "no-content",
      },
    };
    const wrapper = mount(<EasyopsEmpty {...props} />);
    expect(wrapper.find(EasyopsEmpty).length).toBe(1);
    expect((wrapper.find(Empty).prop("image") as string).endsWith(".png")).toBe(
      true
    );
    expect(wrapper.find(Empty).prop("description")).toBe("No content");
  });

  it("EasyopsEmpty should work with the large-sized empty image", () => {
    const props: EasyopsEmptyProps = {
      useBigEmptyImage: true,
    };
    const wrapper = mount(<EasyopsEmpty {...props} />);
    expect(wrapper.find(EasyopsEmpty).length).toBe(1);
  });

  it("renderEasyopsEmpty should work", () => {
    const emptyImage = renderEasyopsEmpty();
    const wrapper = mount(<>{emptyImage}</>);
    expect(wrapper.find(EasyopsEmpty).length).toBe(1);
  });

  it("EasyopsEmpty should work with the large-sized empty image", () => {
    (useCurrentTheme as jest.Mock).mockReturnValueOnce("dark-v2");
    const props: EasyopsEmptyProps = {
      useBigEmptyImage: false,
    };
    const wrapper = mount(<EasyopsEmpty {...props} />);

    expect(wrapper.find("title").text()).toBe("dark default empty image");

    (useCurrentTheme as jest.Mock).mockReturnValueOnce("dark-v2");
    wrapper.setProps({
      useBigEmptyImage: true,
    });

    wrapper.update();

    expect(wrapper.find("title").text()).toBe("dark big empty image");
  });
});
Example #17
Source File: index.tsx    From erda-ui with GNU Affero General Public License v3.0 5 votes vote down vote up
CompMap = {
  Category: (props: ICompProps) => {
    const { category = [], list, onChangeCategory, LoadMoreRender, width, loading } = props;
    const [chosenCategory, setChosenCategory] = React.useState('' as string | number);
    React.useEffect(() => {
      if (!chosenCategory && !isEmpty(category)) {
        setChosenCategory(category[0].value);
      }
    }, [category, chosenCategory]);
    React.useEffect(() => {
      chosenCategory && onChangeCategory && onChangeCategory(chosenCategory);
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [chosenCategory]);
    return (
      <div className="load-more-selector-container">
        <div className="content" style={width ? { width } : {}}>
          <div className="menu">
            <Menu selectedKeys={[`${chosenCategory}`]} className="h-full">
              {map(category, (item) => (
                <MenuItem className="menu-item" key={item.value} onClick={() => setChosenCategory(item.value)}>
                  {item.label}
                </MenuItem>
              ))}
              {isEmpty(category) && <Empty />}
            </Menu>
          </div>
          <div className="list">
            <OptionContainer {...props} viewType="category" />
            {isEmpty(list) ? (
              <Spin spinning={loading}>
                <Empty />
              </Spin>
            ) : (
              LoadMoreRender
            )}
          </div>
        </div>
      </div>
    );
  },
  Normal: (props: ICompProps) => {
    const { list, LoadMoreRender, notFoundContent, width, loading } = props;
    return (
      <div className="load-more-selector-container" style={width ? { width } : {}}>
        <div className="content normal">
          <div className="list">
            <OptionContainer {...props} viewType="normal" />
            {isEmpty(list) ? <Spin spinning={loading}>{notFoundContent || <Empty />}</Spin> : LoadMoreRender}
          </div>
        </div>
      </div>
    );
  },
}
Example #18
Source File: index.tsx    From imove with MIT License 5 votes vote down vote up
SettingBar: React.FC<IProps> = (props) => {
  const { flowChart } = props;
  const forceUpdate = useReducer((n) => n + 1, 0)[1];

  useEffect(() => {
    flowChart.on('settingBar:forceUpdate', forceUpdate);
    return () => {
      flowChart.off('settingBar:forceUpdate');
    };
  }, []);

  const nodes = flowChart.getSelectedCells().filter((v) => v.shape !== 'edge');
  if (nodes.length === 1) {
    return (
      <div className={styles.container}>
        <Tabs
          tabBarGutter={0}
          defaultActiveKey={'basic'}
          tabBarStyle={{
            display: 'flex',
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center',
          }}
        >
          <TabPane tab={'节点配置'} key={'basic'}>
            <Basic selectedCell={nodes[0]} flowChart={flowChart} />
          </TabPane>
          {/* <TabPane tab={'测试用例'} key={'testCase'} forceRender>
            <TestCase selectedCell={nodes[0]} flowChart={flowChart} />
          </TabPane> */}
        </Tabs>
      </div>
    );
  } else {
    return (
      <div className={`${styles.container} ${styles.center}`}>
        <Empty
          description={'请选择一个节点'}
          image={Empty.PRESENTED_IMAGE_SIMPLE}
        />
      </div>
    );
  }
}
Example #19
Source File: ConnectionsPage.tsx    From jitsu with MIT License 5 votes vote down vote up
SourcesEmptyList: React.FC = () => {
  return <Empty className="mt-20" description={`The list is empty`} />
}
Example #20
Source File: task.tsx    From leek with Apache License 2.0 5 votes vote down vote up
TaskPage: React.FC = () => {
  // STATE
  const service = new TaskService();
  const { currentApp } = useApplication();
  const [qpTaskUUID, setQPTaskUUID] = useQueryParam("uuid", StringParam);
  const [task, setTask] = useState({});

  // Data
  const [loading, setLoading] = useState<boolean>(false);

  // API Calls
  function getTaskByUUID(uuid: string) {
    if (!currentApp) return;
    setLoading(true);
    service
      .getById(currentApp, uuid)
      .then(handleAPIResponse)
      .then((result: any) => {
        if (result.hits.hits.length > 0) {
          setTask(result.hits.hits[0]._source);
        }
      }, handleAPIError)
      .catch(handleAPIError)
      .finally(() => setLoading(false));
  }

  useEffect(() => {
    // Stop refreshing metadata
    if (timeout) clearInterval(timeout);
    if (qpTaskUUID) {
      getTaskByUUID(qpTaskUUID);
    }
    timeout = setInterval(() => {
      if (qpTaskUUID) {
        getTaskByUUID(qpTaskUUID);
      }
    }, 5000);

    return () => {
      clearInterval(timeout);
    };
  }, []);

  return (
    <>
      <Helmet>
        <html lang="en" />
        <title>Task detail</title>
        <meta name="description" content="Task details" />
        <meta name="keywords" content="celery, task" />
      </Helmet>

      <Row
        justify="center"
        style={{ marginTop: "20px", width: "100%" }}
        gutter={[12, 12]}
      >
        {task && Object.keys(task).length > 0 && (
          <TaskDetails task={task} loading={loading} />
        )}

        {task && Object.keys(task).length === 0 && (
          <Empty description={<Title level={3}>Waiting task...</Title>} />
        )}
      </Row>
    </>
  );
}
Example #21
Source File: Preview.tsx    From ant-simple-draw with MIT License 5 votes vote down vote up
Preview = memo(function Preview(props) {
  const [componentListData, setComponentListData] = useState<templateDataType[]>([]);
  const [canvasInformation, setCanvasInformation] = useState<any>({});
  const [loading, setLoading] = useState<boolean>(true);
  useEffect(() => {
    if (sessionStorage.getItem('componentDataList')) {
      setComponentListData(sessionStorage.getItem('componentDataList'));
      setCanvasInformation(sessionStorage.getItem('canvasInformation'));
      setTimeout(() => {
        setLoading(false);
      }, 500);
    }
  }, []);
  return (
    <>
      <Head type="preview" />
      {loading ? (
        <Spin size="large" style={{ position: 'relative', left: '50%', top: '30%' }} />
      ) : componentListData.length ? (
        <div
          style={{
            width: canvasInformation.width + 'px',
            height: canvasInformation.height + 'px',
            position: 'relative',
            margin: '0 auto',
          }}
        >
          {componentListData.length
            ? componentListData.map((item, index) => (
                <RenderTemplate
                  {...item}
                  key={item.componentId}
                  style={{ position: 'absolute', ...getStyle(item.style) }}
                  propValue={item.propValue!}
                />
              ))
            : null}
        </div>
      ) : (
        <Empty
          style={{ marginTop: '100px' }}
          image="https://gw.alipayobjects.com/zos/antfincdn/ZHrcdLPrvN/empty.svg"
          imageStyle={{
            height: 200,
          }}
          description={<span>没有可预览的数据</span>}
        ></Empty>
      )}
    </>
  );
})
Example #22
Source File: index.tsx    From scorpio-h5-design with MIT License 5 votes vote down vote up
export default function() {
  const { page, closeCreatePageDrawer, openConfigPageDrawer, onCreatePage } = useModel('page');
  const { queryPageListReq } = Model.useContainer();
  const templateList = queryPageListReq.data;

  const useTemplate = function(template:any){
    onCreatePage({
      ...template.pageSchema[0],
    });
  };

  return (
    <Drawer
      className="page-add"
      title="新增页面-选择页面模板"
      placement="left"
      onClose={closeCreatePageDrawer}
      visible={page.createModalVisible}
      getContainer={false}
      style={{ position: 'absolute' }}
      width={430}
    >
      <Row gutter={16}>
        <Col
          className="gutter-row"
          span={12}
          onClick={()=>{
            // onCreatePage(pageSchema);
            openConfigPageDrawer();
          }}
        >
          <Card
            className="page-add-card"
            cover={
              <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description=""/>
            }
          >
            <div className="title">空白页面</div>
          </Card>
        </Col>
        {
          templateList && templateList.list.map((template: any) => (
            <Col className="gutter-row" span={12} key={template._id}>
              <Card
                className="page-add-card"
                cover={
                  <img
                    className="page-add-card-img"
                    alt="example"
                    src={template.pageSchema[0].cover}
                  />
                }
                onClick={()=>{useTemplate(template);}}
              >
                <div className="title">{template.pageSchema[0].config.title}</div>
              </Card>
            </Col>
          ))
        }
      </Row>
    </Drawer>
  );
}
Example #23
Source File: NoData.tsx    From tailchat with GNU General Public License v3.0 5 votes vote down vote up
NoData: React.FC<NoDataProps> = React.memo((props) => {
  return <Empty description={props.message} />;
})
Example #24
Source File: PaginatedTable.tsx    From mayoor with MIT License 5 votes vote down vote up
export function PaginatedTable<T extends Record>(props: Props<T>) {
	const { t } = useTranslation();
	const [currentPageNumber, setCurrentPageNumber] = useState(1);
	const [selectedItems, setSelectedItems] = useState<string[]>([]);

	const pagination: PaginationConfig = {
		current: currentPageNumber,
		total: props.totalCount,
		pageSize: props.pageSize,
		hideOnSinglePage: true,
		showTotal: (total, range) =>
			t('Showing {{start}}-{{end}} of {{total}} items', {
				total,
				start: range[0],
				end: range[1],
			}),
		onChange: (newPageNumber) => {
			setCurrentPageNumber(newPageNumber);
			props.onPaginationChange(newPageNumber);
		},
	};

	const selectHandler = (id: string, isSelected: boolean) => {
		if (isSelected) {
			return setSelectedItems([...selectedItems, id]);
		}
		setSelectedItems(selectedItems.filter((currentId) => currentId !== id));
	};

	const searchSubmitHandler = (searchValue: string) => {
		setCurrentPageNumber(1);
		props.onSearch && props.onSearch(searchValue);
	};

	return (
		<StyledTableWrapper>
			<Row justify="end">
				{props.topRowContent}
				{props.onSearch && (
					<Col xs={24} md={6}>
						<StyledSearch
							enterButton
							placeholder={props.translations.search}
							onSearch={searchSubmitHandler}
						/>
					</Col>
				)}
			</Row>

			<Table<T>
				columns={props.columns}
				dataSource={props.records}
				pagination={pagination}
				loading={props.loading}
				rowKey={(record) => record.id}
				size="middle"
				rowSelection={{
					onSelect: ({ id }, isSelected) => selectHandler(id, isSelected),
					selectedRowKeys: selectedItems,
					onSelectAll: (_, selectedRows) => {
						setSelectedItems(selectedRows.map(({ id }) => id));
					},
				}}
				locale={{
					emptyText: (
						<Empty
							image={Empty.PRESENTED_IMAGE_SIMPLE}
							description={props.translations.emptyResult}
						/>
					),
				}}
			/>
		</StyledTableWrapper>
	);
}
Example #25
Source File: index.tsx    From Search-Next with GNU General Public License v3.0 5 votes vote down vote up
Commits: React.FC = () => {
  const [commits, setCommits] = React.useState([] as CommitValueTypes[]);
  const [page, setPage] = React.useState<number>(1);
  const [loading, setLoading] = React.useState(false);

  const getList = (page: number) => {
    setPage(page);
    setLoading(true);
    commitList(page)
      .then((res) => {
        const formatCommit = res.data.map((i: CommitSourceValueTypes) => {
          let { email, ...author } = i.commit.author;
          return {
            author: {
              ...author,
              avatar_url: i.author.avatar_url,
              html_url: i.author.html_url,
            },
            url: i.html_url,
            message: i.commit.message,
          };
        });
        setCommits(formatCommit);
        setLoading(false);
      })
      .catch(() => {
        setLoading(false);
      });
  };

  React.useEffect(() => {
    getList(page);
  }, []);

  return (
    <div>
      <Loading loading={loading}>
        <ContentList>
          {commits.length ? (
            commits.map((i, j) => (
              <ItemCard
                key={j}
                title={formatText(i.message)}
                desc={`${i.author.name} ${dayjs(i.author.date).format(
                  'YYYY/MM/DD',
                )}`}
                onClick={() => window.open(i.url)}
              ></ItemCard>
            ))
          ) : (
            <Empty></Empty>
          )}
        </ContentList>
      </Loading>
      <a
        className="flex justify-center mt-2 bg-gray-100 rounded p-1"
        href="https://github.com/virzs/Search-Next/commits/master"
        target="_blank"
      >
        在GitHub上查看更多
      </a>
    </div>
  );
}
Example #26
Source File: ReportViewer.tsx    From yakit with GNU Affero General Public License v3.0 5 votes vote down vote up
ReportViewer: React.FC<ReportViewerProp> = (props) => {
    const [loading, setLoading] = useState(false);
    const [report, setReport] = useState<Report>({
        From: "",
        Hash: "",
        Id: 0,
        JsonRaw: "-",
        Owner: "-",
        PublishedAt: 0,
        Title: "-"
    });
    const [reportItems, setReportItems] = useState<ReportItem[]>([]);


    useEffect(() => {
        if ((props?.id || 0) <= 0) {
            return
        }

        setLoading(true)
        ipcRenderer.invoke("QueryReport", {Id: props.id}).then((r: Report) => {
            if (r) setReport(r);
        }).catch(e => {
            failed(`Query Report[${props.id}] failed`)
        }).finally(() => setTimeout(() => setLoading(false), 300))
    }, [props.id])

    useEffect(() => {
        try {
            const items = JSON.parse(report.JsonRaw) as ReportItem[];
            if (!!items && items.length > 0) {
                setReportItems(items)
            }
        } catch (e) {
            failed(`Parse Report[${props.id}]'s items failed`)
            console.info(e)
        }
    }, [report])

    if (report.Id <= 0) {
        return <AutoCard loading={loading}>
            <Empty>{"选择报告以在此查看内容"}</Empty>
        </AutoCard>
    }

    return <AutoCard size={"small"} bordered={false} loading={loading} title={<Space>
        {report.Title} <Tag>{props.id}</Tag>
    </Space>} bodyStyle={{overflow: "auto"}} extra={<Space>
        <a href={"#"} onClick={() => {
            showModal({
                title: "RAW DATA", content: (
                    <div style={{height: 300}}>
                        <YakEditor value={report.JsonRaw}/>
                    </div>
                ), width: "50%",
            })
        }}>RAW</a>
    </Space>}>
        <Space direction={"vertical"}
               style={{width: "100%"}}
        >
            {reportItems.map((i, index) => {
                return <ReportItemRender item={i} key={index}/>
            })}
        </Space>
    </AutoCard>
}
Example #27
Source File: index.tsx    From drip-table with MIT License 4 votes vote down vote up
EditableTable = (props: Props & { store: GlobalStore }) => {
  const { noDataFeedBack } = useGlobalData();
  const [state, actions] = props.store;
  const store = { state, setState: actions };

  const hasRecord = !(!state.previewDataSource || state.previewDataSource.length <= 0);

  const previewComponentRender = (
    column: DripTableBuiltInColumnSchema | null,
    extraOptions?: {
      isCurrentColumn?: boolean;
      parentIndex?: number[];
      isChildren?: boolean;
    },
  ) => {
    const [libName, componentName] = column?.component?.includes('::') ? column.component.split('::') : ['', column?.component || ''];
    const DripTableComponent = libName ? props.customComponents?.[libName]?.[componentName] : builtInComponents[componentName];
    const record = state.previewDataSource?.[0] || {} as Record<string, unknown>;
    const value = column?.dataIndex ? get(record, column.dataIndex) : record;

    const isChecked = (currentCheckedIndex: number) => {
      const currentColumnPath = [...extraOptions?.parentIndex || [], currentCheckedIndex];
      const stateColumnPath = state.currentColumnPath || [];
      return extraOptions?.isCurrentColumn && currentColumnPath.join('.') === stateColumnPath.join('.');
    };

    // render group column and handler options.items
    if (column?.component === 'group') {
      const gutter = column.options.gutter ?? [0, 0];
      return (
        <div style={{ height: extraOptions?.isChildren ? '100%' : '120px', overflow: 'hidden' }}>
          <div
            className={extraOptions?.isChildren ? '' : styles['table-cell']}
            style={{ width: extraOptions?.isChildren ? '100%' : column?.width || 120 }}
          >
            { column.options.layout?.map((layout, index) => (
              <Row
                key={index}
                className={styles['row-margin']}
                style={{
                  flexFlow: column.options.wrap ? 'row wrap' : 'nowrap',
                  justifyContent: column.options.horizontalAlign,
                  width: 'calc(100% - 4px)',
                  height: 120 / column.options.layout.length - gutter[1],
                }}
                gutter={gutter}
                justify={column.options.horizontalAlign}
                wrap={column.options.wrap}
              >
                { Array.from({ length: layout }, (v, i) => i).map((col, i) => {
                  const currentCheckedIndex = column.options.layout.slice(0, index).reduce((sum, j) => sum + j, i);
                  return (
                    <Col
                      className={classnames(styles['linear-stripe'], isChecked(currentCheckedIndex) ? styles['checked-stripe'] : '')}
                      key={i}
                      style={{
                        width: (Number(column?.width) || 120) / layout - gutter[0],
                        height: '100%',
                        overflow: 'auto',
                      }}
                      onClick={(e) => {
                        e.stopPropagation();
                        if (!extraOptions?.isCurrentColumn) { return; }
                        state.currentColumnPath = isChecked(currentCheckedIndex)
                          ? []
                          : [...extraOptions?.parentIndex || [], currentCheckedIndex];
                        globalActions.updateColumnPath(store);
                      }}
                    >
                      { column.options.items[currentCheckedIndex]
                        ? previewComponentRender(column.options.items[currentCheckedIndex], {
                          isCurrentColumn: extraOptions?.isCurrentColumn,
                          parentIndex: [...extraOptions?.parentIndex || [], currentCheckedIndex],
                          isChildren: true,
                        })
                        : null }
                    </Col>
                  );
                }) }
              </Row>
            )) }
          </div>
        </div>
      );
    }

    // render normal column and preview component
    const componentPreviewCell = DripTableComponent
      ? (
        <DripTableComponent
          driver={props.driver || DripTableDriverAntDesign}
          value={value as unknown}
          data={record}
          schema={column}
          preview={{}}
        />
      )
      : <Alert type="error" message="未知组件" />;
    return extraOptions?.isChildren
      ? componentPreviewCell
      : (
        <div style={{ height: '120px', overflow: 'auto' }}>
          <div className={styles['table-cell']} style={{ width: column?.width || 120 }}>
            { componentPreviewCell }
          </div>
        </div>
      );
  };

  const renderTableCell = (col: DripTableColumn) => {
    const isCurrent = state.currentColumn && state.currentColumn.index === col.index;
    let width = String(col.width).trim() || '120';
    if ((/^[0-9]+$/gui).test(width)) {
      width += 'px';
    }
    return (
      <div
        style={{ width }}
        className={classnames(styles.column, { checked: isCurrent })}
        onClick={() => {
          if (col.key !== state.currentColumn?.key) {
            state.currentColumnPath = [];
          }
          state.currentColumn = isCurrent ? void 0 : col;
          globalActions.checkColumn(store);
        }}
      >
        <div className={styles['column-title']}>{ col.title }</div>
        { hasRecord
          ? previewComponentRender(col as DripTableBuiltInColumnSchema,
            {
              isCurrentColumn: isCurrent ?? false,
            })
          : null }
        { isCurrent && (
        <CloseCircleTwoTone
          className={styles['close-icon']}
          twoToneColor="#ff4d4f"
          onClick={() => {
            const index = state.columns.findIndex(item => item.key === state.currentColumn?.key);
            if (index > -1) {
              state.columns.splice(index, 1);
              for (let i = index; i < state.columns.length; i++) {
                state.columns[i].index = i + 1;
                state.columns[i].sort = i + 1;
              }
              state.currentColumn = void 0;
              globalActions.editColumns(store);
              globalActions.checkColumn(store);
            }
          }}
        />
        ) }
      </div>
    );
  };

  const emptyFeedBack = () => {
    let message = '';
    if (!hasRecord) {
      if (noDataFeedBack) { return noDataFeedBack; }
      message = '暂无数据';
    }
    if (!state.columns || state.columns?.length <= 0) { message = '暂无表格配置'; }
    let width: number = 0;
    state.columns?.forEach((item) => {
      width += Number(String(item.width).replace(/(px|%|r?em|pt|vw|cm|in|pc)$/ui, '')) || 120;
    });

    return message ? <Empty style={{ width: width > 0 ? width : void 0 }} image={Empty.PRESENTED_IMAGE_SIMPLE} description={message} /> : null;
  };

  return (
    <React.Fragment>
      { state.globalConfigs.header && <EditableHeader driver={props.driver} store={props.store} /> }
      <div style={{ padding: '12px 0 12px 12px', overflowX: 'auto' }}>
        {
      state.columns && state.columns.length > 0 && (
        <Draggable<DripTableColumn>
          value={(state.columns || [])}
          codeKey="sort"
          style={{ position: 'relative' }}
          onChange={(data) => {
            state.columns = [...data];
            globalActions.editColumns(store);
          }}
          render={renderTableCell}
        />
      )
      }
        { emptyFeedBack() }
      </div>
      { state.globalConfigs.footer && <EditableFooter driver={props.driver} store={props.store} /> }
    </React.Fragment>
  );
}
Example #28
Source File: ProductsList.tsx    From Shopping-Cart with MIT License 4 votes vote down vote up
ProductsList = () => {
  const dispatch = useDispatch();
  const [currentPage, setCurrentPage] = useState<number>(1);
  const [cartItems, setCartItems] = useState<ProductModel['id'][]>([]);
  const { isLoading, items, totalProducts } = useSelector(
    (state: RootState) => state.productReducer,
  );
  const itemList = items && Object.entries(items).map(item => item[1]);

  useEffect(() => {
    dispatch(fetchProductListAsync.request({ currentPage }));
  }, [dispatch, currentPage]);

  useEffect(() => {
    if (storageService.getItem('cart-class101')) {
      setCartItems(
        JSON.parse(storageService.getItem('cart-class101') as string),
      );
    }
  }, [setCartItems, storageService.setItem]);

  // 제품 카트 클릭 이벤트 핸들러
  const handleProductCardClick = useCallback(
    (id: ProductModel['id']) => {
      if (cartItems.includes(id)) {
        storageService.setItem(
          'cart-class101',
          JSON.stringify([...cartItems.filter(value => value !== id)]),
        );
        setCartItems([...cartItems.filter(value => value !== id)]);
      } else if (cartItems.length >= 3) {
        InfoModal('warning', '주의', '장바구니에는 3개 이상 담을 수 없습니다.');
      } else {
        cartItems.push(id);
        storageService.setItem('cart-class101', JSON.stringify([...cartItems]));
      }
    },
    [cartItems, setCartItems, storageService.setItem, storageService.getItem],
  );

  // 페이지네이션 onChange
  const handlePaginationOnChange = useCallback(
    (page: number, pageNumber?: number) => {
      setCurrentPage(page);
    },
    [setCurrentPage],
  );

  if (isLoading) return <LoadingSpin />;

  return (
    <>
      <Row>
        <Col span={24}>
          <PageTitle title="상품 목록" />
        </Col>
      </Row>
      <Row>
        {itemList ? (
          itemList.map(product => (
            <Col xs={24} sm={12} lg={6} key={product.id}>
              {' '}
              <ProductCard
                onClick={handleProductCardClick}
                product={product}
              />{' '}
            </Col>
          ))
        ) : (
          <Empty />
        )}
      </Row>
      <Row style={{ marginTop: '15px' }}>
        <Col span={24} style={{ textAlign: 'right' }}>
          <Pagination
            defaultCurrent={1}
            defaultPageSize={4}
            total={totalProducts}
            onChange={handlePaginationOnChange}
          />
        </Col>
      </Row>
    </>
  );
}
Example #29
Source File: SelectGradientOverflow.tsx    From posthog-foss with MIT License 4 votes vote down vote up
/**
 * Ant Design Select extended with a gradient overlay to indicate a scrollable list.
 */
export function SelectGradientOverflow({
    autoFocus = false,
    defaultOpen = false,
    delayBeforeAutoOpen,
    dropdownMatchSelectWidth = true,
    handleBlur = () => {},
    placement,
    propertyKey,
    ...props
}: SelectGradientOverflowProps): JSX.Element {
    const selectRef: React.RefObject<RefSelectProps> | null = useRef(null)
    const containerRef: React.RefObject<HTMLDivElement> = useRef(null)
    const dropdownRef = useRef<HTMLDivElement>(null)
    const [isOpen, setOpen] = useState(false)
    const { formatForDisplay } = useValues(propertyDefinitionsModel)

    /**
     * Ant Design Tag with custom styling in .scss to match default style
     */
    function CustomTag({ label, onClose, value }: CustomTagProps): JSX.Element {
        // if this component is displaying a list of PropertyFilterValues it needs to format them for display
        if (typeof label === 'string' && propertyKey) {
            label = formatForDisplay(propertyKey, label)
        }
        return (
            <Tooltip title={toString(value)}>
                <Tag>
                    <span className="label">{label}</span>
                    <CloseButton onClick={onClose} />
                </Tag>
            </Tooltip>
        )
    }

    const updateScrollGradient = (): void => {
        const dropdown = dropdownRef.current
        if (!dropdown) {
            return
        }
        const holder: HTMLDivElement | null = dropdown.querySelector('.rc-virtual-list-holder')
        if (!holder) {
            return
        }
        if (holder.scrollTop > 0) {
            dropdown.classList.add('scrollable-above')
        } else {
            dropdown.classList.remove('scrollable-above')
        }
        if (holder.scrollHeight > holder.scrollTop + holder.offsetHeight) {
            holder.classList.add('scrollable-below')
        } else {
            holder.classList.remove('scrollable-below')
        }
    }

    const onFocus: React.FocusEventHandler<HTMLElement> = (e) => {
        props.onFocus?.(e)
        setTimeout(() => setOpen(true), delayBeforeAutoOpen || 0)
    }

    const onBlur: React.FocusEventHandler<HTMLElement> = (e) => {
        props.onBlur?.(e)
        if (isOpen) {
            setOpen(false)
            handleBlur()
        }
    }

    useEffect(() => {
        if (autoFocus || defaultOpen) {
            selectRef.current?.focus()
        }
    }, [autoFocus, defaultOpen])

    const outsideClickListener = (event: any): void => {
        if (!containerRef.current?.contains(event.target) && !dropdownRef.current?.contains(event.target) && isOpen) {
            selectRef.current?.blur()
        }
    }
    document.addEventListener('click', outsideClickListener)

    return (
        <div ref={containerRef} style={{ width: '100%' }}>
            {/*
            This config provider is used to configure the empty data state on the wrapped
            ANT select component
             */}
            <ConfigProvider
                renderEmpty={() => {
                    if (props.loading) {
                        return (
                            <div className="illustration-main" style={{ textAlign: 'center' }}>
                                <LoadingOutlined style={{ fontSize: 20 }} />
                                <div>Loading data</div>
                            </div>
                        )
                    } else {
                        return (
                            <div className="illustration-main">
                                <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="No data" />
                            </div>
                        )
                    }
                }}
            >
                <Select
                    {...props}
                    dropdownAlign={placement ? ANTD_TOOLTIP_PLACEMENTS[placement] : undefined}
                    ref={selectRef}
                    open={isOpen}
                    onFocus={onFocus}
                    onBlur={onBlur}
                    onPopupScroll={() => {
                        updateScrollGradient()
                    }}
                    tagRender={CustomTag}
                    dropdownRender={(menu) => (
                        <DropdownGradientRenderer
                            menu={menu}
                            innerRef={dropdownRef}
                            updateScrollGradient={updateScrollGradient}
                        />
                    )}
                    dropdownMatchSelectWidth={dropdownMatchSelectWidth}
                >
                    {props.children}
                </Select>
            </ConfigProvider>
        </div>
    )
}