@ant-design/icons#QuestionCircleOutlined JavaScript Examples

The following examples show how to use @ant-design/icons#QuestionCircleOutlined. 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: HelpButton.jsx    From ui with MIT License 6 votes vote down vote up
HelpButton = () => {
  const [visible, setVisible] = useState(false);

  const overlay = () => (
    <Card size='small' style={{ padding: '1em', width: '265px' }}>
      For tutorial videos, ‘how to’ guides and FAQs on how to use Cellenics, visit
      {' '}
      <a href='https://www.biomage.net/get-started' target='_blank' rel='noreferrer'>our website</a>
      .
      <br />
      <br />
      If you need additional help with your analysis, email:
      {' '}
      <a href='mailto:[email protected]'>[email protected]</a>
    </Card>
  );

  return (
    <Dropdown
      visible={visible}
      onVisibleChange={(v) => setVisible(v)}
      overlay={overlay}
      placement='bottomRight'
      trigger='click'
    >
      <Button
        type='dashed'
        icon={<QuestionCircleOutlined />}
      >
        Help & resources
        <DownOutlined />
      </Button>
    </Dropdown>
  );
}
Example #2
Source File: icon.jsx    From virtuoso-design-system with MIT License 5 votes vote down vote up
storiesOf('antd/popconfirm', module).add('icon', () => 
  <Popconfirm title="Are you sure?" icon={<QuestionCircleOutlined style={{ color: 'red' }} />}>
    <a href="#">Delete</a>
  </Popconfirm>,
  { docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Set <code>icon</code> props to customize the icon.</p></>) } });
Example #3
Source File: TrackEnroll.js    From codeclannigeria-frontend with MIT License 5 votes vote down vote up
function TrackEnroll({
  visible,
  getTracksAction,
  loading,
  error,
  userEnrollTrackAction,
  errResponse,
  data,
  onCancel,
}) {
  const [current, setCurrent] = useState(0);
  const [trackId, setTrackId] = useState(null);
  const [mentorId, setMentorId] = useState(null);

  const [trackTitle, setTrackTitle] = useState(null);
  const [currentPage, setCurrentPage] = useState(1);
  // eslint-disable-next-line
  const [trackPerPage, setTrackperPage] = useState(3);

  const indexOfLastTrack = currentPage * trackPerPage;
  const indexOfFirstTrack = indexOfLastTrack - trackPerPage;
  const { items } = data;

  const paginate = pageNumber => setCurrentPage(pageNumber);
  const currentTracks = items
    ? items.slice(indexOfFirstTrack, indexOfLastTrack)
    : null;

  const getTrackName = id => {
    const track = items.filter(data => data.id === id);
    setTrackTitle(track[0].title);
  };
  function next() {
    const newCurrent = current + 1;
    setCurrent(newCurrent);
  }

  function prev() {
    const newCurrent = current - 1;
    setCurrent(newCurrent);
  }

  const handleSetTrackId = e => {
    setTrackId(e.target.value);
  };

  const handleSetMentorId = e => {
    setMentorId(e.target.value);
  };

  const handleEnrollTrack = async (trackId, mentorId) => {
    try {
      await userEnrollTrackAction(trackId, mentorId);
      await getTrackName(trackId);
    } catch (error) {}
    next();
  };

  useEffect(() => {
    getTracksAction();
  }, [getTracksAction]);

  return (
    <TrackEnrollStyled>
      <Modal
        visible={visible}
        onCancel={onCancel}
        className="custom-ant-modal"
        footer={null}
        closable={false}
      >
        <Steps current={current}>
          {steps.map(item => (
            <Step key={item.title} title={item.title} />
          ))}
        </Steps>

        {current === 0 && items ? (
          <React.Fragment>
            <Radio.Group onChange={handleSetTrackId} defaultValue={null}>
              <div className="tracks-card">
                {currentTracks ? (
                  currentTracks.map((item, idx) => (
                    <TrackCard
                      next={next}
                      data={item}
                      key={idx}
                      logo={tempCourseLogo}
                    />
                  ))
                ) : (
                  <CustomLoader />
                )}
              </div>
            </Radio.Group>
            <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
              <Pagination
                // postPerPage={postPerPage}
                total={items.length}
                defaultCurrent={currentPage}
                // paginate={paginate}
                onChange={paginate}
                pageSize={trackPerPage}
                showSizeChanger={false}
              />
            </div>
          </React.Fragment>
        ) : null}
        {current === 1 ? <TracksEnrollStages id={trackId} /> : null}
        {current === 2 ? (
          <React.Fragment>
            <SelectMentorStep
              trackId={trackId}
              handleSetMentorId={handleSetMentorId}
            />
          </React.Fragment>
        ) : null}

        {current === 3 ? (
          <EnrollmentStatus
            status={error ? 'error' : 'success'}
            title={trackTitle}
            prev={prev}
          />
        ) : null}

        <div className="steps-action">
          {current === 0 && (
            <Button type="primary" disabled={!trackId} onClick={() => next()}>
              Next
            </Button>
          )}

          {current === 1 && (
            <React.Fragment>
              <Button type="default" onClick={() => prev()}>
                Back
              </Button>

              <Popconfirm
                title="Are you sure?"
                onConfirm={() => next()}
                icon={<QuestionCircleOutlined style={{ color: 'green' }} />}
              >
                <Button type="primary" className="ml-2">
                  Next
                </Button>
              </Popconfirm>
            </React.Fragment>
          )}

          {current === 2 && (
            <React.Fragment>
              <Button type="default" onClick={() => prev()}>
                Back
              </Button>

              <Popconfirm
                title="Are you sure?"
                onConfirm={() => handleEnrollTrack(trackId, mentorId)}
                icon={<QuestionCircleOutlined style={{ color: 'green' }} />}
                disabled={!mentorId}
              >
                <Button type="primary" disabled={!mentorId} className="ml-2">
                  Enroll
                </Button>
              </Popconfirm>
            </React.Fragment>
          )}
          {current === 3 && (
            <Button type="primary" onClick={() => onCancel()}>
              Done
            </Button>
          )}
        </div>
      </Modal>
    </TrackEnrollStyled>
  );
}
Example #4
Source File: Header.js    From react-admin-portal with MIT License 5 votes vote down vote up
function Header({ addNewPath, hasSelected, handleSearch }) {
  const history = useHistory();

  const handleAddNew = () => {
    history.push('/' + addNewPath);
  };

  return (
    <>
      <Row>
        <Col>
          <Search
            placeholder="Search"
            onSearch={handleSearch}
            allowClear
            style={{ float: 'left', width: 350 }}
          />
        </Col>
        <Col flex="auto">
          <Button
            icon={<PlusOutlined />}
            type="primary"
            style={{ float: 'right' }}
            onClick={handleAddNew}
          >
            Add New
          </Button>

          <Button
            icon={<DeleteOutlined />}
            disabled={!hasSelected}
            style={{ float: 'right', marginRight: 12 }}
          >
            <Popconfirm
              title="Sure to delete?"
              icon={<QuestionCircleOutlined style={{ color: 'red' }} />}
              onConfirm={() => {}}
            >
              Delete
            </Popconfirm>
          </Button>
        </Col>
      </Row>
      <Divider />
    </>
  );
}
Example #5
Source File: ActionMenu.js    From react-admin-portal with MIT License 5 votes vote down vote up
function useActionMenu({ selectedRow, updateEntityPath }) {
  const history = useHistory();

  const handleMenuClick = action => {
    if (action.key === 'edit') {
      const updatePath = '/' + updateEntityPath + '/' + selectedRow.id;
      history.push(updatePath);
    }
  };

  const handleSingleDelete = () => {
    console.log('handleSingleDelete, selected:', selectedRow);
  };

  const actionMenu = (
    <Menu onClick={handleMenuClick}>
      <Menu.Item key="edit">
        <EditOutlined />
        Update
      </Menu.Item>
      <Menu.Item key="delete">
        <Popconfirm
          title="Sure to delete?"
          placement="left"
          icon={<QuestionCircleOutlined style={{ color: 'red' }} />}
          onConfirm={handleSingleDelete}
        >
          <DeleteOutlined type="delete" />
          Delete
        </Popconfirm>
      </Menu.Item>
    </Menu>
  );

  const actionColumnView = (
    <span>
      <Dropdown overlay={actionMenu} trigger={['click']}>
        <a className="ant-dropdown-link" href="#">
          Actions <DownOutlined />
        </a>
      </Dropdown>
    </span>
  );

  return [actionColumnView];
}
Example #6
Source File: RightContent.jsx    From the-eye-knows-the-garbage with MIT License 5 votes vote down vote up
GlobalHeaderRight = props => {
  const { theme, layout } = props;
  let className = styles.right;

  if (theme === 'dark' && layout === 'top') {
    className = `${styles.right}  ${styles.dark}`;
  }

  return (
    <div className={className}>
      {/*<HeaderSearch*/}
      {/*  className={`${styles.action} ${styles.search}`}*/}
      {/*  placeholder="站内搜索"*/}
      {/*  defaultValue="umi ui"*/}
      {/*  options={[*/}
      {/*    {*/}
      {/*      label: <a href="https://umijs.org/zh/guide/umi-ui.html">umi ui</a>,*/}
      {/*      value: 'umi ui',*/}
      {/*    },*/}
      {/*    {*/}
      {/*      label: <a href="next.ant.design">Ant Design</a>,*/}
      {/*      value: 'Ant Design',*/}
      {/*    },*/}
      {/*    {*/}
      {/*      label: <a href="https://protable.ant.design/">Pro Table</a>,*/}
      {/*      value: 'Pro Table',*/}
      {/*    },*/}
      {/*    {*/}
      {/*      label: <a href="https://prolayout.ant.design/">Pro Layout</a>,*/}
      {/*      value: 'Pro Layout',*/}
      {/*    },*/}
      {/*  ]} // onSearch={value => {*/}
      {/*  //   //console.log('input', value);*/}
      {/*  // }}*/}
      {/*/>*/}
      <Tooltip title="使用文档">
        <a
          style={{
            color: 'inherit',
          }}
          target="_blank"
          href="https://github.com/mtianyan/tyadmin_api_cli"
          rel="noopener noreferrer"
          className={styles.action}
        >
          <QuestionCircleOutlined />
        </a>
      </Tooltip>
      {/*<NoticeIconView />*/}
      <Avatar />
      {REACT_APP_ENV && (
        <span>
          <Tag color={ENVTagColor[REACT_APP_ENV]}>{REACT_APP_ENV}</Tag>
        </span>
      )}
      <SelectLang className={styles.action} />
    </div>
  );
}
Example #7
Source File: index.js    From bank-client with MIT License 5 votes vote down vote up
function Recipient({ intl, onValidateFields }) {
  const { recipients } = useSelector(stateSelector);
  const dispatch = useDispatch();

  const onChangeRecipientAccountBill = (name, value) =>
    dispatch(changeInputAction({ name, value }));
  const onSearchRecipient = (value) =>
    value && dispatch(searchRecipientAction(value));

  const checkStringConsistsNumbersOnly = (_, value) => {
    if (value && !numberValidation(value)) {
      return Promise.reject(
        new Error(intl.formatMessage(messages.validationNumber)),
      );
    }

    if (!value) {
      return Promise.reject(new Error(intl.formatMessage(messages.validation)));
    }

    return Promise.resolve();
  };

  const options = recipients.map((recipient) => ({
    label: (
      <>
        <div>
          {recipient.user.firstName} {recipient.user.lastName}
        </div>
        <div>{recipient.accountBillNumber}</div>
      </>
    ),
    value: recipient.accountBillNumber.replace(/ /g, ''),
  }));

  return (
    <StyledFormItem
      label={intl.formatMessage(messages.label)}
      name="recipientBill"
      rules={[{ validator: checkStringConsistsNumbersOnly }]}
    >
      <AutoComplete
        onSearch={onSearchRecipient}
        onChange={(value) =>
          onChangeRecipientAccountBill('recipientAccountBillNumber', value)
        }
        options={options}
        notFoundContent={
          <div>
            <FormattedMessage {...messages.notFoundContent} />
          </div>
        }
      >
        <Input
          onPressEnter={onValidateFields}
          onKeyPress={disabledSpacesInput}
          maxLength="26"
          placeholder={intl.formatMessage(messages.placeholder)}
          suffix={
            <Tooltip title={intl.formatMessage(messages.tooltip)}>
              <QuestionCircleOutlined />
            </Tooltip>
          }
        />
      </AutoComplete>
    </StyledFormItem>
  );
}
Example #8
Source File: NormalisationOptions.jsx    From ui with MIT License 4 votes vote down vote up
NormalisationOptions = (props) => {
  const {
    config, onUpdate, onChange, disabled, methodId,
  } = props;

  const [numGenes, setNumGenes] = useState(config.numGenes);

  return (
    <>
      <Form.Item label='# of HVGs'>
        <InputNumber
          value={numGenes}
          step={100}
          min={1}
          onChange={(value) => {
            onChange();
            setNumGenes(value);
          }}
          onPressEnter={(e) => e.preventDefault()}
          onStep={(value) => onUpdate({
            dataIntegration: {
              methodSettings: {
                [methodId]: {
                  numGenes: value,
                },
              },
            },
          })}
          onBlur={(e) => onUpdate({
            dataIntegration: {
              methodSettings: {
                [methodId]: {
                  numGenes: parseInt(e.target.value, 0),
                },
              },
            },
          })}
          disabled={disabled}
        />
        {' '}
        <Tooltip overlay={(
          <span>
            Number of genes to mark as top highly variable genes (HVGs).
            Integration as well as PCA is based on a sensible selection of HVGs.
            Here, this number selects the top variable genes based on the "vst" method.
            The default 2000 has been found to be a sensible for many cases.
            Further info can be found
            <a
              href='https://satijalab.org/seurat/articles/integration_introduction.html'
              target='_blank'
              rel='noreferrer'
            >
              {' '}
              <code>here</code>
            </a>
          </span>
        )}
        >
          <QuestionCircleOutlined />
        </Tooltip>
      </Form.Item>
      <Form.Item label={(
        <span>
          Normalization&nbsp;
          <Tooltip overlay={(
            <span>
              Normalization aims to remove technical variation that is not biologically relevant, e.g. sequencing depth.
              There are several methods to achieve normalization.
              "sctransform" claims to recover sharper biological distinction compared to log-normalization.
              Normalization is applied to each sample before integration.
              Further info can be found
              <a
                href='https://satijalab.org/seurat/articles/sctransform_vignette.html'
                target='_blank'
                rel='noreferrer'
              >
                {' '}
                <code>here</code>
              </a>
            </span>
          )}
          >
            <QuestionCircleOutlined />
          </Tooltip>
        </span>
      )}
      >
        <Select
          value={config.normalisation}
          onChange={(val) => onUpdate({
            dataIntegration: {
              methodSettings: {
                [methodId]: { normalisation: val },
              },
            },
          })}
          disabled={disabled}
        >
          <Option value='logNormalize'>LogNormalize</Option>

          {/* scTransform is disabled until implemented in the QC pipeline */}
          <Option disabled value='scTransform'>
            <Tooltip title='Will be supported in a later version' placement='left'>
              SCTransform
            </Tooltip>
          </Option>
        </Select>

      </Form.Item>
    </>
  );
}
Example #9
Source File: LayoutBanner.js    From react-admin-portal with MIT License 4 votes vote down vote up
function LayoutBanner({ collapsed, handleOnCollapse }) {
  const getCollapseIcon = () => {
    if (collapsed) {
      return (
        <MenuUnfoldOutlined onClick={handleOnCollapse} className="trigger" />
      );
    }
    return <MenuFoldOutlined onClick={handleOnCollapse} className="trigger" />;
  };

  const handleLanguageMenuClick = () => {};
  const handleSettingMenuClick = () => {};
  const handleLogout = () => {};

  return (
    <Header className="header" style={{ background: '#fff', padding: 0 }}>
      <div
        style={{
          float: 'left',
          width: '100%',
          alignSelf: 'center',
          display: 'flex',
        }}
      >
        {window.innerWidth > 992 && getCollapseIcon()}
      </div>
      <Menu
        // onClick={this.handleLanguageMenuClick}
        mode="horizontal"
        className="menu"
      >
        <SubMenu title={<QuestionCircleOutlined />} />
      </Menu>
      <Menu
        // onClick={this.handleLanguageMenuClick}
        mode="horizontal"
        className="menu"
      >
        <SubMenu
          title={
            <Badge dot>
              <BellOutlined />
            </Badge>
          }
        />
      </Menu>
      <Menu
        onClick={handleLanguageMenuClick}
        mode="horizontal"
        className="menu"
      >
        <SubMenu title={<GlobalOutlined />}>
          <Menu.Item key="en">
            <span role="img" aria-label="English">
              ?? English
            </span>
          </Menu.Item>
          <Menu.Item key="it">
            <span role="img" aria-label="Italian">
              ?? Italian
            </span>
          </Menu.Item>
        </SubMenu>
      </Menu>
      <Menu onClick={handleSettingMenuClick} mode="horizontal" className="menu">
        <SubMenu title={getUsernameAvatar('Cemal')}>
          <Menu.Item key="setting:1">
            <span>
              <UserOutlined />
              Profile
            </span>
          </Menu.Item>
          <Menu.Item key="setting:2">
            <span>
              <LogoutOutlined onClick={handleLogout} />
              Logout
            </span>
          </Menu.Item>
        </SubMenu>
      </Menu>
    </Header>
  );
}
Example #10
Source File: App.js    From hashcat.launcher with MIT License 4 votes vote down vote up
render() {
		return (
			<Layout>
				<Sider
					style={{
						overflow: 'auto',
						height: '100vh',
						position: 'fixed',
						left: 0
					}}
					collapsed
				>
					<Menu theme="dark" onSelect={this.onSelectMenu} defaultSelectedKeys={[this.state.currentView]} mode="inline">
						<Menu.Item key="New Task" icon={<PlusOutlined />}>
							New Task
						</Menu.Item>
						<Menu.Item key="Tasks" icon={<UnorderedListOutlined />}>
							Tasks
						</Menu.Item>
						<Menu.Item key="Settings" icon={<SettingOutlined />}>
							Settings
						</Menu.Item>
						<Menu.Divider />
						<Menu.Item key="Tools" icon={<DeploymentUnitOutlined />}>
							Tools
						</Menu.Item>
						<Menu.Divider />
						<Menu.Item key="Help" icon={<QuestionCircleOutlined />}>
							Help
						</Menu.Item>
						<Menu.Item key="About" icon={<InfoCircleOutlined />}>
							About
						</Menu.Item>
					</Menu>
				</Sider>

				<div style={{ marginLeft: '80px'}}></div>

				<Layout style={{ height: "100vh" }}>
					<Header
						style={{
							display: 'flex',
							alignItems: 'center',
							position: 'fixed',
							zIndex: 1,
							width: '100%',
							backgroundColor: '#000',
							borderBottom: '1px #1d1d1d solid'
						}}
					>
						<img style={{ height: '100%'}} src={require('./images/Icon.png').default} />
						<Title level={3} style={{ margin: '0 10px', color: '#fff' }}>
							hashcat.launcher
						</Title>
						<span>
							{this.state.version ? (
								this.state.version === "dev" ? (
									"dev"
								) : (
									"v" + this.state.version
								)
							) : "dev"}
						</span>
					</Header>

					<div style={{ marginTop: '64px'}}></div>

					{this.state.isLoadedHashcat === false && (
						<Alert
							style={{ maxHeight: "38px" }}
							type="warning"
							message={
								<Tooltip
									title={
										<>
											hashcat is expected to be in the same directory as hashcat.launcher
											inside a subfolder <Text code>/hashcat</Text>
										</>
									}
								>
									hashcat not found
								</Tooltip>
							}
							banner
						/>
					)}

					<div
						style={{ display: this.state.currentView === "New Task" ? "block" : "none" }}
					>
						{this.newTaskView}
					</div>

					<div
						style={{
							display: this.state.currentView === "Tasks" ? "flex" : "none",
							flexDirection: "column",
							flex: "1 0 auto",
							maxHeight: this.state.isLoadedHashcat === false ? "calc(100% - 64px - 38px)" : "calc(100% - 64px)"
						}}
					>
						{this.tasksView}
					</div>

					<div
						style={{ display: this.state.currentView === "Settings" ? "block" : "none" }}
					>
						{this.settingsView}
					</div>

					<div
						style={{ display: this.state.currentView === "Tools" ? "block" : "none" }}
					>
						{this.toolsView}
					</div>

					<div
						style={{ display: this.state.currentView === "Help" ? "block" : "none" }}
					>
						{this.helpView}
					</div>

					<div
						style={{ display: this.state.currentView === "About" ? "block" : "none" }}
					>
						{this.aboutView}
					</div>
				</Layout>
			</Layout>
		)
	}
Example #11
Source File: head.js    From ant-simple-pro with MIT License 4 votes vote down vote up
TopBar = memo(function TopBar({
  collapsed,
  onToggle,
  width,
  setIsMobileDrawer,
}) {
  const moreList = [
    { title: 'ant-simple-pro(vue3.0)', url: 'https://lgf196.top/vue/' },
    {
      title: 'ant-simple-pro(afterEnd)',
      url: 'https://github.com/lgf196/ant-simple-pro/tree/afterEnd',
    },
    {
      title: 'ant-simple-draw(图形编辑器)',
      url: 'https://github.com/lgf196/ant-simple-draw',
    },
    {
      title: 'ant-simple-pro(angular)',
      url: 'https://github.com/lgf196/ant-simple-pro/tree/angular/angular',
    },
    {
      title: 'h5-Dooring(可视化)',
      url: 'https://github.com/MrXujiang/h5-Dooring',
    },
  ];

  const history = useHistory();

  const dispatch = useDispatch();

  useEffect(() => {
    dispatch({ type: SAGA_GET_USER_INFO });
  }, [dispatch]);

  const selectNumOfDoneTodos = createSelector(
    [(state) => state.user.getUserInfo, (state) => state.user.loadingUserInfo],
    (getUserInfo, loadingUserInfo) => [getUserInfo, loadingUserInfo],
  );

  const [getUserInfo, loadingUserInfo] = useSelector(selectNumOfDoneTodos);

  const isMobileDevice = useMemo(
    () => (width < responsiveConfig.mobileInnerWidth ? true : false),
    [width],
  );

  const tagOption = ({ key }) => {
    if (key === '2') {
      confirm(() => {
        localStorage.clear();
        history.push(`/login?rp=${+new Date()}`);
      }, '确定要退出登录吗?');
    }
  };

  const dropdown = () => (
    <Menu onClick={tagOption}>
      <Menu.Item key="1">
        <Link to="/userInfo">
          <UserOutlined />
          <span>个人信息</span>
        </Link>
      </Menu.Item>
      <Menu.Divider />
      <Menu.Item key="2">
        <LogoutOutlined />
        <span>退出登录</span>
      </Menu.Item>
    </Menu>
  );

  const more = () => (
    <Menu>
      {moreList.map((item, index) => (
        <Menu.Item key={index}>
          <a href={item.url} target="_blank">
            <span>{item.title}</span>
          </a>
        </Menu.Item>
      ))}
    </Menu>
  );

  const options = () => {
    setIsMobileDrawer(isMobileDevice);
    onToggle(!collapsed);
  };

  return (
    <div className={`${style.head} clearfix`}>
      <div className={`${style.headLeft} fl`}>
        <div className={`${style.menu}`} onClick={options}>
          {collapsed ? (
            <MenuUnfoldOutlined className={style.icon} />
          ) : (
            <MenuFoldOutlined className="icon" />
          )}
        </div>
      </div>
      <div className={`${style.menuList} fr`}>
        <a
          href="http://blog.lgf196.top/ant-simple-pro-document/"
          target="_blank"
        >
          <Tooltip title="文档">
            <QuestionCircleOutlined className={style.icon} />
          </Tooltip>
        </a>
        <News />
        <FullScreeOut className={style.icon} />
        <Dropdown overlay={dropdown} placement="bottomCenter">
          <div className={`${style.propsUser}`}>
            {loadingUserInfo ? (
              <>
                <HeadImage
                  url={
                    getUserInfo.iconUrl
                      ? getUserInfo.iconUrl
                      : 'https://antd-simple-pro.oss-cn-beijing.aliyuncs.com/image/1605845717285.png'
                  }
                />
                <span>
                  {getUserInfo.username ? getUserInfo.username : '珍珍'}
                </span>
              </>
            ) : (
              <Spin size="small" />
            )}
          </div>
        </Dropdown>
        <Dropdown overlay={more} placement="bottomRight">
          <Button
            size="small"
            style={{ marginLeft: '20px', color: 'rgba(105, 123, 140, 0.7)' }}
          >
            <span>更多</span>
            <DownOutlined />
          </Button>
        </Dropdown>
      </div>
    </div>
  );
})
Example #12
Source File: login.js    From ctf_platform with MIT License 4 votes vote down vote up
render() {

        return (

            <Layout style={{ maxWidth: "100vw", maxHeight: "100vh" }}>
                <Content style={{ display: "flex", alignItems: "center", justifyContent: "center", backgroundColor: "rgba(0, 0, 0, 0)", backgroundImage: "url(" + require("./../assets/mainBG.webp").default + ")" }}>
                    <div className="login-banner login-banner-responsive">
                        <div style={{ fontSize: "7ch", color: "#595959" }}>
                            <span style={{ fontWeight: "500", textShadow: '1px -1px 1px -1px #000000' }}>Sieberrsec Training Platform</span>
                        </div>
                        <div style={{ color: "#595959", fontSize: "5ch" }}>
                            <p style={{ textShadow: '1px 1px 1px 1px #000000' }}>The Wheel. Reinvented.™</p>
                        </div>
                    </div>


                    <div className="login-page login-page-responsive">
                        <div style={{ padding: "15px", marginBottom: "5vh" }}>
                            <img src={require("./../assets/sieberrsec_ctf.svg").default} style={{ width: "100%" }}></img>
                        </div>
                        {this.state.login && (
                            <div style={{ width: "98%" }}>
                                <h1 style={{ color: "white", fontSize: "3ch" }}>Sign In</h1>
                                <Form
                                    name="normal_login"
                                    className="login-form"
                                    initialValues={{ remember: true }}
                                    onFinish={this.handleLogin}
                                    style={{ width: "95%" }}
                                >
                                    <Form.Item
                                        name="username"
                                        rules={[{ required: true, message: 'Please enter your username/email' }]}
                                    >
                                        <Input allowClear prefix={<UserOutlined className="site-form-item-icon" />} placeholder="Username/Email" />
                                    </Form.Item>
                                    <Form.Item
                                        name="password"
                                        rules={[{ required: true, message: 'Please enter your password.' }]}
                                    >
                                        <Input
                                            prefix={<LockOutlined className="site-form-item-icon" />}
                                            type="password"
                                            placeholder="Password"
                                            allowClear
                                        />
                                    </Form.Item>
                                    <Form.Item >
                                        <div style={{ display: "flex", justifyContent: "space-between" }}>
                                            <Form.Item name="remember" valuePropName="checked" noStyle>
                                                <Checkbox>Remember me</Checkbox>
                                            </Form.Item>

                                            <a href="#" id="forgot-password" onClick={() => { this.setState({ login: false, forgotPass: true }) }}><b>I forgot my password <QuestionCircleOutlined /></b></a>
                                        </div>
                                    </Form.Item>

                                    <Form.Item>
                                        <div style={{ display: "flex", alignItems: "center" }}>
                                            <Button type="primary" htmlType="submit" className="login-form-button" style={{ marginRight: "2ch" }} loading={this.state.loading}>Log in</Button>
                                            <span>Or <a href="#" id="register-toggle" onClick={() => { this.setState({ login: false, register: true }) }} ><b>Register now <RightCircleOutlined /></b></a></span>
                                        </div>
                                    </Form.Item>
                                </Form>
                            </div>
                        )}
                        {this.state.register && (
                            <div style={{ width: "98%" }}>
                                <h1 style={{ color: "white", fontSize: "3ch" }}>Register an Account</h1>
                                <Form
                                    name="register_form"
                                    id="register-form"
                                    className="register-form"
                                    onFinish={this.handleRegister}
                                    style={{ width: "95%" }}
                                    requiredMark="optional"
                                >
                                    <Form.Item
                                        name="username"
                                        
                                        rules={[{ required: true, message: 'Please enter a username' }, { message: "Please enter an alphanumeric username (without spaces) <= 50 characters.", pattern: /^[a-zA-Z0-9_]{1,50}$/ }]}
                                    >
                                        <Input id="register-username" allowClear prefix={<UserOutlined className="site-form-item-icon" />} placeholder="Enter a new username" />
                                    </Form.Item>

                                    <Form.Item
                                        name="email"
                                        
                                        rules={[{ required: true, message: 'Please enter an email' },
                                        {
                                            type: 'email',
                                            message: "Please enter a valid email",
                                        }]}
                                    >
                                        <Input id="register-email" allowClear prefix={<MailOutlined />} placeholder="Enter a new email" />
                                    </Form.Item>

                                    <Form.Item
                                        name="password"
                                        rules={[
                                            {
                                                required: true,
                                                message: 'Please input your password!',
                                            },
                                            { message: "Please enter a password that is >= 1 character and <= 200 characters", pattern: /^.{1,200}$/ }
                                        ]}
                                        hasFeedback
                                    >
                                        <Input.Password allowClear prefix={<LockOutlined />} placeholder="Enter a new password" />
                                    </Form.Item>

                                    <Form.Item
                                        name="confirm"
                                        dependencies={['password']}
                                        hasFeedback
                                        rules={[
                                            {
                                                required: true,
                                                message: 'Please confirm your password!',
                                            },
                                            ({ getFieldValue }) => ({
                                                validator(rule, value) {
                                                    if (!value || getFieldValue('password') === value) {
                                                        return Promise.resolve();
                                                    }
                                                    return Promise.reject('Oops, the 2 passwords do not match');
                                                },
                                            }),
                                        ]}
                                    >
                                        <Input.Password allowClear prefix={<LockOutlined />} placeholder="Confirm new password" />
                                    </Form.Item>
                                    <Form.Item>
                                        <Button loading={this.state.loading} type="primary" htmlType="submit" className="login-form-button" style={{ marginBottom: "1.5vh" }}>Register</Button>

                                        <p>Already have an account? <a href="#" onClick={() => { this.setState({ login: true, register: false }) }}><b>Login Here <LeftCircleOutlined /></b></a></p>
                                    </Form.Item>
                                </Form>
                            </div>
                        )}
                        {this.state.forgotPass && (
                            <div style={{ width: "98%" }}>
                                <h1 style={{ color: "white", fontSize: "3ch" }}>Forgot Password</h1>
                                <Form
                                    onFinish={this.handleForgot}
                                    style={{ width: "95%" }}
                                >
                                    <Form.Item
                                        name="email"
                                        rules={[{ required: true, message: 'Please enter your email' }, { type: "email", message: "Please enter a valid email" }]}
                                    >
                                        <Input allowClear prefix={<MailOutlined />} placeholder="Email" />
                                    </Form.Item>
                                    <p>
                                        If an account associated with the email above exists, you will receive a password reset email in your inbox <br /><br />
                                        Please note that there is a limit on how often password reset emails can be requested per user. A new email will <b>not be sent if you have just requested for one</b>.

                                    </p>

                                    <Form.Item>
                                        <div style={{ display: "flex", alignItems: "center", marginTop: "4ch" }}>
                                            <Button type="primary" htmlType="submit" style={{ marginRight: "2ch" }} loading={this.state.loading}>Send Email</Button>
                                            <span>Or <a href="#" onClick={() => { this.setState({ login: true, forgotPass: false }) }} ><b>Remember your password? <LeftCircleOutlined /></b></a></span>
                                        </div>
                                    </Form.Item>
                                </Form>
                            </div>
                        )}
                        {this.state.forgotPassReset && (
                            <div style={{ width: "98%" }}>
                                {this.state.forgotPassResetLoading ? (
                                    <div style={{ display: "flex", alignItems: "center", justifyContent: "center", flexDirection: "column" }}>
                                        <h1>Loading Link Details</h1>
                                        <Ellipsis color="#177ddc" size={120} />
                                    </div>
                                ) : (
                                    <div>
                                        <h1 style={{ color: "white", fontSize: "3ch" }}>Reset Password</h1>
                                        <h4>Resetting password for <u>{this.state.forgotPassUsername}</u></h4>
                                        <Form
                                            onFinish={this.handleResetPasword}
                                            style={{ width: "95%" }}
                                        >

                                            <Form.Item
                                                name="password"
                                                rules={[
                                                    {
                                                        required: true,
                                                        message: 'Please input your password',
                                                    },
                                                ]}
                                                hasFeedback
                                            >
                                                <Input.Password allowClear prefix={<LockOutlined />} placeholder="Enter a new password" />
                                            </Form.Item>

                                            <Form.Item
                                                name="confirm"
                                                dependencies={['password']}
                                                hasFeedback
                                                rules={[
                                                    {
                                                        required: true,
                                                        message: 'Please confirm your password',
                                                    },
                                                    ({ getFieldValue }) => ({
                                                        validator(rule, value) {
                                                            if (!value || getFieldValue('password') === value) {
                                                                return Promise.resolve();
                                                            }
                                                            return Promise.reject('Oops, the 2 passwords do not match');
                                                        },
                                                    }),
                                                ]}
                                            >
                                                <Input.Password allowClear prefix={<LockOutlined />} placeholder="Confirm new password" />
                                            </Form.Item>

                                            <Form.Item>
                                                <div style={{ display: "flex", alignItems: "center", marginTop: "4ch" }}>
                                                    <Button type="primary" htmlType="submit" style={{ marginRight: "2ch" }} loading={this.state.loading}>Reset Password</Button>
                                                    <span>Or <a href="#" onClick={() => { this.setState({ login: true, forgotPass: false, forgotPassReset: false }) }} ><b>Remember your password? <LeftCircleOutlined /></b></a></span>
                                                </div>
                                            </Form.Item>
                                        </Form>
                                    </div>
                                )}
                            </div>
                        )}
                        {this.state.needVerify && (
                            <div style={{ width: "98%" }}>
                                {this.state.verifyEmailLoading ? (
                                    <div style={{ display: "flex", alignItems: "center", justifyContent: "center", flexDirection: "column" }}>
                                        <h1>Verifying Email</h1>
                                        <Ellipsis color="#177ddc" size={120} />
                                    </div>
                                ) : (
                                    <div >
                                        <h1 style={{ color: "white", fontSize: "3ch" }}>Email Verification Required</h1>
                                        <p>
                                            Hi, we require you to <b>verify your email (<code>{this.state.verifyEmail}</code>)</b> in order to login to the platform. Please check your inbox and click on the verification link sent to you.
                                            <br /><br />
                                            Did not receive an email? You can resend a verficiation email below!
                                            <br />

                                            Please note that there is a limit on how often verification emails can be sent per user.
                                        </p>
                                        <Button type="primary" icon={<MailOutlined />} loading={this.state.loading} onClick={() => { this.handleResendVerification(this.state.verifyEmail) }}>Resend Verification</Button>
                                    </div>
                                )}
                            </div>
                        )}
                    </div>
                </Content>
            </Layout>
        );
    }
Example #13
Source File: CalculationConfig.jsx    From ui with MIT License 4 votes vote down vote up
CalculationConfig = (props) => {
  const {
    onConfigChange, disabled, disableDataIntegration,
  } = props;
  const FILTER_UUID = 'dataIntegration';
  const dispatch = useDispatch();
  const { dataIntegration, dimensionalityReduction } = useSelector(
    (state) => state.experimentSettings.processing.dataIntegration,
  );
  const elbowPlotUuid = generateDataProcessingPlotUuid(null, FILTER_UUID, 1);
  const data = useSelector((state) => state.componentConfig[elbowPlotUuid]?.plotData);

  const methods = [
    {
      value: 'harmony',
      text: 'Harmony',
      disabled: false,
    },
    {
      value: 'seuratv4',
      text: 'Seurat v4',
      disabled: false,
    },
    {
      value: 'fastmnn',
      text: 'Fast MNN',
      disabled: false,
    },
    {
      value: 'unisample',
      text: 'No integration',
      disabled: false,
    },
    {
      value: 'seuratv3',
      text: 'Seurat v3',
      disabled: true,
    },
    {
      value: 'conos',
      text: 'Conos',
      disabled: true,
    },
    {
      value: 'liger',
      text: 'Liger',
      disabled: true,
    },
  ];

  const [numPCs, setNumPCs] = useState(dimensionalityReduction.numPCs);

  const updateSettings = (diff) => {
    onConfigChange();
    dispatch(updateFilterSettings(
      FILTER_UUID,
      diff,
    ));
  };

  const roundedVariationExplained = () => {
    const variationExplained = data?.length
      ? data.slice(0, dimensionalityReduction.numPCs).reduce(
        (acum, current) => acum + current.percentVariance, 0,
      ) : 0;
    const roundingPrecision = 2;

    return _.round(variationExplained * 100, roundingPrecision);
  };

  const renderDimReductionMethod = () => (
    <Form.Item label={(
      <span>
        Method&nbsp;
        <Tooltip overlay={(
          <span>
            To integrate data, dimensional reduction is performed to find so called "anchors".
            cross-dataset pairs of cells that are in a matched biological state (‘anchors’), are both to correct for technical
            differences between datasets
            (i.e. batch effect correction), and to perform comparative scRNA-seq analysis across experimental conditions.
            CCA is well-suited when cell types are conserved, but there are very substantial differences
            in gene expression across experiments.
            However, CCA-based integration may also lead to overcorrection, especially when a large proportion of cells are
            non-overlapping across datasets.

            RPCA-based integration runs significantly faster, and also represents a more conservative approach where
            cells in different biological states are less likely to ‘align’ after integration.
            More info
            <a
              href='https://satijalab.org/seurat/articles/integration_rpca.html'
              target='_blank'
              rel='noreferrer'
            >
              {' '}
              <code>here</code>
            </a>
          </span>
        )}
        >
          <QuestionCircleOutlined />
        </Tooltip>
      </span>
    )}
    >

      <Select
        value={dimensionalityReduction.method}
        onChange={(val) => updateSettings({ dimensionalityReduction: { method: val } })}
        disabled={disabled}
      >
        <Option key='rpca' value='rpca'>Reciprocal PCA (RPCA)</Option>
        <Option key='cca' value='cca'>Canonical Correlation Analysis (CCA)</Option>
      </Select>
    </Form.Item>
  );

  return (
    <Collapse defaultActiveKey='data-integration'>
      <Panel header='Data Integration' key='data-integration'>
        <Space direction='vertical' style={{ width: '100%' }} />
        <Form size='small'>
          <Form.Item>
            <Text>
              <strong style={{ marginRight: '0.5rem' }}>Data integration settings:</strong>
              <Tooltip title='Integration of multiple samples corrects for batch effect. These methods identify shared cell states that are present across different datasets, even if they were collected from different individuals, experimental conditions, technologies, or even species. The user selects the integration method and sets the controls, as appropriate. The latest Seurat method is selected as default.'>
                <QuestionCircleOutlined />
              </Tooltip>
            </Text>
          </Form.Item>
          <div style={{ paddingLeft: '1rem' }}>
            <Form.Item
              label='Method:'
            >
              <Select
                value={dataIntegration.method}
                onChange={(val) => updateSettings({ dataIntegration: { method: val } })}
                disabled={disableDataIntegration || disabled}
              >
                {
                  methods.map((el) => (
                    <Option key={el.text} value={el.value} disabled={el.disabled}>
                      {
                        el.disabled ? (
                          <Tooltip title='Will be supported in a later version' placement='left'>
                            {el.text}
                          </Tooltip>
                        ) : el.text
                      }

                    </Option>
                  ))
                }
              </Select>
            </Form.Item>

            <NormalisationOptions
              config={dataIntegration.methodSettings[dataIntegration.method]}
              onUpdate={updateSettings}
              methodId={dataIntegration.method}
              onChange={() => onConfigChange()}
              disabled={disableDataIntegration || disabled}
            />

          </div>
          <Form.Item>
            <Text>
              <strong style={{ marginRight: '0.5rem' }}>Dimensionality reduction settings:</strong>
              <Tooltip title='Dimensionality reduction is necessary to summarise and visualise single cell RNA-seq data. The most common method is Principal Component Analysis. The user sets the number of Principal Components (PCs). This is the number that explains the majority of the variation within the dataset (ideally >90%), and is typically set between 5 and 30.'>
                <QuestionCircleOutlined />
              </Tooltip>
            </Text>
          </Form.Item>
          <div style={{ paddingLeft: '1rem' }}>
            <Form.Item label='Number of Principal Components'>
              <InputNumber
                value={numPCs}
                max={data?.length || 100}
                min={0}
                onChange={(value) => {
                  onConfigChange();
                  setNumPCs(value);
                }}
                onPressEnter={(e) => e.preventDefault()}
                onStep={(value) => updateSettings({ dimensionalityReduction: { numPCs: value } })}
                onBlur={(e) => updateSettings(
                  { dimensionalityReduction: { numPCs: parseInt(e.target.value, 0) } },
                )}
                disabled={disabled}
              />
            </Form.Item>
            <Form.Item label='% variation explained'>
              <InputNumber
                value={roundedVariationExplained()}
                disabled={disabled}
                readOnly
              />
            </Form.Item>
            <Form.Item label='Exclude genes categories'>
              <Tooltip title='Normalization can be biased by certain gene categories such the ones listed here.
              Checking them will ignore those categories.
              For example, cell cycle genes should be removed if sampling timepoints occured throughout the day.
              Those genes can otherwise introduces within-cell-type heterogeneity that can obscure the differences
              in expression between cell types.
              This is not implemented yet'
              >
                <QuestionCircleOutlined />
              </Tooltip>
              <Checkbox.Group
                onChange={(val) => updateSettings(
                  { dimensionalityReduction: { excludeGeneCategories: val } },
                )}
                value={dimensionalityReduction.excludeGeneCategories}
                disabled
              >
                <Space direction='vertical'>
                  <Checkbox value='ribosomal'>ribosomal</Checkbox>
                  <Checkbox value='mitochondrial'>mitochondrial</Checkbox>
                  <Checkbox value='cellCycle'>cell cycle</Checkbox>
                </Space>
              </Checkbox.Group>
            </Form.Item>

            {dataIntegration.method === 'seuratv4' ? renderDimReductionMethod() : <></>}

          </div>
        </Form>
      </Panel>
    </Collapse>
  );
}
Example #14
Source File: CalculationConfig.jsx    From ui with MIT License 4 votes vote down vote up
CalculationConfig = (props) => {
  const { experimentId, onConfigChange } = props;
  const FILTER_UUID = 'configureEmbedding';
  const dispatch = useDispatch();

  const data = useSelector((state) => state.experimentSettings.processing[FILTER_UUID]);
  const changedQCFilters = useSelector(
    (state) => state.experimentSettings.processing.meta.changedQCFilters,
  );

  const { method: clusteringMethod } = data?.clusteringSettings || {};
  const { method: embeddingMethod } = data?.embeddingSettings || {};
  const { umap: umapSettings, tsne: tsneSettings } = data?.embeddingSettings.methodSettings || {};
  const { louvain: louvainSettings } = data?.clusteringSettings.methodSettings || {};

  const debouncedClustering = useCallback(
    _.debounce((resolution) => {
      dispatch(runCellSetsClustering(experimentId, resolution));
    }, 1500),
    [],
  );

  const [resolution, setResolution] = useState(null);
  const [minDistance, setMinDistance] = useState(null);

  useEffect(() => {
    if (!resolution && louvainSettings) {
      setResolution(louvainSettings.resolution);
    }
  }, [louvainSettings]);

  useEffect(() => {
    if (!minDistance && umapSettings) {
      setMinDistance(umapSettings.minimumDistance);
    }
  }, [umapSettings]);

  const dispatchDebounce = useCallback(_.debounce((f) => {
    dispatch(f);
  }, 1500), []);

  const updateSettings = (diff) => {
    if (diff.embeddingSettings) {
      // If this is an embedding change, indicate to user that their changes are not
      // applied until they hit Run.
      onConfigChange();
    } else {
      // If it's a clustering change, debounce the save process at 1.5s.
      dispatchDebounce(saveProcessingSettings(experimentId, FILTER_UUID));
    }

    dispatch(updateFilterSettings(
      FILTER_UUID,
      diff,
    ));
  };

  const setMinimumDistance = (value) => {
    updateSettings({
      embeddingSettings: {
        methodSettings: {
          umap: {
            minimumDistance: parseFloat(value),
          },
        },
      },
    });

    onConfigChange();
  };
  const setDistanceMetric = (value) => {
    updateSettings({
      embeddingSettings: {
        methodSettings: {
          umap: {
            distanceMetric: value,
          },
        },
      },
    });

    onConfigChange();
  };

  const setLearningRate = (value) => {
    updateSettings({
      embeddingSettings: {
        methodSettings: {
          tsne: {
            learningRate: parseFloat(value),
          },
        },
      },
    });

    onConfigChange();
  };
  const setPerplexity = (value) => {
    updateSettings({
      embeddingSettings: {
        methodSettings: {
          tsne: {
            perplexity: parseFloat(value),
          },
        },
      },
    });

    onConfigChange();
  };

  const renderUMAPSettings = () => (
    <>
      <Form.Item>
        <Text strong>Settings for UMAP:</Text>
      </Form.Item>
      <Form.Item label={(
        <span>
          Minimum distance&nbsp;
          <Tooltip title={MIN_DIST_TEXT}>
            <QuestionCircleOutlined />
          </Tooltip>
        </span>
      )}
      >
        <InputNumber
          value={umapSettings.minimumDistance}
          min={0}
          step={0.1}
          onChange={(value) => setMinimumDistance(value)}
          onStep={(value) => setMinimumDistance(value)}
          onPressEnter={(e) => e.preventDefault()}
          onBlur={(e) => setMinimumDistance(e.target.value)}
        />
      </Form.Item>
      <Form.Item label={(
        <span>
          Distance metric&nbsp;
          <Tooltip overlay={(
            <span>
              A metric determines how similarity between cells is measured.
              "Euclidean" is the standard for most normalized datasets.
              Cosine might be a good choice for unnormalized data.
              More information
              <a
                href='https://satijalab.org/seurat/reference/runumap'
                target='_blank'
                rel='noreferrer'
              >
                {' '}
                <code>here</code>
              </a>
            </span>
          )}
          >
            <QuestionCircleOutlined />
          </Tooltip>
        </span>
      )}
      >
        <Select
          value={umapSettings.distanceMetric}
          onChange={(value) => setDistanceMetric(value)}
        >
          <Option value='cosine'>Cosine</Option>
          <Option value='euclidean'>Euclidean</Option>
        </Select>
      </Form.Item>
    </>
  );

  const renderTSNESettings = () => (
    <>
      <Form.Item>
        <Text strong>Settings for t-SNE:</Text>
      </Form.Item>
      <Form.Item label={(
        <span>
          Perplexity &nbsp;
          <Tooltip title='Determines how to much emphasis should be on local or global aspects of your data.
          The parameter is, in a sense, a guess about the number of close neighbors each cell has.
          In most implementations, perplexity defaults to 30. This focuses the attention of t-SNE on preserving the
          distances to its 30 nearest neighbors and puts virtually no weight on preserving distances to the remaining points.
          The perplexity value has a complex effect on the resulting pictures.'
          >
            <QuestionCircleOutlined />
          </Tooltip>
        </span>
      )}
      >
        <InputNumber
          value={tsneSettings.perplexity}
          min={5}
          onChange={(value) => setPerplexity(value)}
          onStep={(value) => setPerplexity(value)}
          onPressEnter={(e) => e.preventDefault()}
          onBlur={(e) => setPerplexity(e.target.value)}
        />
      </Form.Item>
      <Form.Item
        label={(
          <span>
            Learning Rate &nbsp;
            <Tooltip title='If the learning rate is too high, the data may look like a "ball" with any point approximately equidistant from its nearest neighbours.
          If the learning rate is too low, most points may look compressed in a dense cloud with few outliers. usually in the range [10.0, 1000.0]'
            >
              <QuestionCircleOutlined />
            </Tooltip>
          </span>
        )}
      >
        <InputNumber
          value={tsneSettings.learningRate}
          min={10}
          max={1000}
          step={10}
          onChange={(value) => setLearningRate(value)}
          onStep={(value) => setLearningRate(value)}
          onPressEnter={(e) => e.preventDefault()}
          onBlur={(e) => setLearningRate(e.target.value)}
        />
      </Form.Item>
    </>
  );

  if (!data) {
    return <PreloadContent />;
  }

  return (
    <Collapse defaultActiveKey={['embedding-settings', 'clustering-settings']}>
      <Panel header='Embedding settings' key='embedding-settings'>
        <Form size='small'>
          {Boolean(changedQCFilters.size) && (
            <Form.Item>
              <Alert message='Your changes are not yet applied. To update the plots, click Run.' type='warning' showIcon />
            </Form.Item>
          )}

          <Form.Item label={(
            <span>
              Method&nbsp;
              <Tooltip overlay={(
                <span>
                  {EMBEDD_METHOD_TEXT}
                  More info for
                  <a
                    href='https://satijalab.org/seurat/reference/runumap'
                    target='_blank'
                    rel='noreferrer'
                  >
                    {' '}
                    <code>UMAP</code>
                    {' '}
                  </a>
                  or
                  <a
                    href='https://satijalab.org/seurat/reference/runtsne'
                    target='_blank'
                    rel='noreferrer'
                  >
                    {' '}
                    <code>t-SNE</code>
                  </a>
                </span>
              )}
              >
                <QuestionCircleOutlined />
              </Tooltip>
            </span>
          )}
          >
            <Select
              value={embeddingMethod}
              onChange={(value) => {
                updateSettings({
                  embeddingSettings: {
                    method: value,
                  },
                });
              }}
            >
              <Option value='umap'>UMAP</Option>
              <Option value='tsne'>t-SNE</Option>
            </Select>

          </Form.Item>
          {embeddingMethod === 'umap' && renderUMAPSettings()}
          {embeddingMethod === 'tsne' && renderTSNESettings()}
        </Form>
      </Panel>
      <Panel header='Clustering settings' key='clustering-settings'>
        <Form size='small'>
          <Form.Item label={(
            <span>
              Clustering method&nbsp;
              <Tooltip overlay={(
                <span>
                  Louvain and Leiden are graph-based clustering methods which are the most popular
                  clustering algorithm in scRNA-seq data analysis since they have been reported to have outperformed other
                  clustering methods in many situations.
                  They are also more efficient than other cluster methods which is crucial large scRNA-seq datasets.
                  <a
                    href='https://en.wikipedia.org/wiki/Louvain_method'
                    target='_blank'
                    rel='noreferrer'
                  >
                    {' '}
                    <code>here</code>
                  </a>
                </span>
              )}
              >
                <QuestionCircleOutlined />
              </Tooltip>
            </span>
          )}
          >
            <Select
              value={clusteringMethod}
              onChange={(value) => updateSettings(
                { clusteringSettings: { method: value } },
              )}
            >
              <Option value='louvain'>Louvain</Option>
              <Option value='leiden' disabled>
                <Tooltip title='Leiden metric is going to be supported on a future version of the platform.'>
                  Leiden
                </Tooltip>
              </Option>
              <Option value='slm' disabled>
                <Tooltip title='SLM metric is going to be supported on a future version of the platform.'>
                  SLM
                </Tooltip>
              </Option>
            </Select>
          </Form.Item>
          <Form.Item label={(
            <span>
              Resolution&nbsp;
              <Tooltip overlay={(
                <span>
                  Resolution is a parameter for the Louvain community detection algorithm that alters the number of the recovered clusters. Smaller resolution recovers fewer clusters while larger resolution recovers more clusters. The default is 0.8.
                </span>
              )}
              >
                <QuestionCircleOutlined />
              </Tooltip>
            </span>
          )}
          >
            <SliderWithInput
              min={0}
              max={2}
              step={0.1}
              value={resolution}
              onUpdate={(value) => {
                if (value === resolution) { return; }

                setResolution(value);
                updateSettings({
                  clusteringSettings: {
                    methodSettings: {
                      louvain: { resolution: value },
                    },
                  },
                });

                debouncedClustering(value);
              }}
            />
          </Form.Item>
        </Form>
      </Panel>
    </Collapse>
  );
}
Example #15
Source File: index.jsx    From mixbox with GNU General Public License v3.0 4 votes vote down vote up
render() {
        let {
            // 自定义属性
            type = 'input',
            labelWidth,
            showLabel,
            width, // 整体宽度,默认 100%
            labelTip,
            tip,
            decorator,
            style,
            elementStyle,
            layout,
            forwardedRef,
            noSpace,
            trim,
            // 校验相关
            maxLength,
            minLength,

            // Form.Item属性
            colon,
            dependencies,
            extra,
            getValueFromEvent,
            hasFeedback,
            help,
            htmlFor,
            noStyle,
            label,
            labelAlign,
            labelCol,
            name,
            normalize,
            required,
            rules,
            shouldUpdate,
            trigger,
            validateFirst,
            validateStatus,
            validateTrigger,
            valuePropName,
            wrapperCol,

            children,

            // 其他的会直接作为Form 表单元素属性
            ...others
        } = this.props;


        if (type === 'switch' || type === 'checkbox') {
            valuePropName = 'checked';
        }

        if (type === 'transfer') {
            valuePropName = 'targetKeys';
        }

        let labelWithoutWidth = true;
        if (!labelCol && labelWidth !== undefined) {
            labelCol = {flex: `0 0 ${labelWidth}px`};
            labelWithoutWidth = false;
        }

        if (type === 'select' && ('showSearch' in others) && !('optionFilterProp' in others)) {
            others.optionFilterProp = 'children';
        }

        // 处理整体样式
        const wrapperStyle = {};
        if (width !== void 0) {
            wrapperStyle.width = width;
            wrapperStyle.flexBasis = width;
            wrapperStyle.flexGrow = 0;
            wrapperStyle.flexShrink = 0;
        } else {
            wrapperStyle.flex = 1;
        }

        // 处理元素样式
        let eleStyle = {width: '100%'};
        eleStyle = {...eleStyle, ...elementStyle};

        // 处理placeholder
        if (!('placeholder' in others)) {
            if (isInputLikeElement(type)) {
                others.placeholder = `请输入${label}`;
            } else if (type === 'date-range') {
                others.placeholder = ['开始日期', '结束日期'];
            } else {
                others.placeholder = `请选择${label}`;
            }
        }

        if (!('allowClear' in others) && isInputLikeElement(type)) {
            others.allowClear = true;
        }

        rules = this.getRules(rules, isInputLikeElement(type) ? `请输入${label}` : `请选择${label}`);

        if (rules.find(item => ('required' in item) && item.required)) {
            required = true;
        }

        let formLabel = label;
        if (labelTip) {
            formLabel = (
                <span>
                    <Tooltip
                        placement="bottom"
                        title={labelTip}
                    >
                        <QuestionCircleOutlined style={{marginRight: '4px'}}/>
                    </Tooltip>
                    {label}
                </span>
            );
        }

        const getValueFromEventNoSpace = noSpace ? (e) => {
            if (isInputLikeElement(type)) {
                let value = (!e || !e.target) ? e : e.target.value;

                if (value && typeof value === 'string') return value.replace(/\s/g, '');

                return value;
            } else {
                return getValueFromEvent(e);
            }
        } : getValueFromEvent;

        const elementProps = {
            ...others, ref: forwardedRef, style: eleStyle,
        };

        if (layout) {
            formLabel = formLabel || '';
            colon = false;
        } else {
            if (children && !shouldUpdate) {
                children = children ? React.cloneElement(children, elementProps) : null;
            } else {
                children = getElement({type, ...elementProps});
            }
        }

        // 不处理不显示红色星号
        if ((!formLabel && required) || !showLabel) formLabel = ' ';

        return (
            <div
                style={{display: type === 'hidden' ? 'none' : 'flex', ...wrapperStyle, ...style}}
                className="form-element-flex-root"
                ref={node => this.container = node}
            >
                <FormItem
                    colon={colon}
                    dependencies={dependencies}
                    extra={extra}
                    getValueFromEvent={getValueFromEventNoSpace}
                    hasFeedback={hasFeedback}
                    help={help}
                    htmlFor={htmlFor}
                    noStyle={noStyle}
                    label={formLabel}
                    labelAlign={labelAlign}
                    labelCol={labelCol}
                    name={name}
                    normalize={normalize}
                    required={required}
                    rules={rules}
                    shouldUpdate={shouldUpdate}
                    trigger={trigger}
                    validateFirst={validateFirst}
                    validateStatus={validateStatus}
                    validateTrigger={validateTrigger}
                    valuePropName={valuePropName}
                    wrapperCol={wrapperCol}
                    className={labelWithoutWidth ? 'frame-label-without-width' : ''}
                >
                    {children}
                </FormItem>
                {tip ? <div className="font-element-tip">{tip}</div> : null}
            </div>
        );
    }
Example #16
Source File: confgo.jsx    From juno with Apache License 2.0 4 votes vote down vote up
render() {
    const that = this;
    const {
      appId = 0,
      app = {},
      apps = [],
      configList = [],
      configText,
      commonText,
      appConfigList = [],
      configChangeList = [],
      statusList = [],
      configHistoryList = [],
      resourceData = {},
      appInfo: { aid, appName },
      msg,
      idcList,
      file_path = '',
      zoneCode,
    } = this.props;
    console.log('render -> configText', configText);

    const { users = [] } = app;
    const appInfo = appConfigList[0] || {};
    const {
      caid,
      file_name,
      format,
      env,
      filterKey,
      selectItemID,
      selectKey,
      selectValue,
      selectComment,
      selectIsResource,
      selectResourceID,
      selectIsPublic,
      fileDelModalVisible: showFileManage,
      fileDelConfirmLoading,
      result_list = [],
    } = this.state;
    const changeNum = configList.filter((v) => v.status * 1 !== 1).length;

    const leftCardStyle = {
      borderRadius: '4px',
      marginTop: '4px',
      marginLeft: '4px',
    };
    const statusMap = (t, status) => {
      const map = {
        1: <span></span>,
        2: <span>{getOpSapn('new')}</span>,
        3: <span>{getOpSapn('update')}</span>,
        4: <span>{getOpSapn('del')}</span>,
      };
      return map[status];
    };

    const changListCols = [
      {
        key: 'key',
        dataIndex: 'key',
        title: 'Block',
        width: 120,
        render(t, r) {
          return <span style={{ wordBreak: 'break-word' }}>{t}</span>;
        },
      },
      {
        key: 'op_type',
        dataIndex: 'op_type',
        title: '操作',
        width: 80,
        render(t) {
          const opMap = {
            1: getOpSapn('new', '新增'),
            2: getOpSapn('update', '更新'),
            3: getOpSapn('del', '删除'),
          };
          return <span>{opMap[t]}</span>;
        },
      },
      {
        key: 'old_value',
        dataIndex: 'old_value',
        title: '旧值',
        render(t) {
          let tmp = t;
          if (t.length > 200) {
            tmp = tmp.substring(0, 200) + '...';
          }
          return <span style={{ wordBreak: 'break-word' }}>{tmp}</span>;
        },
      },
      {
        key: 'new_value',
        dataIndex: 'new_value',
        title: '新值',
        render(t) {
          let tmp = t;
          if (t.length > 200) {
            tmp = tmp.substring(0, 200) + '...';
          }
          return <span style={{ wordBreak: 'break-word' }}>{tmp}</span>;
        },
      },
      {
        key: 'update_time',
        dataIndex: 'update_time',
        title: '时间',
        width: 180,
        render(t) {
          return moment(t * 1000).format('YYYY-MM-DD HH:mm:ss');
        },
      },
      {
        key: 'op_name',
        dataIndex: 'op_name',
        width: 180,
        title: '操作人',
      },
    ];

    const statusCol = [
      {
        key: 'is_use',
        dataIndex: 'is_use',
        title: (
          <span>
            配置状态
            <Tooltip
              title={`当前实例上的systemd配置文件项是否接入配置中心\n。若显示未接入,则需要修改systemd下发配置,路径改为配置中心提供的路径\n。若已经修改下发过,点击【同步实例状态】刷新。`}
            >
              <QuestionCircleOutlined style={{ marginLeft: '6px' }} />
            </Tooltip>
          </span>
        ),
        render(t) {
          return t ? getOpSapn('new', '已接入') : <div>{getOpSapn('del', '未接入')}</div>;
        },
      },
      {
        key: 'is_latest',
        dataIndex: 'is_latest',
        title: (
          <span>
            文件状态
            <Tooltip
              title={`当前实例上的配置文件是否为最新发布\n。若显示未同步,点击【刷新文件状态】。若刷新无效则需要【重新发布】一次。`}
            >
              <QuestionCircleOutlined style={{ marginLeft: '6px' }} />
            </Tooltip>
          </span>
        ),
        render(t) {
          return t ? getOpSapn('new', '已同步') : getOpSapn('del', '未同步');
        },
      },
      {
        key: 'is_effect',
        dataIndex: 'is_effect',
        title: (
          <span>
            配置状态
            <Tooltip title={`重启之后应用配置是否生效`}>
              <QuestionCircleOutlined style={{ marginLeft: '6px' }} />
            </Tooltip>
          </span>
        ),
        render(t) {
          return t ? getOpSapn('new', '已生效') : <div>{getOpSapn('del', '未生效')}</div>;
        },
      },
      {
        key: 'hostname',
        dataIndex: 'hostname',
        title: '实例名称',
      },
      {
        key: 'message',
        dataIndex: 'message',
        title: '提交日志',
      },
      {
        key: 'timestamp',
        dataIndex: 'timestamp',
        title: '文件同步时间/进程启动时间',
        render(t, r) {
          const { process_start_time = 0, is_latest, is_use } = r;
          if (process_start_time !== 0) {
            const syncTime = t * 1000;
            const startTime = process_start_time * 1000;
            //进程生效状态
            let process_start_status = null;
            if (syncTime > startTime) {
              //配置未完全生效
              process_start_status = (
                <Tooltip title={'配置文件已经同步完成,进程尚未重启生效'}>
                  <Icon type="clock-circle" style={{ color: 'orange' }} />
                </Tooltip>
              );
            } else if (is_latest && is_use) {
              // 配置文件已同步,进程已重启,生效
              process_start_status = (
                <Tooltip title={'最新配置已经生效'}>
                  <Icon type="check-circle" style={{ color: 'green' }} />
                </Tooltip>
              );
            }
            return (
              <div>
                <p>{moment(syncTime).format('YYYY-MM-DD HH:mm:ss')}</p>
                <p>
                  {moment(startTime).format('YYYY-MM-DD HH:mm:ss')} {process_start_status}
                </p>
              </div>
            );
          }
          return (
            <div>
              <p>{moment(t * 1000).format('YYYY-MM-DD HH:mm:ss')}</p>
            </div>
          );
        },
      },
      {
        key: 'params',
        dataIndex: 'params',
        title: (
          <span>
            启动参数
            <Tooltip
              title={
                '当前实例上的systemd配置中的启动参数, ${ConfigDir}变量为配置中心默认下发路径。启动时间为进程启动时间。'
              }
            >
              <Icon style={{ marginLeft: '6px' }} type="question-circle" />
            </Tooltip>
          </span>
        ),
        render(t, r) {
          const paramsArr = t.split('/bin/%(program_name)s');
          if (paramsArr.length !== 2) {
            return t;
          }
          const params = paramsArr[1];
          return (
            <div>
              <p style={{ margin: 0 }}>{params}</p>
            </div>
          );
        },
      },
      {
        key: 'op',
        dataIndex: 'op',
        title: '操作',
        render(t, r) {
          const { pub_id, is_latest } = r;
          if (is_latest) {
            return (
              <div>
                <Button
                  style={{ color: 'black' }}
                  onClick={(e) => {
                    that.showConfirm('restart', this.state.zone_code, r.hostname);
                  }}
                >
                  重启
                </Button>
              </div>
            );
          }
        },
      },
    ];

    const customPanelStyle = {
      background: '#f7f7f7',
      borderRadius: 4,
      marginBottom: 8,
      border: 0,
      overflow: 'hidden',
    };

    //文本编辑器options
    const options = {
      lineNumbers: true, //显示行号
      mode: { name: 'text/html' }, //定义mode
      theme: 'ambiance', //选中的theme
      lineWrapping: true,
    };

    if (msg === '权限错误') {
      return (
        <div style={{ marginTop: 10 }}>
          <Alert
            message="权限不足"
            description="对线上配置操作需要管理员权限"
            type="error"
            showIcon
          />
        </div>
      );
    }
    let idcArr = [];
    let zone_codeMap = [];

    idcList.forEach((element) => {
      idcArr.push(element.zone_code);
      zone_codeMap[element.zone_code] = element.zone_name;
    });

    const genHeader = (record) => (
      <div>
        <div className={'cube'}>
          {record.is_public == 0 && <Tag color="#2db7f5">私有</Tag>}
          {record.is_public == 1 && <Tag color="#f50">公有</Tag>}
          {record.is_public == 2 && <Tag color="#87d068">关联</Tag>}
        </div>
        <div className={'cube-title'}>
          <h3>{record.key}</h3>
        </div>
      </div>
    );

    const genExtra = (record) => (
      <div>
        {statusMap(record.key, record.status)}
        <Divider type="vertical" />
        {record.status != 4 && (
          <Tag
            color={'blue'}
            onClick={(event) => {
              event.stopPropagation();
              that.setState({
                selectItemID: record.id,
                selectKey: record.key,
                selectValue: record.value,
                selectComment: record.comment,
                selectIsResource: record.is_resource,
                selectResourceID: record.resource_id,
                selectIsPublic: record.is_public,
                showUpdateItem: true,
              });
              that.getEnvResource();
            }}
          >
            编辑
          </Tag>
        )}
        {record.status != 4 && (
          <Popconfirm
            title="确定删除吗?"
            onConfirm={() => {
              that.delItem({ id: record.id });
            }}
          >
            <Tag color={'red'}>删除</Tag>
          </Popconfirm>
        )}
      </div>
    );

    let configItemList = [];
    configList.forEach((element) => {
      configItemList.push(
        <Panel
          header={genHeader(element)}
          key={element.key}
          className="site-collapse-custom-panel"
          extra={genExtra(element)}
        >
          <ReactCodeMirror
            ref="editor"
            value={element.value}
            options={{
              mode: 'text/x-toml',
              lineNumbers: true,
              autoMatchParens: true,
              lineWrapping: false,
              readOnly: this.state.readOnly,
              scrollbarStyle: null,
            }}
          />
        </Panel>,
      );
    });

    return (
      <Layout>
        <Sider width={250} style={{ backgroundColor: 'transparent' }}>
          <Card style={leftCardStyle}>
            <p style={{ textAlign: 'left' }}>
              配置文件列表
              <Button
                style={{ marginLeft: '8px' }}
                size={'small'}
                type={'primary'}
                icon={<PlusCircleOutlined />}
                onClick={() => {
                  this.setState({ showConfigFile: true });
                }}
              >
                添加配置
              </Button>
            </p>
            {appInfo && appInfo.configs ? (
              <Menu
                selectedKeys={[caid + '_' + env + '_' + format]}
                mode="inline"
                style={{ height: '50%', borderRight: 0 }}
                defaultOpenKeys={idcArr}
                onClick={this.changeAppConfig}
              >
                {Object.keys(this.sortObj(appInfo.files, idcArr)).map((zone_code) => {
                  if (zoneCode == 'all' || zoneCode == zone_code) {
                    return (
                      <Menu.SubMenu key={zone_code} title={<h4>{`${zone_codeMap[zone_code]}`}</h4>}>
                        {appInfo.files[zone_code].map((v) => {
                          console.log('this.state.zone_code', this.state.zone_code);
                          return (
                            <Menu.Item
                              style={{ paddingLeft: '20px' }}
                              key={v.id + '_' + v.env + '_' + v.format}
                            >
                              {v.file_name}
                            </Menu.Item>
                          );
                        })}
                      </Menu.SubMenu>
                    );
                  }
                })}
              </Menu>
            ) : (
              <div style={{ textAlign: 'left' }}>
                <Button type={'primary'} onClick={() => this.setState({ showConfigFile: true })}>
                  添加配置文件
                </Button>
              </div>
            )}
          </Card>
          <Card style={leftCardStyle}>
            <p style={{ textAlign: 'left' }}>文件管理</p>
            <Button type="primary" onClick={this.handleFileManage} style={{ marginLeft: '4px' }}>
              文件管理
            </Button>
            <Button type="primary" onClick={this.handleFileDiff} style={{ marginLeft: '4px' }}>
              文件对比
            </Button>
          </Card>
        </Sider>
        <Content>
          <div>
            {caid !== 0 && (
              <Row style={{ marginTop: '4px', marginLeft: '4px', marginRight: '4px' }}>
                <Col span={4} style={{ textAlign: 'left' }}>
                  <Button
                    style={{ float: 'left', marginRight: '6px' }}
                    onClick={(e) => {
                      //加载节点数据
                      this.getAppList().then((_) => {
                        //获取配置列表
                        this.autoChangeConfig(); //自动选择第一个配置文件
                        message.success('数据已更新');
                      });
                    }}
                  >
                    <Icon type="sync" />
                    刷新数据
                  </Button>
                  <Tooltip
                    title={`当前页面为静态页面,修改配置前需要刷新获取最新配置数据,以免覆盖其他人的配置数据`}
                  >
                    <QuestionCircleOutlined />
                  </Tooltip>
                </Col>
                <Col span={20} style={{ textAlign: 'right' }}>
                  <Button.Group>
                    <Button
                      type={'primary'}
                      onClick={() => {
                        that.setState({ showPublish: true });
                      }}
                    >
                      发布配置
                    </Button>
                    <Button
                      type={'danger'}
                      onClick={(e) => {
                        that.changeTab('status');
                      }}
                    >
                      重启列表
                    </Button>
                    <Button
                      type={'primary'}
                      onClick={(e) => {
                        that.setState({ showRollback: true });
                      }}
                    >
                      配置回滚
                    </Button>
                    <Button
                      onClick={() => {
                        that.getHistoryList();
                        that.setState({ showHistory: true });
                      }}
                    >
                      发布历史
                    </Button>
                  </Button.Group>
                </Col>
              </Row>
            )}
            {caid !== 0 && (
              <Tabs
                style={{
                  backgroundColor: '#fff',
                  marginTop: '5px',
                  marginLeft: '5px',
                  marginRight: '5px',
                }}
                activeKey={this.state.tab}
                onChange={this.changeTab}
              >
                <TabPane
                  tab={
                    <span>
                      <div style={{ marginLeft: 10 }}>
                        <TableOutlined />
                        配置编辑
                      </div>
                    </span>
                  }
                  key="table"
                >
                  <Row>
                    <Col style={{ marginTop: '-5px' }}>
                      <Button.Group>
                        <Button
                          style={{ marginLeft: '10px' }}
                          type="primary"
                          onClick={() => {
                            that.setState({ showAddItem: true });
                            that.getEnvResource();
                          }}
                        >
                          添加 Block
                        </Button>
                      </Button.Group>
                    </Col>
                  </Row>
                  <Row gutter={24}>
                    <Col span={24} style={{ marginTop: '10px' }}>
                      <Collapse
                        bordered={false}
                        defaultActiveKey={['application']}
                        expandIcon={({ isActive }) => (
                          <CaretRightOutlined rotate={isActive ? 90 : 0} />
                        )}
                        className="site-collapse-custom-collapse"
                        expandIconPosition="right"
                      >
                        {configItemList}
                      </Collapse>
                    </Col>
                  </Row>
                </TabPane>
                <TabPane
                  tab={
                    <span>
                      <FileOutlined />
                      发布预览
                    </span>
                  }
                  key="text"
                >
                  <Spin spinning={this.state.loading} />
                  <Row>
                    <Col
                      style={{
                        textAlign: 'left',
                        marginLeft: '8px',
                        marginBottom: '8px',
                        fontSize: '18px',
                      }}
                      span={12}
                    >
                      {file_name}
                    </Col>
                    <Col
                      style={{
                        textAlign: 'right',
                        marginRight: '8px',
                        marginBottom: '8px',
                      }}
                      span={11}
                    >
                      <Button.Group>
                        <span>
                          <Button
                            onClick={(e) => {
                              copy(configText);
                              message.success('已复制到剪切板');
                            }}
                          >
                            复制
                          </Button>
                        </span>
                      </Button.Group>
                    </Col>
                  </Row>
                  <div className={'configEditor'}>
                    <ReactCodeMirror
                      ref="editor"
                      value={configText}
                      options={{
                        mode: 'text/x-toml',
                        lineNumbers: true,
                        autoMatchParens: true,
                        lineWrapping: true,
                        readOnly: this.state.readOnly,
                      }}
                      onChange={(editor, data, value) => {
                        this.configInputText = editor.getValue();
                      }}
                    />
                  </div>
                </TabPane>
                <TabPane
                  tab={
                    <span>
                      <FileDoneOutlined />
                      <Badge count={changeNum} overflowCount={9999} offset={[0, 18]}>
                        变更历史
                      </Badge>
                    </span>
                  }
                  key="history"
                >
                  <Table
                    columns={changListCols}
                    dataSource={configChangeList}
                    size={'small'}
                    pagination={false}
                    rowKey={'id'}
                  />
                </TabPane>
                <TabPane
                  tab={
                    <span>
                      <HddOutlined />
                      实例列表
                    </span>
                  }
                  key="status"
                >
                  <Spin spinning={this.state.showStatusSync} />
                  <div style={{ marginLeft: '10px' }}>
                    配置文件路径:
                    <span
                      style={{
                        marginLeft: '8px',
                        marginRight: '8px',
                        fontSize: '16px',
                      }}
                    >{`${file_path}`}</span>
                    <a
                      onClick={(e) => {
                        copy(`${file_path}`);
                        message.success('已复制,请重新下发配置文件生效');
                      }}
                    >
                      点击复制
                    </a>
                    <Tooltip
                      title={`修改systemd下发的配置文件路径,由原来的项目相对路径改为配置中心的路径`}
                    >
                      <Icon style={{ marginLeft: '6px' }} type="question-circle" />
                    </Tooltip>
                    <span
                      style={{
                        float: 'right',
                        marginRight: '8px',
                        marginBottom: '8px',
                      }}
                    >
                      <Button
                        type={'primary'}
                        onClick={(e) => {
                          that.setState({
                            showStatusSync: true,
                          });
                          SyncConfigNodes({ caid: caid })
                            .then((rs) => {
                              that.getConfigStatusList();
                              message.success('同步成功');
                              that.setState({
                                showStatusSync: false,
                              });
                            })
                            .catch((err) => {
                              that.setState({
                                showStatusSync: false,
                              });
                            });
                        }}
                      >
                        刷新实例状态
                      </Button>
                    </span>
                    <Table
                      size="small"
                      columns={statusCol}
                      dataSource={statusList}
                      pagination={false}
                    />
                  </div>
                </TabPane>
              </Tabs>
            )}

            <NewItemForm
              show={this.state.showAddItem}
              cancel={() => {
                this.setState({ showAddItem: false });
              }}
              item={{
                resourceData: resourceData,
              }}
              env={this.state.env}
              zone_code={this.state.zone_code}
              submit={this.addItem}
              caid={this.state.caid}
              zone_codeMap={zone_codeMap}
            />

            <UpdateItemForm
              show={this.state.showUpdateItem}
              env={this.state.env}
              zone_code={this.state.zone_code}
              cancel={() => {
                this.setState({ showUpdateItem: false });
              }}
              changeResource={(e) => {
                that.setState({
                  selectIsResource: e,
                });
              }}
              changeResourceID={(e) => {
                that.setState({
                  selectResourceID: e * 1,
                });
              }}
              caid={this.state.caid}
              submit={this.updateItem}
              item={{
                id: selectItemID,
                key: selectKey,
                value: selectValue,
                comment: selectComment,
                is_resource: selectIsResource,
                resource_id: selectResourceID,
                resourceData: resourceData,
                is_public: selectIsPublic,
              }}
              zone_codeMap={zone_codeMap}
            />

            <PublishForm
              show={this.state.showPublish}
              publish_loading={this.state.publish_loading}
              file_name={file_name}
              item={{ caid }}
              cancel={() => {
                this.setState({ showPublish: false });
              }}
              submit={this.publishItem}
            />

            <NewConfigFile
              show={this.state.showConfigFile}
              cancel={() => {
                this.setState({ showConfigFile: false });
              }}
              submit={this.AddConfigFile}
              zoneList={this.props.zoneList}
            />

            <HistoryList
              show={this.state.showHistory}
              cancel={() => {
                this.setState({ showHistory: false });
                this.props.dispatch({
                  type: 'confuNew/setPublishChangeData',
                  payload: {},
                });
              }}
              list={configHistoryList}
            />

            <Preview
              oldCode={configText}
              newCode={this.configInputText}
              show={this.state.showPreview}
              cancel={() => {
                this.setState({ showPreview: false });
              }}
            />

            {this.state.showRollback && (
              <RollbackView
                caid={caid}
                show={this.state.showRollback}
                rollback={() => {
                  that.getConfigList();
                }}
                cancel={() => {
                  this.setState({ showRollback: false });
                }}
              />
            )}
            <FileManageView
              show={this.state.showFileManage}
              app_name={appName}
              app_id={aid}
              env={env}
              zone_code={this.state.zone_code}
              cancel={() => {
                this.setState({ showFileManage: false }, () => {
                  this.autoChangeConfig;
                });
              }}
            />
            <FileDiffView
              show={this.state.showFileDiff}
              originCid={this.state.caid}
              rafeCid={0}
              appConfigList={this.props.appConfigList}
              cancel={() => {
                this.setState({ showFileDiff: false });
              }}
            />
          </div>
        </Content>
        <Modal
          title="操作面板"
          visible={this.state.visible}
          onOk={(e) => {
            this.refreshState();
            this.setState({ visible: false, result_list: [] });
          }}
          okText={'确定'}
          onCancel={(e) => {
            this.refreshState();
            this.setState({ visible: false, result_list: [] });
          }}
          cancelText={'关闭'}
        >
          <div>
            <Spin spinning={this.state.loading} />
          </div>
          <div style={{ backgroundColor: 'black', borderRadius: '5px' }}>
            {result_list.map((v, i) => {
              const { name, content } = v;
              return (
                <p key={i} style={{ color: 'green' }}>
                  {content}
                </p>
              );
            })}
          </div>
        </Modal>
      </Layout>
    );
  }
Example #17
Source File: DashboardSidebar.js    From codeclannigeria-frontend with MIT License 4 votes vote down vote up
function DashboardSidebar({ showSidebar, tabs, path, authLogoutApi }) {
  const history = useHistory();

  const logoutUser = () => {
    authLogoutApi();
    history.push('/login/');
  };
  return (
    <MentorDashboardSidebarStyled showSidebar={showSidebar}>
      {/* <nav className="col-2 sidebar">
        <ul className="nav flex-column">
          <li className="nav-item mb-5 mt-3">
            <Link className="active" to="/dashboard">
              <img className="img-fluid" src={codeClanLogo} alt="code clan" />
            </Link>
          </li>
          {tabs.map(tab => (
            <li
              key={tab.id}
              className={` nav-item mb-5 ${
                path === tab.link ? 'active-icon ' : ''
              } `}
            >
              <Link className="nav-link text-white" to={`${tab.link}`}>
                {tab.icon}
              </Link>
            </li>
          ))}
          <Popconfirm
            title="Are sure you want to log out?"
            okText="Yes"
            cancelText="Oppss"
            onConfirm={() => logoutUser()}
            icon={<QuestionCircleOutlined style={{ color: 'red' }} />}
          >
            <LogoutOutlined style={{ fontSize: '2rem', color: '#fff' }} />
          </Popconfirm>
          ,
        </ul>
      </nav> */}
      <Link to="/">
        <img src={codeClanLogo} alt="code clan" className="img-fluid" />
      </Link>
      <ul>
        <li className="main-menu-link">
          <DashboardBulletLogo /> <Link to="/dashboard/"> Dashboard</Link>
        </li>

        {tabs.map(tab => (
          <li
            key={tab.id}
            className={` sub-menu ${path === tab.link ? 'active-icon ' : ''} `}
          >
            {/* <DashboardStackLogo /> */}
            {tab.icon}

            <Link to={`${tab.link}`}> {tab.name}</Link>
          </li>
        ))}

        {/* <li className="sub-menu">
          <DashboardStackLogo />
          <Link to="/dashboard/mentor/mentees/"> Mentees</Link>
        </li>
        <li className="sub-menu">
          <DashboardStackLogo /> Courses
        </li>
        <li className="sub-menu">
          <DashboardStackLogo /> Tasks
        </li>

         */}
        <li className="logout__link">
          <Popconfirm
            title="Are sure you want to log out?"
            okText="Yes"
            placement="topLeft"
            cancelText="Oppss"
            onConfirm={() => logoutUser()}
            icon={<QuestionCircleOutlined style={{ color: 'red' }} />}
          >
            <button className="btn btn-lg btn-primary">
              <i className="fas fa-power-off"></i> Logout
            </button>
          </Popconfirm>
        </li>
      </ul>
    </MentorDashboardSidebarStyled>
  );
}
Example #18
Source File: MentorDashboardSidebar.js    From codeclannigeria-frontend with MIT License 4 votes vote down vote up
function MentorDashboardSidebar({ showSidebar, authLogoutApi, path }) {
  const history = useHistory();

  const logoutUser = () => {
    authLogoutApi();
    history.push('/login/');
  };
  const tabs = [
    {
      id: 1,
      icon: <i className="fas fa-user-friends"></i>,
      link: '/dashboard/mentor/mentees',
      name: 'Mentee',
    },
    // {
    //   id: 2,
    //   icon: <i className="fas fa-code"></i>,
    //   link: '/dashboard/track',
    //   name: 'Tracks',
    // },
    {
      id: 2,
      icon: <i className="fas fa-tasks"></i>,
      link: '/dashboard/mentor/tasks-submissions/',
      name: 'Tasks',
    },
    {
      id: 3,
      icon: <i className="fas fa-user-ninja"></i>,
      link: '/dashboard/mentor/profile',
      name: 'Profile',
    },

    {
      id: 4,
      icon: <i className="fas fa-sliders-h"></i>,
      link: '#',
      name: 'Settings',
    },
  ];
  return (
    <MentorDashboardSidebarStyled showSidebar={showSidebar}>
      <Link to="/">
        <img src={codeClanLogo} alt="code clan" className="img-fluid" />
      </Link>

      <ul>
        <li className="main-menu-link">
          <DashboardBulletLogo />{' '}
          <Link to="/dashboard/mentor/mentees/"> Dashboard</Link>
        </li>

        {tabs.map(tab => (
          <li
            key={tab.id}
            className={` sub-menu ${path === tab.link ? 'active-icon ' : ''} `}
          >
            {/* <DashboardStackLogo /> */}
            {tab.icon}

            <Link to={`${tab.link}`}> {tab.name}</Link>
          </li>
        ))}

        {/* <li className="sub-menu">
          <DashboardStackLogo />
          <Link to="/dashboard/mentor/mentees/"> Mentees</Link>
        </li> */}
        {/* <li className="sub-menu">
          <DashboardStackLogo /> Courses
        </li>
        <li className="sub-menu">
          <DashboardStackLogo /> Tasks
        </li> */}

        <li className="logout__link">
          <Popconfirm
            title="Are sure you want to log out?"
            okText="Yes"
            placement="topLeft"
            cancelText="Oppss"
            onConfirm={() => logoutUser()}
            icon={<QuestionCircleOutlined style={{ color: 'red' }} />}
          >
            <button className="btn btn-lg btn-primary">
              <i className="fas fa-power-off"></i> Logout
            </button>
          </Popconfirm>
        </li>
      </ul>
    </MentorDashboardSidebarStyled>
  );
}
Example #19
Source File: submission.js    From deadviz with MIT License 4 votes vote down vote up
Submission = ({ onSubmit }) => {
    const [form] = Form.useForm();

    const onFinish = values => {
        onSubmit(values);
        form.resetFields();
    };

    return (
        <StyledForm
            requiredMark={false}
            form={form}
            onFinish={onFinish}>
            <Form.Item name="name" label={
                <span>
                    Name&nbsp;
                    <Tooltip title="What's your plan/goal?">
                        <QuestionCircleOutlined />
                    </Tooltip>
                </span>
            } hasFeedback rules={[{ required: true, message: 'Please input your plan/goal', whitespace: true }]}>
                <Input placeholder="My ultimate goal" />
            </Form.Item>
            <Form.Item name="start" label={
                <span>
                    Start&nbsp;
                    <Tooltip title="Goal's Start Date">
                        <QuestionCircleOutlined />
                    </Tooltip>
                </span>
            }
                initialValue={dayjs()}
                hasFeedback
                dependencies={['end']}
                rules={[
                    { type: 'object', required: true, message: 'Please select start time' },
                    ({ getFieldValue }) => ({
                        validator(rule, value) {
                            if (!value || getFieldValue('end') > value) {
                                return Promise.resolve();
                            }
                            return Promise.reject('The start date should be before end date');
                        },
                    })]}>
                <DatePicker initialValues={dayjs()} className="full-width" />
            </Form.Item>
            <Form.Item name="end" label={
                <span>
                    End&nbsp;
                    <Tooltip title="Goal's End Date">
                        <QuestionCircleOutlined />
                    </Tooltip>
                </span>
            }
                hasFeedback
                initialValue={dayjs().add(1, 'y')}
                dependencies={['start']}
                rules={[
                    { type: 'object', required: true, message: 'Please select end time' },
                    ({ getFieldValue }) => ({
                        validator(rule, value) {
                            if (!value || getFieldValue('start') < value) {
                                return Promise.resolve();
                            }
                            return Promise.reject('The end date should be after start date');
                        },
                    })]}>
                <DatePicker initialValues={dayjs().add(1, 'y')} className="full-width" />
            </Form.Item>
            <Form.Item name="priority" style={{ width: '100%' }} hasFeedback
                label={
                    <span>
                        Priority&nbsp;
                    <Tooltip title="Goal's Priority">
                            <QuestionCircleOutlined />
                        </Tooltip>
                    </span>
                }>
                <Slider style={{ width: '85%' }} defaultValue={0.5} max={1.0} min={0.0} marks={false} step={0.01} />
            </Form.Item>
            <Form.Item>
                <StyledButton size="large" icon={<UnorderedListOutlined />} shape="round" className="centered" type="primary"
                    htmlType="submit">
                    Add to List
                </StyledButton>
            </Form.Item>
        </StyledForm>
    );
}