antd#Skeleton JavaScript Examples

The following examples show how to use antd#Skeleton. 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: loading.jsx    From virtuoso-design-system with MIT License 6 votes vote down vote up
render() {
    const { loading } = this.state;

    return (
      <>
        <Switch checked={!loading} onChange={this.onChange} />

        <Card style={{ width: 300, marginTop: 16 }} loading={loading}>
          <Meta
            avatar={
              <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
            }
            title="Card title"
            description="This is the description"
          />
        </Card>

        <Card
          style={{ width: 300, marginTop: 16 }}
          actions={[
            <SettingOutlined key="setting" />,
            <EditOutlined key="edit" />,
            <EllipsisOutlined key="ellipsis" />,
          ]}
        >
          <Skeleton loading={loading} avatar active>
            <Meta
              avatar={
                <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
              }
              title="Card title"
              description="This is the description"
            />
          </Skeleton>
        </Card>
      </>
    );
  }
Example #2
Source File: index.jsx    From prometheusPro with MIT License 6 votes vote down vote up
PageHeaderContent = ({ currentUser }) => {
  const loading = currentUser && Object.keys(currentUser).length;

  if (!loading) {
    return (
      <Skeleton
        avatar
        paragraph={{
          rows: 1,
        }}
        active
      />
    );
  }

  return (
    <div className={styles.pageHeaderContent}>
      <div className={styles.avatar}>
        <Avatar size="large" src={currentUser.avatar} />
      </div>
      <div className={styles.content}>
        <div className={styles.contentTitle}>
          早安,
          {currentUser.name}
          ,祝你开心每一天!
        </div>
        <div>
          {currentUser.title} |{currentUser.group}
        </div>
      </div>
    </div>
  );
}
Example #3
Source File: SingleGeneSelection.jsx    From ui with MIT License 6 votes vote down vote up
SingleGeneSelection = (props) => {
  const { config, setSearchedGene } = props;

  const changeDisplayedGene = (geneName) => {
    const geneNameNoSpaces = geneName.replace(/\s/g, '');
    setSearchedGene(geneNameNoSpaces);
  };

  const [localShownGene, setLocalShownGene] = useState(config?.shownGene);

  useEffect(() => {
    if (!config?.shownGene) return;

    setLocalShownGene(config.shownGene);
  }, [config?.shownGene]);

  if (!config?.shownGene) {
    return (
      <div data-testid='skeletonInput'>
        <Skeleton.Input style={{ width: 200 }} active />
      </div>
    );
  }

  return (
    <Search
      style={{ width: '100%' }}
      enterButton='Search'
      value={localShownGene}
      onChange={(e) => { setLocalShownGene(e.target.value); }}
      onSearch={(val) => changeDisplayedGene(val)}
    />
  );
}
Example #4
Source File: CardSplit.jsx    From ResoBin with MIT License 6 votes vote down vote up
StyledSkeleton = styled(Skeleton)`
  width: 100%;
  margin-bottom: 1rem;

  .ant-skeleton-content {
    padding: 1rem;
    background: ${({ theme }) => theme.secondary};
    border-radius: ${({ theme }) => theme.borderRadius};
    box-shadow: 0 0 0.7rem rgb(0 0 0 / 30%);

    @media ${device.max.xs} {
      padding: 0.75rem;
    }
  }
`
Example #5
Source File: HierarchicalTreeGenes.jsx    From ui with MIT License 6 votes vote down vote up
HierarchicalTreeGenes = (props) => {
  const {
    treeData,
    onGeneReorder,
  } = props;

  const onDrop = (info) => {
    const {
      dragNode, node, dropPosition, dropToGap,
    } = info;

    // if dropped in place, ignore
    // dragNode.key is str, dropPosition is int
    if (dragNode.key == dropPosition) return;

    // If not dropped in gap, ignore
    if (!dropToGap) return;

    let newPosition = dropPosition - (dragNode.key < dropPosition ? 1 : 0);
    newPosition = Math.max(0, newPosition);

    onGeneReorder(dragNode.key, newPosition);
  };

  if (!treeData) return <Skeleton active />;

  return (
    <Tree
      data-testid='HierachicalTreeGenes'
      draggable
      treeData={treeData}
      onDrop={onDrop}
    />
  );
}
Example #6
Source File: MySkeleton.jsx    From react-sendbird-messenger with GNU General Public License v3.0 6 votes vote down vote up
export function MySkeleton({
    loading = false,
    rows = 1,
    children,
    size = 'default',
    avatar,
    avatarShape = 'circle',
}) {
    if (loading) {
        return [...Array(rows).keys()].map((i) => (
            <Fragment key={i}>
                <Space style={{ padding: 12, height: 60 }}>
                    {!!avatar && (
                        <Skeleton.Avatar
                            active={true}
                            size={size}
                            shape={avatarShape}
                        />
                    )}
                    <Skeleton.Input
                        style={{ minWidth: 308, width: 355 }}
                        active={true}
                        size={size}
                    />
                </Space>
            </Fragment>
        ))
    }

    return children
}
Example #7
Source File: Card.jsx    From ResoBin with MIT License 6 votes vote down vote up
CardSkeleton = styled(Skeleton)`
  display: flex;
  align-items: center;
  padding: 0.875rem 1.125rem;
  background: #1b172866;
  border-radius: ${({ theme }) => theme.borderRadius};
  box-shadow: 0 0 0.5rem rgb(0 0 0 / 20%);

  .ant-skeleton-avatar {
    width: 3rem;
    height: 3rem;
  }

  .ant-skeleton-content .ant-skeleton-title {
    margin: 0;
  }
`
Example #8
Source File: PreloadContent.jsx    From ui with MIT License 6 votes vote down vote up
PreloadContent = () => (
  <>
    <div data-testid='preloadContent' style={{ padding: '20px 0' }}>
      <Row gutter={32}>
        <Col className='gutter-row' span={14} offset={2}>
          <div className='preloadContextSkeleton' style={{ padding: '16px 0px' }}>
            <Skeleton.Input style={{ width: '100%', height: 400 }} active />
          </div>
          <div className='preloadContextSkeleton' style={{ padding: '16px 0px' }}>
            <Skeleton.Input style={{ width: '100%', height: 400 }} active />
          </div>
          <div className='preloadContextSkeleton' style={{ padding: '16px 0px' }}>
            <Skeleton.Input style={{ width: '100%', height: 400 }} active />
          </div>
        </Col>
        <Col className='gutter-row' span={6}>
          <Skeleton active paragraph={{ rows: 10 }} />
          <Skeleton active paragraph={{ rows: 10 }} />
          <Skeleton active paragraph={{ rows: 10 }} />
        </Col>
      </Row>
    </div>
  </>
)
Example #9
Source File: children.jsx    From virtuoso-design-system with MIT License 6 votes vote down vote up
render() {
    return (
      <div className="article">
        <Skeleton loading={this.state.loading}>
          <div>
            <h4>Ant Design, a design language</h4>
            <p>
              We supply a series of design principles, practical patterns and high quality design
              resources (Sketch and Axure), to help people create their product prototypes
              beautifully and efficiently.
            </p>
          </div>
        </Skeleton>
        <Button onClick={this.showSkeleton} disabled={this.state.loading}>
          Show Skeleton
        </Button>
      </div>
    );
  }
Example #10
Source File: index.js    From gobench with Apache License 2.0 6 votes vote down vote up
render() {
    return (
      <div>
        <h5 className="mb-3">
          <strong>Basic</strong>
        </h5>
        <div className="mb-5">
          <Skeleton active />
        </div>
      </div>
    )
  }
Example #11
Source File: index.js    From youdidao-unmanned-shop with MIT License 5 votes vote down vote up
render() {
    const {
      title = '',
      logo,
      action,
      content,
      extraContent,
      tabList,
      className,
      tabActiveKey,
      tabDefaultActiveKey,
      tabBarExtraContent,
      loading = false,
      wide = false,
      hiddenBreadcrumb = false,
    } = this.props;

    const clsString = classNames(styles.pageHeader, className);
    const activeKeyProps = {};
    if (tabDefaultActiveKey !== undefined) {
      activeKeyProps.defaultActiveKey = tabDefaultActiveKey;
    }
    if (tabActiveKey !== undefined) {
      activeKeyProps.activeKey = tabActiveKey;
    }
    return (
      <div className={clsString}>
        <div className={wide ? styles.wide : ''}>
          <Skeleton
            loading={loading}
            title={false}
            active
            paragraph={{ rows: 3 }}
            avatar={{ size: 'large', shape: 'circle' }}
          >
            {hiddenBreadcrumb ? null : <BreadcrumbView {...this.props} />}
            <div className={styles.detail}>
              {logo && <div className={styles.logo}>{logo}</div>}
              <div className={styles.main}>
                <div className={styles.row}>
                  <h1 className={styles.title}>{title}</h1>
                  {action && <div className={styles.action}>{action}</div>}
                </div>
                <div className={styles.row}>
                  {content && <div className={styles.content}>{content}</div>}
                  {extraContent && <div className={styles.extraContent}>{extraContent}</div>}
                </div>
              </div>
            </div>
            {tabList && tabList.length ? (
              <Tabs
                className={styles.tabs}
                {...activeKeyProps}
                onChange={this.onChange}
                tabBarExtraContent={tabBarExtraContent}
              >
                {tabList.map(item => (
                  <TabPane tab={item.tab} key={item.key} />
                ))}
              </Tabs>
            ) : null}
          </Skeleton>
        </div>
      </div>
    );
  }
Example #12
Source File: loadmore.jsx    From virtuoso-design-system with MIT License 5 votes vote down vote up
render() {
    const { initLoading, loading, list } = this.state;
    const loadMore =
      !initLoading && !loading ? (
        <div
          style={{
            textAlign: 'center',
            marginTop: 12,
            height: 32,
            lineHeight: '32px',
          }}
        >
          <Button onClick={this.onLoadMore}>loading more</Button>
        </div>
      ) : null;

    return (
      <List
        className="demo-loadmore-list"
        loading={initLoading}
        itemLayout="horizontal"
        loadMore={loadMore}
        dataSource={list}
        renderItem={item => (
          <List.Item
            actions={[<a key="list-loadmore-edit">edit</a>, <a key="list-loadmore-more">more</a>]}
          >
            <Skeleton avatar title={false} loading={item.loading} active>
              <List.Item.Meta
                avatar={
                  <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
                }
                title={<a href="https://ant.design">{item.name.last}</a>}
                description="Ant Design, a design language for background applications, is refined by Ant UED Team"
              />
              <div>content</div>
            </Skeleton>
          </List.Item>
        )}
      />
    );
  }
Example #13
Source File: Playlists.js    From remixr with MIT License 5 votes vote down vote up
export default function Playlist() {
  const [accessToken] = useState(Cookies.get('access_token'));
  const [playlists, setPlaylists] = useState([]);
  const [filteredPlaylists, setFilteredPlaylists] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(false);

  useEffect(() => {
    if (accessToken) {
      ReactGA.pageview('/playlists');
      let url = process.env.REACT_APP_API_URL + '/playlists';

      transport.get(url).then(
        (response) => {
          setPlaylists(response.data.playlists);
          setFilteredPlaylists(response.data.playlists);
          setLoading(false);
        },
        (error) => {
          setError(true);
        }
      );
    }
  }, []);

  if (!accessToken) {
    return <Redirect to="/" />;
  }

  const filter = (searchTerm) => {
    setFilteredPlaylists(playlists.filter((item) => item.name.toLowerCase().includes(searchTerm.toLowerCase())));
    ReactGA.event({
      category: 'Playlist',
      action: 'Search playlists',
    });
  };

  if (error) {
    return <ErrorScreen />;
  }

  return (
    <div className="playlists">
      <Navbar />

      <Title> Select playlist </Title>

      <AutoComplete className="searchBox" onSearch={filter}>
        <Input className="rounded" size="large" placeholder="Filter Playlists" />
      </AutoComplete>

      <Divider />

      <div>
        <Row gutter={[16, 24]}>
          {loading && <Skeleton active />}
          {filteredPlaylists &&
            filteredPlaylists.map((item) => {
              return <PlaylistCard playlist={item} key={item.id} />;
            })}
        </Row>
      </div>
    </div>
  );
}
Example #14
Source File: RaceSelect.js    From 4IZ268-2021-2022-ZS with MIT License 5 votes vote down vote up
RaceSelect = () => {

    const setRace = useRace((state) => state.setCurrentRace)

    const query = useQuery(['competitions'], getCompetitions)
    const [data, setData] = useState([])
    const [page, setPage] = useState(1)

    const height = window.innerHeight - 64 - 82 - 60

    const navigate = useNavigate()

    useEffect(() => {
        if (query.data?.competitions) {
            setData(query.data.competitions.slice(0, 100))
        }
    }, [query.data])

    useEffect(() => {
        if (query.data?.competitions) {
            setData(query.data?.competitions.slice(0, page * 100))
        }
    }, [page, query.data])

    const appendData = () => {
        setPage(page + 1)
    }

    const onScroll = e => {
        if (e.target.scrollHeight - e.target.scrollTop < height + 5) {
            appendData()
        }
    }

    const onClick = (race) => {
        setRace(race.id)
        navigate('/~bukp00/sp2/' + race.id)
    }

    return (
        <>
            {
                query.data?.competitions ?
                    <div className='select-list'>
                        <List>
                            <VirtualList
                                key='list'
                                data={data}
                                height={height}
                                itemHeight={47}
                                itemKey='id'
                                onScroll={onScroll}
                            >
                                {item => (
                                    <List.Item key={item.id} onClick={() => onClick(item)}>
                                        <List.Item.Meta
                                            title={<span>{item.name}</span>}
                                            description={item.organizer + ', ' + item.date}
                                        />
                                    </List.Item>
                                )}
                            </VirtualList>
                        </List>
                    </div> :
                    <div className='select-list-loading'>
                        <Skeleton />
                    </div>
            }
        </>
    )
}
Example #15
Source File: index.js    From acy-dex-interface with MIT License 5 votes vote down vote up
render() {
    const {
      title,
      logo,
      action,
      content,
      extraContent,
      tabList,
      className,
      tabActiveKey,
      tabDefaultActiveKey,
      tabBarExtraContent,
      loading = false,
      wide = false,
      hiddenBreadcrumb = false,
    } = this.props;

    const clsString = classNames(styles.pageHeader, className);
    const activeKeyProps = {};
    if (tabDefaultActiveKey !== undefined) {
      activeKeyProps.defaultActiveKey = tabDefaultActiveKey;
    }
    if (tabActiveKey !== undefined) {
      activeKeyProps.activeKey = tabActiveKey;
    }
    return (
      <div className={clsString}>
        <div className={wide ? styles.wide : ''}>
          <Skeleton
            loading={loading}
            title={false}
            active
            paragraph={{ rows: 3 }}
            avatar={{ size: 'large', shape: 'circle' }}
          >
            {hiddenBreadcrumb ? null : <BreadcrumbView {...this.props} />}
            <div className={styles.detail}>
              {logo && <div className={styles.logo}>{logo}</div>}
              <div className={styles.main}>
                <div className={styles.row}>
                  {title && <h1 className={styles.title}>{title}</h1>}
                  {action && <div className={styles.action}>{action}</div>}
                </div>
                <div className={styles.row}>
                  {content && <div className={styles.content}>{content}</div>}
                  {extraContent && <div className={styles.extraContent}>{extraContent}</div>}
                </div>
              </div>
            </div>
            {tabList && tabList.length ? (
              <Tabs
                className={styles.tabs}
                {...activeKeyProps}
                onChange={this.onChange}
                tabBarExtraContent={tabBarExtraContent}
              >
                {tabList.map(item => (
                  <TabPane tab={item.tab} key={item.key} />
                ))}
              </Tabs>
            ) : null}
          </Skeleton>
        </div>
      </div>
    );
  }
Example #16
Source File: SelectData.jsx    From ui with MIT License 5 votes vote down vote up
SelectData = (props) => {
  const { onUpdate, config, cellSets } = props;

  const {
    loading: cellSetsLoading,
    error: cellSetsError,
    hierarchy,
    properties,
  } = cellSets;

  const getMetadataOptions = (parent) => {
    const children = hierarchy.filter((cluster) => (
      cluster.key === parent))[0]?.children;
    return children;
  };
  const getMetadataParents = () => {
    const options = hierarchy.map(({ key }) => ({ value: key }));

    const filteredOptions = options.filter((element) => (
      properties[element.value].type === 'metadataCategorical'
    ));
    return filteredOptions;
  };
  const handleChange = (value) => {
    onUpdate({ selectedSample: value });
  };
  const parents = getMetadataParents();

  if (!config || cellSetsLoading) {
    return <Skeleton.Input style={{ width: 200 }} active />;
  }

  if (cellSetsError) {
    return <InlineError message='Error loading cell set' />;
  }

  return (
    <>
      <div>
        Select the data to view on the embedding:
      </div>
      <Form.Item>
        <Select
          value={config.selectedSample}
          style={{ width: 200 }}
          onChange={(value) => {
            handleChange(value);
          }}
        >
          <Option value='All'>All</Option>
          {parents.map((parent) => (
            <OptGroup label={metadataKeyToName(properties[parent.value].name)}>
              {getMetadataOptions(parent.value).map((option) => (
                <Option value={option.key}>{properties[option.key].name}</Option>
              ))}
            </OptGroup>
          ))}
        </Select>
      </Form.Item>
    </>
  );
}
Example #17
Source File: active.jsx    From virtuoso-design-system with MIT License 5 votes vote down vote up
storiesOf('antd/skeleton', module).add('active', () => <Skeleton active />, { docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Display active animation.</p></>) } });
Example #18
Source File: index.js    From egoshop with Apache License 2.0 5 votes vote down vote up
render() {
        const {
            title = '',
            logo,
            action,
            content,
            extraContent,
            tabList,
            className,
            tabActiveKey,
            tabDefaultActiveKey,
            tabBarExtraContent,
            loading = false,
            wide = false,
            hiddenBreadcrumb = false,
        } = this.props;

        const clsString = classNames(styles.pageHeader, className);
        const activeKeyProps = {};
        if (tabDefaultActiveKey !== undefined) {
            activeKeyProps.defaultActiveKey = tabDefaultActiveKey;
        }
        if (tabActiveKey !== undefined) {
            activeKeyProps.activeKey = tabActiveKey;
        }
        return (
          <div className={clsString}>
              <div className={wide ? styles.wide : ''}>
                  <Skeleton
                    loading={loading}
                    title={false}
                    active
                    paragraph={{ rows: 3 }}
                    avatar={{ size: 'large', shape: 'circle' }}
                  >
                      {hiddenBreadcrumb ? null : <BreadcrumbView {...this.props} />}
                      <div className={styles.detail}>
                          {logo && <div className={styles.logo}>{logo}</div>}
                          <div className={styles.main}>
                              <div className={styles.row}>
                                  <h1 className={styles.title}>{title}</h1>
                                  {action && <div className={styles.action}>{action}</div>}
                              </div>
                              <div className={styles.row}>
                                  {content && <div className={styles.content}>{content}</div>}
                                  {extraContent && <div className={styles.extraContent}>{extraContent}</div>}
                              </div>
                          </div>
                      </div>
                      {tabList && tabList.length ? (
                        <Tabs
                          className={styles.tabs}
                          {...activeKeyProps}
                          onChange={this.onChange}
                          tabBarExtraContent={tabBarExtraContent}
                        >
                            {tabList.map(item => (
                              <TabPane tab={item.tab} key={item.key} />
                            ))}
                        </Tabs>
                      ) : null}
                  </Skeleton>
              </div>
          </div>
        );
    }
Example #19
Source File: complex.jsx    From virtuoso-design-system with MIT License 5 votes vote down vote up
storiesOf('antd/skeleton', module).add('complex', () => <Skeleton avatar paragraph={{ rows: 4 }} />, { docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Complex combination with avatar and multiple paragraphs.</p></>) } });
Example #20
Source File: MessageSkeleton.jsx    From react-sendbird-messenger with GNU General Public License v3.0 5 votes vote down vote up
export function MessageSkeleton({
    loading = false,
    rows = 1,
    children,
    size = 'default',
    avatar,
    avatarShape = 'circle',
}) {
    if (loading) {
        return [...Array(rows).keys()].map((i) => (
            <Fragment key={i}>
                <div
                    style={{
                        width: '100%',
                        display: 'flex',
                        justifyContent: i % 2 === 0 && 'flex-end',
                    }}
                >
                    <Space
                        style={{
                            padding: 12,
                            height: 60,
                            flexDirection: i % 2 === 0 && 'row-reverse',
                        }}
                    >
                        {!!avatar && (
                            <Skeleton.Avatar
                                style={{
                                    marginLeft: i % 2 === 0 && 8,
                                }}
                                active={true}
                                size={size}
                                shape={avatarShape}
                            />
                        )}
                        <Skeleton.Input
                            style={{ minWidth: 308, width: 355 }}
                            active={true}
                            size={size}
                        />
                    </Space>
                </div>
            </Fragment>
        ))
    }

    return children
}
Example #21
Source File: Address.js    From ship with MIT License 5 votes vote down vote up
export default function Address(props) {

  const [ ens, setEns ] = useState(0)
  useEffect(()=>{
    if(props.value && props.ensProvider){
      async function getEns(){
        let newEns
        try{
          console.log("getting ens",newEns)
          newEns = await props.ensProvider.lookupAddress(props.value)
          setEns(newEns)
        }catch(e){}
      }
      getEns()
    }
  },[props.value, props.ensProvider])

  if(!props.value){
    return (
      <span>
        <Skeleton avatar paragraph={{ rows: 1 }} />
      </span>
    )
  }

  let displayAddress = props.value.substr(0,6)

  if(ens){
    displayAddress=ens
  }else if(props.size === "short"){
    displayAddress += "..."+props.value.substr(-4)
  }else if(props.size === "long"){
    displayAddress = props.value
  }

  let blockExplorer = "https://etherscan.io/address/"
  if(props.blockExplorer){
    blockExplorer = props.blockExplorer
  }

  if(props.minimized){
    return (
        <span style={{verticalAlign:"middle"}}>
          <a style={{color:"#222222"}} href={blockExplorer+props.value}>
            <Blockies seed={props.value.toLowerCase()} size={8} scale={2}/>
          </a>
        </span>
    );
  }

  let text
  if(props.onChange){
    text = (
      <Text editable={{onChange:props.onChange}} copyable={{text:props.value}}>
        <a style={{color:"#222222"}} href={blockExplorer+props.value}>{displayAddress}</a>
      </Text>
    )
  }else{
    text = (
      <Text copyable={{text:props.value}}>
        <a style={{color:"#222222"}} href={blockExplorer+props.value}>{displayAddress}</a>
      </Text>
    )
  }

  return (
    <span>
      <span style={{verticalAlign:"middle"}}>
        <Blockies seed={props.value.toLowerCase()} size={8} scale={4}/>
      </span>
      <span style={{verticalAlign:"middle",paddingLeft:5,fontSize:28}}>
        {text}
      </span>
    </span>
  );
}
Example #22
Source File: ResultTable.js    From 4IZ268-2021-2022-ZS with MIT License 4 votes vote down vote up
ResultsTable = (props) => {

    const { selectedResults, setSelectedResults } = props

    const location = useLocation()

    const compId = location.pathname.slice(location.pathname.lastIndexOf('/') + 1)

    const highlightClub = usePersonalSettings((state) => state.highlightClub)
    const clubList = useDataStore((store) => store.clubList)
    const setClubList = useDataStore((store) => store.setClubList)
    const autoRefetch = usePersonalSettings((state) => state.autoRefetch)
    const refetchInterval = usePersonalSettings((state) => state.refetchInterval)

    const [nameFilter, setNameFilter] = useState('')
    const [clubFilter, setClubFilter] = useState('')

    const { data, isLoading, isError } = useQuery(
        ['class', { comp: compId, type: selectedResults.type, value: selectedResults.value }],
        getResults,
        {
            refetchInterval: autoRefetch ? refetchInterval || 15000 : undefined,
        }
    )

    useEffect(() => {
        if (Array.isArray(data?.results)) {
            const clubs = []
            data.results.forEach((record) => {
                if (!clubList.includes(record.club) && !clubs.includes(record.club)) {
                    clubs.push(record.club)
                }
            });
            if (clubs.length) {
                setClubList([...clubList, ...clubs])
            }
        }
    }, [data, clubList, setClubList])

    if (!selectedResults.value.length) {
        return <Empty />
    }

    if (isLoading) {
        return (
            <Skeleton active title />
        )
    }

    if (isError) {
        return (
            <div>Failed to fetch data</div>
        )
    }

    const columns = [
        {
            title: '#',
            dataIndex: 'place',
            key: '#',
            render: (text) => text,
            width: '35px',
            align: 'center'
        }, {
            title: 'Jméno',
            dataIndex: 'name',
            key: 'name',
            filterDropdown: () => {
                return (
                    <div className='filterWrapper'>
                        <span>Jméno: </span>
                        <FilterInput onChange={(val) => setNameFilter(val)} />
                    </div>
                )
            },
        }
    ]

    if (selectedResults.type === 'class') {
        columns.push({
            title: 'Klub',
            dataIndex: 'club',
            key: 'club',
            filterDropdown: () => {
                return (
                    <div className='filterWrapper'>
                        <span>Klub: </span>
                        <FilterInput onChange={(val) => setClubFilter(val)} />
                    </div>
                )
            },
            render: (text) => {
                return (
                    <button onClick={() => setSelectedResults({ type: 'club', value: text })}>{text}</button>
                )
            }
        })
    } else {
        columns.push({
            title: 'Kat.',
            dataIndex: 'class',
            key: 'class',
            render: (text) => {
                return (
                    <button onClick={() => setSelectedResults({ type: 'class', value: text })}>{text}</button>
                )
            }
        })
    }

    columns.push({
        title: 'Start',
        dataIndex: 'start',
        key: 'start',
        render: (text) => {
            return formatTime(text);
        }
    })

    if (data) {
        if (Array.isArray(data.splitcontrols)) {
            if (data.splitcontrols.length) {
                data.splitcontrols.forEach((obj) => {
                    columns.push({
                        title: obj.name,
                        dataIndex: obj.code,
                        key: obj.code,
                        render: (obj) => {
                            return (
                                formatSplitResult(obj))
                        }
                    })
                })
            }
        }
        columns.push({
            title: 'Cíl',
            dataIndex: 'result',
            key: 'result',
            render: (obj) => {
                return (
                    translateFinishTime(obj)
                )
            }
        })
        columns.push({
            title: 'Ztráta',
            dataIndex: 'timeplus',
            key: 'timeplus',
            render: (obj) => {
                return (
                    translateFinishTime(obj)
                )
            }
        })
    }

    const tableData = {...data}

    if (data?.splitcontrols?.length) {
        tableData.results = data.results.map((obj) => {
            const adjusted = { ...obj };
            data.splitcontrols.forEach((splitControl) => {
                adjusted[splitControl.code] = {
                    time: obj.splits[splitControl.code],
                    place: obj.splits[splitControl.code + '_place'],
                    timeplus: obj.splits[splitControl.code + '_timeplus']
                }
            })
            return adjusted;
        })
    }

    const keyData = tableData.results.map((obj, index) => {
        return { ...obj, key: index }
    })

    const getFilteredData = () => {
        if (Array.isArray(keyData)) {
            let filteredData = [...keyData]
            if (nameFilter.length) {
                filteredData = [...filteredData.filter(obj => obj.name.includes(nameFilter))]
            }
            if (clubFilter.length) {
                filteredData = [...filteredData.filter(obj => obj.club.includes(clubFilter))]
            }
            return filteredData
        }
        else return keyData
    }

    const getRowClassName = (record, index) => {
        const isOdd = (num) => {
            return num % 2
        }

        const classNames = []

        if (isOdd(index)) {
            classNames.push('odd')
        }

        if (highlightClub?.length && record.club?.toLowerCase() === highlightClub.toLowerCase()) {
            classNames.push('highlight')
        }

        return classNames.join(' ')
    }

    return (
        <Table
            columns={columns}
            dataSource={getFilteredData()}
            pagination={false}
            size='small'
            bordered
            rowClassName={(record, index) => getRowClassName(record, index)}
            scroll={{ y: 'calc(100vh - 270px - 2.55rem)', x: true }}
        />
    )
}
Example #23
Source File: index.jsx    From ui with MIT License 4 votes vote down vote up
VolcanoPlotPage = (props) => {
  const { experimentId } = props;

  const dispatch = useDispatch();
  const comparisonCreated = useRef(false);
  const config = useSelector((state) => state.componentConfig[plotUuid]?.config);
  const {
    loading: diffExprLoading,
    data: diffExprData,
    error: diffExprError,
    cellSets: plotCellSets,
    comparisonType: plotComparisonType,
  } = useSelector(
    (state) => state.differentialExpression.properties,
  );
  const comparison = useSelector((state) => state.differentialExpression.comparison);

  const [plotData, setPlotData] = useState([]);
  const [maxYAxis, setMaxYAxis] = useState(null);
  const [spec, setSpec] = useState(null);

  useEffect(() => {
    if (!config) dispatch(loadPlotConfig(experimentId, plotUuid, plotType));

    setComparisonGroup({
      ...plotCellSets,
      type: plotComparisonType,
    });
  }, []);

  useEffect(() => {
    if (!config || !diffExprData.length) return;
    setPlotData(calculateVolcanoDataPoints(config, diffExprData));
  }, [config, diffExprData]);

  const getMaxNegativeLogPValue = (data) => data.reduce((maxNegativeLogPValue, datum, i) => {
    if (!datum.p_val_adj || datum.p_val_adj === 0) return maxNegativeLogPValue;
    return Math.max(maxNegativeLogPValue, -Math.log10(datum.p_val_adj));
  }, 0);

  useEffect(() => {
    if (plotData.length === 0) return;

    const maxNegativeLogpValue = getMaxNegativeLogPValue(plotData);
    setMaxYAxis(Math.round(maxNegativeLogpValue));
  }, [plotData]);

  const currentConfig = useRef(null);

  useEffect(() => {
    if (config && !_.isEqual(currentConfig.current !== config)) {
      currentConfig.current = config;
      setSpec(generateSpec(config, plotData));
    }
  }, [config, plotData]);

  const plotStylingConfig = [
    {
      panelTitle: 'Main schema',
      controls: [{
        name: 'volcanoDimensions',
        props: {
          xMax: 20,
          yMax: maxYAxis * 2,
        },
      }],
      children: [
        {
          panelTitle: 'Title',
          controls: ['title'],
        },
        {
          panelTitle: 'Font',
          controls: ['font'],
        },
      ],
    },
    {
      panelTitle: 'Data thresholding',
      controls: ['volcanoThresholds'],
    },
    {
      panelTitle: 'Axes and margins',
      controls: ['axes'],
    },
    {
      panelTitle: 'Colours',
      controls: ['volcanoMarkers', 'colourInversion'],
    },
    {
      panelTitle: 'Markers',
      controls: ['markers'],
    },
    {
      panelTitle: 'Add Labels',
      controls: [{
        name: 'volcanoLabels',
        props: {
          min: 0,
          max: maxYAxis + 5,
        },
      },
      ],
    },
    {
      panelTitle: 'Legend',
      controls: ['legend'],
    },
  ];

  // obj is a subset of what default config has and contains only the things we want change
  const updatePlotWithChanges = (obj) => {
    dispatch(updatePlotConfig(plotUuid, obj));
  };

  const onComputeDiffExp = () => {
    comparisonCreated.current = true;
    dispatch(
      loadDifferentialExpression(experimentId, comparison.group[comparison.type], comparison.type),
    );
    updatePlotWithChanges(comparison.group[comparison.type]);
  };

  const generateExportDropdown = () => {
    let {
      cellSet, compareWith,
    } = comparison.group[comparison.type];

    // Remove 'groups' from 'group/cluster' name for use in filename below
    if (cellSet && compareWith) {
      cellSet = getCellSetKey(cellSet);
      compareWith = getCellSetKey(compareWith);
    }

    const date = moment.utc().format('YYYY-MM-DD-HH-mm-ss');
    const fileName = `de_${experimentId}_${cellSet}_vs_${compareWith}_${date}.csv`;
    const disabled = plotData.length === 0 || diffExprLoading || diffExprError;

    return (
      <ExportAsCSV
        data={diffExprData}
        filename={fileName}
        disabled={disabled}
      />
    );
  };

  if (!config) {
    return <Skeleton />;
  }

  const renderPlot = () => {
    if (diffExprError) {
      return (
        <PlatformError
          description='Could not load differential expression data.'
          onClick={() => {
            dispatch(
              loadDifferentialExpression(
                experimentId,
                comparison.group[comparison.type],
                comparison.type,
              ),
            );
          }}
        />
      );
    }

    if (!comparisonCreated.current) {
      return (
        <Empty description='Create a comparison to get started' />
      );
    }

    if (plotData.length === 0 || diffExprLoading) {
      return <Loader experimentId={experimentId} />;
    }

    return <Vega spec={spec} renderer='canvas' />;
  };

  const renderExtraPanels = () => (
    <>
      <Panel header='Differential expression' key='differential-expression'>
        <DiffExprCompute
          experimentId={experimentId}
          onCompute={onComputeDiffExp}
        />
      </Panel>
    </>
  );

  return (
    <>
      <Header title={plotNames.VOLCANO_PLOT} />
      <PlotContainer
        experimentId={experimentId}
        plotUuid={plotUuid}
        plotType={plotType}
        plotStylingConfig={plotStylingConfig}
        extraToolbarControls={generateExportDropdown()}
        extraControlPanels={renderExtraPanels()}
        defaultActiveKey='differential-expression'
      >
        {renderPlot()}
      </PlotContainer>
    </>
  );
}
Example #24
Source File: NoticeList.js    From acy-dex-interface with MIT License 4 votes vote down vote up
export default function NoticeList({
  data = [],
  onClick,
  onClear,
  title,
  locale,
  emptyText,
  emptyImage,
  loading,
  onLoadMore,
  visible,
  loadedAll = true,
  scrollToLoad = true,
  showClear = true,
  skeletonCount = 5,
  skeletonProps = {},
}) {
  if (data.length === 0) {
    return (
      <div className={styles.notFound}>
        {emptyImage ? <img src={emptyImage} alt="not found" /> : null}
        <div>{emptyText || locale.emptyText}</div>
      </div>
    );
  }
  const loadingList = Array.from({ length: loading ? skeletonCount : 0 }).map(() => ({ loading }));
  const LoadMore = loadedAll ? (
    <div className={classNames(styles.loadMore, styles.loadedAll)}>
      <span>{locale.loadedAll}</span>
    </div>
  ) : (
    <div className={styles.loadMore} onClick={onLoadMore}>
      <span>{locale.loadMore}</span>
    </div>
  );
  const onScroll = event => {
    if (!scrollToLoad || loading || loadedAll) return;
    if (typeof onLoadMore !== 'function') return;
    const { currentTarget: t } = event;
    if (t.scrollHeight - t.scrollTop - t.clientHeight <= 40) {
      onLoadMore(event);
      ListElement = t;
    }
  };
  if (!visible && ListElement) {
    try {
      ListElement.scrollTo(null, 0);
    } catch (err) {
      ListElement = null;
    }
  }
  return (
    <div>
      <List className={styles.list} loadMore={LoadMore} onScroll={onScroll}>
        {[...data, ...loadingList].map((item, i) => {
          const itemCls = classNames(styles.item, {
            [styles.read]: item.read,
          });
          // eslint-disable-next-line no-nested-ternary
          const leftIcon = item.avatar ? (
            typeof item.avatar === 'string' ? (
              <Avatar className={styles.avatar} src={item.avatar} />
            ) : (
              <span className={styles.iconElement}>{item.avatar}</span>
            )
          ) : null;

          return (
            <List.Item className={itemCls} key={item.key || i} onClick={() => onClick(item)}>
              <Skeleton avatar title={false} active {...skeletonProps} loading={item.loading}>
                <List.Item.Meta
                  className={styles.meta}
                  avatar={leftIcon}
                  title={
                    <div className={styles.title}>
                      {item.title}
                      <div className={styles.extra}>{item.extra}</div>
                    </div>
                  }
                  description={
                    <div>
                      <div className={styles.description} title={item.description}>
                        {item.description}
                      </div>
                      <div className={styles.datetime}>{item.datetime}</div>
                    </div>
                  }
                />
              </Skeleton>
            </List.Item>
          );
        })}
      </List>
      {showClear ? (
        <div className={styles.clear} onClick={onClear}>
          {locale.clear} {title}
        </div>
      ) : null}
    </div>
  );
}
Example #25
Source File: Address.jsx    From nft-e2e-example with MIT License 4 votes vote down vote up
export default function Address(props) {
  const address = props.value || props.address;

  const ens = useLookupAddress(props.ensProvider, address);

  const { currentTheme } = useThemeSwitcher();

  if (!address) {
    return (
      <span>
        <Skeleton avatar paragraph={{ rows: 1 }} />
      </span>
    );
  }

  let displayAddress = address.substr(0, 6);

  if (ens && ens.indexOf("0x") < 0) {
    displayAddress = ens;
  } else if (props.size === "short") {
    displayAddress += "..." + address.substr(-4);
  } else if (props.size === "long") {
    displayAddress = address;
  }

  const etherscanLink = blockExplorerLink(address, props.blockExplorer);
  if (props.minimized) {
    return (
      <span style={{ verticalAlign: "middle" }}>
        <a
          style={{ color: currentTheme === "light" ? "#222222" : "#ddd" }}
          target="_blank"
          href={etherscanLink}
          rel="noopener noreferrer"
        >
          <Blockies seed={address.toLowerCase()} size={8} scale={2} />
        </a>
      </span>
    );
  }

  let text;
  if (props.onChange) {
    text = (
      <Text editable={{ onChange: props.onChange }} copyable={{ text: address }}>
        <a
          style={{ color: currentTheme === "light" ? "#222222" : "#ddd" }}
          target="_blank"
          href={etherscanLink}
          rel="noopener noreferrer"
        >
          {displayAddress}
        </a>
      </Text>
    );
  } else {
    text = (
      <Text copyable={{ text: address }}>
        <a
          style={{ color: currentTheme === "light" ? "#222222" : "#ddd" }}
          target="_blank"
          href={etherscanLink}
          rel="noopener noreferrer"
        >
          {displayAddress}
        </a>
      </Text>
    );
  }

  return (
    <span>
      <span style={{ verticalAlign: "middle" }}>
        <Blockies seed={address.toLowerCase()} size={8} scale={props.fontSize ? props.fontSize / 7 : 4} />
      </span>
      <span style={{ verticalAlign: "middle", paddingLeft: 5, fontSize: props.fontSize ? props.fontSize : 28 }}>
        {text}
      </span>
    </span>
  );
}
Example #26
Source File: index.jsx    From ui with MIT License 4 votes vote down vote up
MarkerHeatmap = ({ experimentId }) => {
  const dispatch = useDispatch();

  const [vegaSpec, setVegaSpec] = useState();

  const config = useSelector((state) => state.componentConfig[plotUuid]?.config);

  const { expression: expressionData } = useSelector((state) => state.genes);
  const { error, loading } = expressionData;

  const cellSets = useSelector(getCellSets());
  const { hierarchy, properties } = cellSets;

  const cellOptions = useSelector(getCellSetsHierarchyByType('cellSets'));

  const selectedCellSetClassAvailable = useSelector(
    getCellSetsHierarchyByKeys([config?.selectedCellSet]),
  ).length;

  const loadedMarkerGenes = useSelector(
    (state) => state.genes.expression.views[plotUuid]?.data,
  ) || [];

  const {
    loading: loadingMarkerGenes,
    error: errorMarkerGenes,
  } = useSelector((state) => state.genes.markers);

  const louvainClustersResolution = useSelector(
    (state) => state.experimentSettings.processing
      .configureEmbedding?.clusteringSettings.methodSettings.louvain.resolution,
  ) || false;

  useEffect(() => {
    if (!louvainClustersResolution) dispatch(loadProcessingSettings(experimentId));
    if (!config) dispatch(loadPlotConfig(experimentId, plotUuid, plotType));
    if (!hierarchy?.length) dispatch(loadCellSets(experimentId));
  }, []);

  useEffect(() => {
    if (louvainClustersResolution && config?.nMarkerGenes && hierarchy?.length) {
      if (selectedCellSetClassAvailable) {
        dispatch(loadMarkerGenes(
          experimentId, louvainClustersResolution,
          plotUuid, config.nMarkerGenes, config.selectedCellSet,
        ));
      } else {
        pushNotificationMessage('error', endUserMessages.NO_CLUSTERS);
      }
    }
  }, [config?.selectedCellSet, config?.nMarkerGenes, hierarchy]);

  useEffect(() => {
    if (louvainClustersResolution
      && config && hierarchy?.length) {
      dispatch(loadMarkerGenes(
        experimentId,
        louvainClustersResolution,
        plotUuid,
        config.nMarkerGenes,
        config.selectedCellSet,
      ));
    }
  }, [louvainClustersResolution]);

  useEffect(() => {
    if (!config) {
      return;
    }

    // grouping and metadata tracks should change when data is changed
    updatePlotWithChanges(
      { selectedTracks: [config.selectedCellSet], groupedTracks: [config.selectedCellSet] },
    );
  }, [config?.selectedCellSet]);

  const sortGenes = (newGenes) => {
    const clusters = hierarchy.find((cluster) => cluster.key === config.selectedCellSet).children;

    const getCellIdsForCluster = (clusterId) => properties[clusterId].cellIds;

    const getAverageExpressionForGene = (gene, currentCellIds) => {
      const expressionValues = expressionData.data[gene].rawExpression.expression;
      let totalValue = 0;
      currentCellIds.forEach((cellId) => {
        totalValue += expressionValues[cellId];
      });
      return totalValue / currentCellIds.size;
    };

    const getClusterForGene = (gene) => {
      const maxAverageExpression = { expression: 0, clusterId: -1 };

      clusters.forEach((cluster, clusterIndx) => {
        const currentCellIds = getCellIdsForCluster(cluster.key);
        const currentAverageExpression = getAverageExpressionForGene(gene, currentCellIds);
        if (currentAverageExpression > maxAverageExpression.expression) {
          maxAverageExpression.expression = currentAverageExpression;
          maxAverageExpression.clusterId = clusterIndx;
        }
      });
      return maxAverageExpression.clusterId;
    };

    const newOrder = _.cloneDeep(config.selectedGenes);

    newGenes.forEach((gene) => {
      const clusterIndx = getClusterForGene(gene);
      newOrder.forEach((oldGene) => {
        if (!_.includes(newOrder, gene)) {
          const currentClusterIndx = getClusterForGene(oldGene);
          if (currentClusterIndx === clusterIndx) {
            const geneIndex = newOrder.indexOf(oldGene);
            newOrder.splice(geneIndex, 0, gene);
          }
        }
      });
    });
    return newOrder;
  };

  const reSortGenes = () => {
    const newGenes = _.difference(loadedMarkerGenes, config.selectedGenes);
    let newOrder;

    if (!newGenes.length) {
      // gene was removed instead of added - no need to sort
      const removedGenes = _.difference(config.selectedGenes, loadedMarkerGenes);
      newOrder = _.cloneDeep(config.selectedGenes);
      newOrder = newOrder.filter((gene) => !removedGenes.includes(gene));
    } else if (newGenes.length === 1) {
      // single gene difference - added manually by user
      newOrder = sortGenes(newGenes);
    } else {
      // selected data was changed
      newOrder = loadedMarkerGenes;
    }

    return newOrder;
  };

  useEffect(() => {
    if (!config || _.isEmpty(expressionData)) {
      return;
    }
    if (loadedMarkerGenes.length && !config.selectedGenes.length) {
      updatePlotWithChanges({ selectedGenes: loadedMarkerGenes });
      return;
    }

    if (loadedMarkerGenes.length !== config.selectedGenes.length) {
      const newOrder = reSortGenes();
      updatePlotWithChanges({ selectedGenes: newOrder });
    }
  }, [loadedMarkerGenes, config?.selectedGenes]);

  useEffect(() => {
    if (cellSets.loading
      || _.isEmpty(expressionData)
      || _.isEmpty(loadedMarkerGenes)
      || !loading
      || !hierarchy?.length
    ) {
      return;
    }

    const data = populateHeatmapData(cellSets, config, expressionData, config.selectedGenes, true);
    const spec = generateSpec(config, 'Cluster ID', data, true);

    spec.description = 'Marker heatmap';

    const extraMarks = {
      type: 'rule',
      from: { data: 'clusterSeparationLines' },
      encode: {
        enter: {
          stroke: { value: 'white' },
        },
        update: {
          x: { scale: 'x', field: 'data' },
          y: 0,
          y2: { field: { group: 'height' } },
          strokeWidth: { value: 1 },
          strokeOpacity: { value: 1 },
        },
      },
    };
    spec.marks.push(extraMarks);

    setVegaSpec(spec);
  }, [config, cellSets]);

  useEffect(() => {
    const state = {
      sorter: {
        field: 'gene_names',
        columnKey: 'gene_names',
        order: 'ascend',
      },
      pagination: {
        current: 1,
        pageSize: 100000,
      },
      pageSizeFilter: null,
    };

    dispatch(loadPaginatedGeneProperties(experimentId, ['dispersions'], searchBarUuid, state));
  }, []);

  // updatedField is a subset of what default config has and contains only the things we want change
  const updatePlotWithChanges = (updatedField) => {
    dispatch(updatePlotConfig(plotUuid, updatedField));
  };

  const plotStylingConfig = [
    {
      panelTitle: 'Expression values',
      controls: ['expressionValuesType', 'expressionValuesCapping'],
    },
    {
      panelTitle: 'Main schema',
      controls: ['dimensions'],
      children: [
        {
          panelTitle: 'Title',
          controls: ['title'],
        },
        {
          panelTitle: 'Font',
          controls: ['font'],
        },
      ],
    },
    {
      panelTitle: 'Colours',
      controls: ['colourScheme'],
    },
    {
      panelTitle: 'Legend',
      controls: [
        {
          name: 'legend',
          props: {
            option: {
              positions: 'horizontal-vertical',
            },
          },
        },
      ],
    },
  ];
  const onGeneEnter = (genes) => {
    dispatch(loadGeneExpression(experimentId, genes, plotUuid));
  };

  const onReset = () => {
    onGeneEnter([]);
    dispatch(loadMarkerGenes(
      experimentId,
      louvainClustersResolution,
      plotUuid,
      config.nMarkerGenes,
      config.selectedCellSet,
    ));
  };

  if (!config || cellSets.loading || hierarchy.length === 0) {
    return (<Skeleton />);
  }

  const clustersForSelect = getSelectOptions(cellOptions);

  const changeClusters = (option) => {
    const newValue = option.value.toLowerCase();
    updatePlotWithChanges({ selectedCellSet: newValue });
  };

  const renderExtraPanels = () => (
    <>
      <Panel header='Gene selection' key='gene-selection'>
        <Tabs defaultActiveKey='1'>
          <TabPane tab='Add/Remove genes' key='1'>
            <MarkerGeneSelection
              config={config}
              onUpdate={updatePlotWithChanges}
              onGeneEnter={onGeneEnter}
              onReset={onReset}
            />
            <div>
              <p>Gene labels:</p>
              <Radio.Group
                onChange={
                  (e) => updatePlotWithChanges({ showGeneLabels: e.target.value })
                }
                value={config.showGeneLabels}
              >
                <Radio value>Show</Radio>
                <Radio value={false}>Hide</Radio>
              </Radio.Group>
            </div>
          </TabPane>
          <TabPane tab='Search for and re-order genes' key='2'>
            <p>Type in a gene name and select it to add it to the heatmap. Drag and drop genes to re-order them.</p>
            {/* space needed to separate search box and reorder tree, display=flex fills the space */}
            <Space direction='vertical' style={{ display: 'flex' }}>
              <GeneSearchBar
                plotUuid={plotUuid}
                experimentId={experimentId}
                searchBarUuid={searchBarUuid}
              />
              <GeneReorderTool
                plotUuid={plotUuid}
              />
            </Space>
          </TabPane>
        </Tabs>
      </Panel>
      <Panel header='Select data' key='select-data'>
        <Space direction='vertical' size='small'>
          <p>Select cell sets to show in the heatmap:</p>
          <Select
            value={{
              value: config.selectedCellSet,
            }}
            onChange={changeClusters}
            labelInValue
            style={{ width: '100%' }}
            placeholder='Select cell set...'
            options={clustersForSelect}
          />
        </Space>
      </Panel>
      <Panel header='Cluster guardlines' key='cluster-guardlines'>
        <Radio.Group
          value={config.guardLines}
          onChange={(e) => updatePlotWithChanges({ guardLines: e.target.value })}
        >
          <Radio value>Show</Radio>
          <Radio value={false}>Hide</Radio>
        </Radio.Group>
      </Panel>
      <Panel header='Metadata tracks' key='metadata-tracks'>
        <HeatmapMetadataTracksSettings componentType={plotUuid} />
      </Panel>
      <Panel header='Group by' key='group-by'>
        <HeatmapGroupBySettings componentType={plotUuid} />
      </Panel>
    </>
  );

  const renderPlot = () => {
    if (error) {
      return (
        <PlatformError
          description='Could not load gene expression data.'
          error={error}
          onClick={() => dispatch(loadGeneExpression(experimentId, config.selectedGenes, plotUuid))}
        />
      );
    }

    if (errorMarkerGenes) {
      return (
        <PlatformError
          description='Could not load marker genes.'
          error={errorMarkerGenes}
          onClick={
            () => dispatch(
              loadMarkerGenes(
                experimentId, louvainClustersResolution,
                plotUuid, config.nMarkerGenes, config.selectedCellSet,
              ),
            )
          }
        />
      );
    }

    if (!config
      || loading.length > 0
      || cellSets.loading
      || loadingMarkerGenes
      || !config.selectedGenes.length) {
      return (<Loader experimentId={experimentId} />);
    }

    if (loadedMarkerGenes.length === 0) {
      return (
        <Empty description='Add some genes to this heatmap to get started.' />
      );
    }

    if (vegaSpec) {
      return <Vega spec={vegaSpec} renderer='canvas' />;
    }
  };

  return (
    <>
      <Header title={plotNames.MARKER_HEATMAP} />
      <PlotContainer
        experimentId={experimentId}
        plotUuid={plotUuid}
        plotType={plotType}
        plotStylingConfig={plotStylingConfig}
        extraControlPanels={renderExtraPanels()}
        defaultActiveKey='gene-selection'
      >
        {renderPlot()}
      </PlotContainer>
    </>
  );
}
Example #27
Source File: Address.jsx    From Tai-Shang-NFT-Wallet with MIT License 4 votes vote down vote up
export default function Address(props) {
  const address = props.value || props.address;

  const ens = useLookupAddress(props.ensProvider, address);

  const { currentTheme } = useThemeSwitcher();

  if (!address) {
    return (
      <span>
        <Skeleton avatar paragraph={{ rows: 1 }} />
      </span>
    );
  }

  let displayAddress = address.substr(0, 6);

  if (ens && ens.indexOf("0x") < 0) {
    displayAddress = ens;
  } else if (props.size === "short") {
    displayAddress += "..." + address.substr(-4);
  } else if (props.size === "long") {
    displayAddress = address;
  }

  const etherscanLink = blockExplorerLink(address, props.blockExplorer);
  if (props.minimized) {
    return (
      <span style={{ verticalAlign: "middle" }}>
        <a
          style={{ color: currentTheme === "light" ? "#222222" : "#ddd" }}
          target="_blank"
          href={etherscanLink}
          rel="noopener noreferrer"
        >
          <Blockies seed={address.toLowerCase()} size={8} scale={2} />
        </a>
      </span>
    );
  }

  let text;
  if (props.onChange) {
    text = (
      <Text editable={{ onChange: props.onChange }} copyable={{ text: address }}>
        <a
          style={{ color: currentTheme === "light" ? "#222222" : "#ddd" }}
          target="_blank"
          href={etherscanLink}
          rel="noopener noreferrer"
        >
          {displayAddress}
        </a>
      </Text>
    );
  } else {
    text = (
      <Text copyable={{ text: address }}>
        <a
          style={{ color: currentTheme === "light" ? "#222222" : "#ddd" }}
          target="_blank"
          href={etherscanLink}
          rel="noopener noreferrer"
        >
          {displayAddress}
        </a>
      </Text>
    );
  }

  return (
    <span>
      <span style={{ verticalAlign: "middle" }}>
        <Blockies seed={address.toLowerCase()} size={8} scale={props.fontSize ? props.fontSize / 7 : 4} />
      </span>
      <span style={{ verticalAlign: "middle", paddingLeft: 5, fontSize: props.fontSize ? props.fontSize : 28 }}>
        {text}
      </span>
    </span>
  );
}
Example #28
Source File: Address.jsx    From moonshot with MIT License 4 votes vote down vote up
export default function Address(props) {
  const address = props.value || props.address;

  const ens = useLookupAddress(props.ensProvider, address);

  // const { currentTheme } = useThemeSwitcher();
  const currentTheme = "light";

  if (!address) {
    return (
      <span>
        <Skeleton avatar paragraph={{ rows: 1 }} />
      </span>
    );
  }

  let displayAddress = address.substr(0, 6);

  if (ens && ens.indexOf("0x") < 0) {
    displayAddress = ens;
  } else if (props.size === "short") {
    displayAddress += "..." + address.substr(-4);
  } else if (props.size === "long") {
    displayAddress = address;
  }

  const etherscanLink = blockExplorerLink(address, props.blockExplorer);
  if (props.minimized) {
    return (
      <span style={{ verticalAlign: "middle" }}>
        <a
          style={{ color: currentTheme == "light" ? "#222222" : "#ddd" }}
          target="_blank"
          href={etherscanLink}
          rel="noopener noreferrer"
        >
          <Blockies seed={address.toLowerCase()} size={8} scale={2} />
        </a>
      </span>
    );
  }

  let text;
  if (props.noLink) {
    text = <Text>{displayAddress}</Text>;
  } else if (props.onChange) {
    text = (
      <Text editable={{ onChange: props.onChange }} copyable={{ text: address }}>
        <a
          style={{ color: currentTheme == "light" ? "#222222" : "#ddd" }}
          target="_blank"
          href={etherscanLink}
          rel="noopener noreferrer"
        >
          {displayAddress}
        </a>
      </Text>
    );
  } else {
    text = (
      <Text copyable={{ text: address }}>
        <a
          style={{ color: currentTheme == "light" ? "#222222" : "#ddd" }}
          target="_blank"
          href={etherscanLink}
          rel="noopener noreferrer"
        >
          {displayAddress}
        </a>
      </Text>
    );
  }

  return (
    <span>
      <span style={{ verticalAlign: "middle" }}>
        <Blockies seed={address.toLowerCase()} size={8} scale={props.fontSize ? props.fontSize / 7 : 4} />
      </span>
      <span style={{ verticalAlign: "middle", paddingLeft: 5, fontSize: props.fontSize ? props.fontSize : 28 }}>
        {text}
      </span>
    </span>
  );
}
Example #29
Source File: Address.jsx    From quadratic-diplomacy with MIT License 4 votes vote down vote up
export default function Address(props) {
  const address = props.value || props.address;

  const ens = useLookupAddress(props.ensProvider, address);

  const { currentTheme } = useThemeSwitcher();

  if (!address) {
    return (
      <span>
        <Skeleton avatar paragraph={{ rows: 1 }} />
      </span>
    );
  }

  let displayAddress = address.substr(0, 6);

  if (ens && ens.indexOf("0x") < 0) {
    displayAddress = ens;
  } else if (props.size === "short") {
    displayAddress += "..." + address.substr(-4);
  } else if (props.size === "long") {
    displayAddress = address;
  }

  const etherscanLink = blockExplorerLink(address, props.blockExplorer);
  if (props.minimized) {
    return (
      <span style={{ verticalAlign: "middle" }}>
        <a
          style={{ color: currentTheme === "light" ? "#222222" : "#C9B8FF" }}
          target="_blank"
          href={etherscanLink}
          rel="noopener noreferrer"
        >
          <Blockies seed={address.toLowerCase()} size={8} scale={2} />
        </a>
      </span>
    );
  }

  let text;
  if (props.onChange) {
    text = (
      <Text editable={{ onChange: props.onChange }} copyable={{ text: address }}>
        <a
          style={{ color: currentTheme === "light" ? "#222222" : "#C9B8FF" }}
          target="_blank"
          href={etherscanLink}
          rel="noopener noreferrer"
        >
          {displayAddress}
        </a>
      </Text>
    );
  } else {
    text = (
      <Text copyable={{ text: address }}>
        <a
          style={{ color: currentTheme === "light" ? "#222222" : "#C9B8FF" }}
          target="_blank"
          href={etherscanLink}
          rel="noopener noreferrer"
        >
          {displayAddress}
        </a>
      </Text>
    );
  }

  return (
    <span>
      <span style={{ verticalAlign: "middle" }}>
        <Blockies seed={address.toLowerCase()} size={8} scale={props.fontSize ? props.fontSize / 7 : 4} />
      </span>
      <span style={{ verticalAlign: "middle", paddingLeft: 5, fontSize: props.fontSize ? props.fontSize : 28 }}>
        {text}
      </span>
    </span>
  );
}