@ant-design/icons#InfoCircleOutlined JavaScript Examples

The following examples show how to use @ant-design/icons#InfoCircleOutlined. 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: presuffix.jsx    From virtuoso-design-system with MIT License 6 votes vote down vote up
storiesOf('antd/Input', module).add('presuffix', () => 
  <>
    <Input
      placeholder="Enter your username"
      prefix={<UserOutlined className="site-form-item-icon" />}
      suffix={
        <Tooltip title="Extra information">
          <InfoCircleOutlined style={{ color: 'rgba(0,0,0,.45)' }} />
        </Tooltip>
      }
    />
    <br />
    <br />
    <Input prefix="¥" suffix="RMB" />
    <br />
    <br />
    <Input prefix="¥" suffix="RMB" disabled />
  </>,
  { docs: { page: () => (<><h1 id="enus">en-US</h1>
<p>Add a prefix or suffix icons inside input.</p></>) } });
Example #2
Source File: infoTooltip.js    From virtuoso-design-system with MIT License 6 votes vote down vote up
InfoTooltip = ({ title, placement, size, trigger }) => {
  return (
    <span className={styles.wrap}>
      <Tooltip placement={placement} title={title} trigger={trigger}>
        <InfoCircleOutlined style={{ fontSize: size }} />
      </Tooltip>
    </span>
  );
}
Example #3
Source File: Label.js    From bonded-stablecoin-ui with MIT License 6 votes vote down vote up
Label = ({
  label,
  descr,
  required = false,
  type = "attention",
}) => {
  return (
    <span style={{ display: "flex", alignItems: "center" }}>
      <span style={{ paddingRight: 5 }}>
        {label}
        {required && <span style={{ color: "red" }}>*</span>}
      </span>
      <Tooltip title={descr}>
        <InfoCircleOutlined />
      </Tooltip>
    </span>
  );
}
Example #4
Source File: github_rate_limit_status_bar.js    From art-dashboard-ui with Apache License 2.0 6 votes vote down vote up
render() {
        return (
            <div>
                <Row style={{padding: "30px"}} className="center">
                    <Col span={23}>
                        <p>GitHub Developer API Quota Stats</p>
                    </Col>
                    <Col span={1}>
                        <InfoCircleOutlined className="right" onClick={this.openNotification} />
                    </Col>
                </Row>
                <Row style={{padding: "30px"}}>
                    <Col span={8}>
                        <Statistics_components title="Total" value={this.state.total}/>
                    </Col>
                    <Col span={8}>
                        <Statistics_components title="Remaining" value={this.state.remaining}/>
                    </Col>
                    <Col span={8}>
                        <Github_rate_limit_status_bar_countdown minutes={this.state.time_to_reset_mins}/>
                    </Col>
                </Row>
            </div>
        )
    }
Example #5
Source File: TopSearch.jsx    From prometheusPro with MIT License 5 votes vote down vote up
TopSearch = ({ loading, visitData2, searchData, dropdownGroup }) => (
  <Card
    loading={loading}
    bordered={false}
    title="线上热门搜索"
    extra={dropdownGroup}
    style={{
      height: '100%',
    }}
  >
    <Row gutter={68} type="flex">
      <Col
        sm={12}
        xs={24}
        style={{
          marginBottom: 24,
        }}
      >
        <NumberInfo
          subTitle={
            <span>
              搜索用户数
              <Tooltip title="指标说明">
                <InfoCircleOutlined
                  style={{
                    marginLeft: 8,
                  }}
                />
              </Tooltip>
            </span>
          }
          gap={8}
          total={numeral(12321).format('0,0')}
          status="up"
          subTotal={17.1}
        />
        <MiniArea line height={45} data={visitData2} />
      </Col>
      <Col
        sm={12}
        xs={24}
        style={{
          marginBottom: 24,
        }}
      >
        <NumberInfo
          subTitle={
            <span>
              人均搜索次数
              <Tooltip title="指标说明">
                <InfoCircleOutlined
                  style={{
                    marginLeft: 8,
                  }}
                />
              </Tooltip>
            </span>
          }
          total={2.7}
          status="down"
          subTotal={26.2}
          gap={8}
        />
        <MiniArea line height={45} data={visitData2} />
      </Col>
    </Row>
    <Table
      rowKey={record => record.index}
      size="small"
      columns={columns}
      dataSource={searchData}
      pagination={{
        style: {
          marginBottom: 0,
        },
        pageSize: 5,
      }}
    />
  </Card>
)
Example #6
Source File: CalculationConfig.jsx    From ui with MIT License 5 votes vote down vote up
CellSizeDistributionConfig = (props) => {
  const {
    config, disabled, updateSettings, highestUmi,
  } = props;

  const withinRange = (cellSize) => Math.max(Math.min(cellSize, highestUmi), 0);

  return (
    <>

      <Form.Item disabled label='Minimum #UMIs per cell'>
        <Space>
          <Tooltip title='The cut-off is automatically calculated as the inflection point of the knee plot. The inflection point estimates the boundary between empty drops and droplets that contain cells. The number of UMIs per cell varies depending on cell type. The typical minimum threshold range approx. 500-2000.'>
            <InfoCircleOutlined />
          </Tooltip>
          <InputNumber
            value={config.minCellSize}
            onChange={(value) => {
              updateSettings({ minCellSize: withinRange(value) });
            }}
            onPressEnter={(e) => {
              updateSettings({ minCellSize: withinRange(e.target.value) });
            }}
            placeholder={MIN_CELL_SIZE_PLACEHOLDER}
            step={100}
            disabled={disabled}
            max={highestUmi}
            min={0}
          />
        </Space>
      </Form.Item>

      <Form.Item label='Bin step'>
        <SliderWithInput
          min={100}
          max={400}
          value={config.binStep}
          onUpdate={(value) => {
            updateSettings({ binStep: value });
          }}
          disabled={disabled}
        />
      </Form.Item>
    </>
  );
}
Example #7
Source File: CalculationConfig.jsx    From ui with MIT License 5 votes vote down vote up
ClassifierConfig = (props) => {
  const {
    // eslint-disable-next-line no-unused-vars
    config, disabled, updateSettings,
  } = props;

  return (
    <>
      <Form.Item label='FDR'>
        <Space direction='horizontal'>
          <Tooltip overlay={(
            <span>
              False discovery rate (FDR) is calculated for each barcode by using the
              {' '}
              <a
                href='https://rdrr.io/github/MarioniLab/DropletUtils/man/emptyDrops.html'
                target='_blank'
                rel='noreferrer'
              >
                <code>emptyDrops</code>
                {' '}
                function
              </a>
              . This
              distinguishes between droplets containing cells and ambient RNA. The FDR range is
              [0-1]. The default FDR value is 0.01, where only barcodes with FDR &lt; 0.01
              are retained.
            </span>
          )}
          >
            <InfoCircleOutlined />
          </Tooltip>
          <InputNumber
            value={config.FDR}
            onChange={(value) => updateSettings({ FDR: value })}
            onPressEnter={(e) => updateSettings({ FDR: e.target.value })}
            placeholder={0.01}
            min={0.00}
            max={1.00}
            step={0.01}
            disabled={disabled}
          />
        </Space>
      </Form.Item>
    </>
  );
}
Example #8
Source File: CalculationConfig.jsx    From ui with MIT License 5 votes vote down vote up
GenesVsUMIsConfig = (props) => {
  const {
    // eslint-disable-next-line no-unused-vars
    config, disabled, plotType, updateSettings,
  } = props;

  return (
    <>
      <Form.Item label={(
        <span>
          Fit type&nbsp;
          <Tooltip overlay={(
            <span>
              A linear fit works well for most samples and is performed with `MASS::rlm`.
              A spline fit is useful to prevent excluding samples that show a natural saturation
              in the gene counts at high molecule counts and is performed with `splines::bs`.
            </span>
          )}
          >
            <InfoCircleOutlined />
          </Tooltip>
        </span>
      )}
      >
        <Select
          value={config.regressionType}
          onChange={(val) => updateSettings({ regressionType: val })}
          disabled={disabled}
        >
          <Option value='linear'>linear</Option>
          <Option value='spline'>spline</Option>
        </Select>
      </Form.Item>
      <Form.Item label='p-level cut-off:'>
        <Space direction='horizontal'>
          <Tooltip title='Regression of feature counts (genes) vs UMI counts (molecules) is performed for all cells in order to detect outliers. The ‘p-level cut-off’ is the stringency for defining outliers: ‘p.level’ refers to the confidence level for a given cell to deviate from the main trend. The smaller the number the more stringent cut-off.
‘p.level’ sets the prediction intervals calculated by the R `predict` where `level = 1 - p.value`.'
          >
            <InfoCircleOutlined />
          </Tooltip>
          <InputNumber
            value={config.regressionTypeSettings[config.regressionType]['p.level']}
            onChange={(value) => updateSettings({ regressionTypeSettings: { [config.regressionType]: { 'p.level': value } } })}
            onPressEnter={(e) => updateSettings({ regressionTypeSettings: { [config.regressionType]: { 'p.level': e.target.value } } })}
            placeholder={0.00001}
            min={0}
            max={1}
            step={0.00001}
            disabled={disabled}
          />
        </Space>
      </Form.Item>
    </>
  );
}
Example #9
Source File: Settings.js    From 4IZ268-2021-2022-ZS with MIT License 5 votes vote down vote up
Settings = () => {

    const [visible, setVisible] = useState(false);

    const navigate = useNavigate()

    const handleMenuClick = (e) => {
        // console.log(e)
    }

    const handleVisibleChange = (flag) => {
        setVisible(flag)
    }

    const onRaceSelect = () => {
        navigate('~bukp00/sp2/')
    }

    const menu = (
        <Menu onClick={handleMenuClick}>
            <Menu.Item key={1}>
                <div>
                    <span>Zvýraznit oddíl: </span>
                    <Tooltip
                        title={<span>Veřejné API nenabízí výpis všech klubů, proto v nabídce najdete pouze ty kluby, které již byly vypsané v tabulce.</span>}
                    >
                        <InfoCircleOutlined style={{ color: 'rgba(20, 170, 20, 0.7)' }} />
                    </Tooltip>
                    <br />
                    <HighlightInput />
                </div>
            </Menu.Item>
            <Menu.Item key={2}>
                <div>
                    <RefetchIntervalInput />
                </div>
            </Menu.Item>
            <Menu.Item key={3}>
                <div>
                    <Button onClick={onRaceSelect}>Vybrat závod</Button>
                </div>
            </Menu.Item>
        </Menu>
    )

    return (
        <Dropdown
            overlay={menu}
            onVisibleChange={handleVisibleChange}
            visible={visible}
        >
            <SettingOutlined
                style={{ fontSize: '1.5rem', color: 'rgba(255, 255, 255, 0.7)' }}
                onClick={() => setVisible(true)}
            />
        </Dropdown>
    )
}
Example #10
Source File: styles.js    From bank-client with MIT License 5 votes vote down vote up
StyledInfoCircleOutlined = styled(InfoCircleOutlined)`
  font-size: 40px;
  margin-right: 13px;
`
Example #11
Source File: index.jsx    From ui with MIT License 4 votes vote down vote up
DataProcessingPage = ({ experimentId, experimentData }) => {
  const dispatch = useDispatch();
  const { navigateTo } = useAppRouter();

  const pipelineStatus = useSelector(getBackendStatus(experimentId))?.status?.pipeline;

  const processingConfig = useSelector((state) => state.experimentSettings.processing);
  const sampleKeys = useSelector((state) => state.experimentSettings.info.sampleIds);
  const samples = useSelector((state) => state.samples);

  const pipelineStatusKey = pipelineStatus?.status;
  const pipelineRunning = pipelineStatusKey === 'RUNNING';

  // Pipeline is not loaded (either running or in an errored state)
  const pipelineErrors = ['FAILED', 'TIMED_OUT', 'ABORTED'];
  const pipelineHadErrors = pipelineErrors.includes(pipelineStatusKey);
  const pipelineNotFinished = pipelineRunning || pipelineHadErrors;

  const completedSteps = pipelineStatus?.completedSteps || [];

  const changedQCFilters = useSelector(
    (state) => state.experimentSettings.processing.meta.changedQCFilters,
  );

  const changesOutstanding = Boolean(changedQCFilters.size);

  const [stepIdx, setStepIdx] = useState(0);
  const [runQCModalVisible, setRunQCModalVisible] = useState(false);
  const [inputsList, setInputsList] = useState([]);

  useEffect(() => {
    // If processingConfig is not loaded then reload
    if (Object.keys(processingConfig).length <= 1) {
      dispatch(loadProcessingSettings(experimentId));
    }

    dispatch(loadSamples(experimentId));
    dispatch(loadCellSets(experimentId));
  }, []);

  // Checks if the step is in the 'completed steps' list we get from the pipeline status
  const isStepComplete = (stepName) => {
    if (stepName === undefined) {
      return true;
    }

    const lowerCaseStepName = stepName.toLowerCase();

    const stepAppearances = _.filter(
      completedSteps,
      (stepPipelineName) => stepPipelineName.toLowerCase().includes(lowerCaseStepName),
    );

    return stepAppearances.length > 0;
  };

  const onConfigChange = useCallback((key) => {
    dispatch(addChangedQCFilter(key));
  });

  const prefixSampleName = (name) => {
    // eslint-disable-next-line no-param-reassign
    if (!name.match(/$sample/ig)) name = `Sample ${name}`;
    return name;
  };

  useEffect(() => {
    if (sampleKeys && sampleKeys.length > 0 && Object.keys(samples).filter((key) => key !== 'meta').length > 0) {
      const list = sampleKeys?.map((sampleId) => ({
        key: sampleId,
        headerName: prefixSampleName(samples[sampleId].name),
        params: { key: sampleId },
      }));
      setInputsList(list);
    }
  }, [samples, sampleKeys]);

  const steps = [
    {

      key: 'classifier',
      name: getUserFriendlyQCStepName('classifier'),
      description: 'The Classifier filter is based on the ‘emptyDrops’ method which distinguishes between droplets containing cells and ambient RNA. Droplets are filtered based on the False Discovery Rate (FDR) value - the red line on the density plot. In the knee plot, the ‘mixed’ population shown in grey contains some cells that are filtered out and some that remain and can be filtered further in the next filter.',
      multiSample: true,
      render: (key) => (
        <SingleComponentMultipleDataContainer
          defaultActiveKey={sampleKeys}
          inputsList={inputsList}
          baseComponentRenderer={(sample) => (
            <Classifier
              id='classifier'
              experimentId={experimentId}
              filtering
              key={key}
              sampleId={sample.key}
              sampleIds={sampleKeys}
              onConfigChange={() => onConfigChange(key)}
              stepDisabled={!processingConfig[key]?.enabled}
            />
          )}
        />
      ),
    },
    {
      key: 'cellSizeDistribution',
      name: getUserFriendlyQCStepName('cellSizeDistribution'),
      description: 'The number of unique molecular identifiers (#UMIs) per cell distinguishes real cells (high #UMIs per cell) from empty droplets (low #UMIs per cell). This filter is used to detect empty droplets and fine-tunes the Classifier filter. In some datasets this filter might be used instead of the Classifier filter.',
      multiSample: true,
      render: (key) => (
        <SingleComponentMultipleDataContainer
          defaultActiveKey={sampleKeys}
          inputsList={inputsList}
          baseComponentRenderer={(sample) => (
            <CellSizeDistribution
              experimentId={experimentId}
              filtering
              key={key}
              sampleId={sample.key}
              sampleIds={sampleKeys}
              onConfigChange={() => onConfigChange(key)}
              stepDisabled={!processingConfig[key].enabled}
            />
          )}
        />
      ),
    },
    {
      key: 'mitochondrialContent',
      name: getUserFriendlyQCStepName('mitochondrialContent'),
      description: 'A high percentage of mitochondrial reads is an indicator of cell death. UMIs mapped to mitochondrial genes are calculated as a percentage of total UMIs. The percentage of mitochondrial reads depends on the cell type. The typical cut-off range is 10-50%, with the default cut-off set to 3 median absolute deviations above the median.',
      multiSample: true,
      render: (key) => (
        <SingleComponentMultipleDataContainer
          defaultActiveKey={sampleKeys}
          inputsList={inputsList}
          baseComponentRenderer={(sample) => (
            <MitochondrialContent
              experimentId={experimentId}
              filtering
              key={key}
              sampleId={sample.key}
              sampleIds={sampleKeys}
              onConfigChange={() => onConfigChange(key)}
              stepDisabled={!processingConfig[key].enabled}
            />
          )}
        />
      ),
    },
    {
      key: 'numGenesVsNumUmis',
      name: getUserFriendlyQCStepName('numGenesVsNumUmis'),
      description: 'The number of expressed genes per cell and number of UMIs per cell is expected to have a linear relationship. This filter is used to exclude outliers (e.g. many UMIs originating from only a few genes).',
      multiSample: true,
      render: (key) => (
        <SingleComponentMultipleDataContainer
          defaultActiveKey={sampleKeys}
          inputsList={inputsList}
          baseComponentRenderer={(sample) => (
            <GenesVsUMIs
              experimentId={experimentId}
              filtering
              key={key}
              sampleId={sample.key}
              sampleIds={sampleKeys}
              onConfigChange={() => onConfigChange(key)}
              stepDisabled={!processingConfig[key].enabled}
            />
          )}
        />
      ),
    },
    {
      key: 'doubletScores',
      name: getUserFriendlyQCStepName('doubletScores'),
      description:
        <span>
          Droplets may contain more than one cell.
          In such cases, it is not possible to distinguish which reads came from which cell.
          Such “cells” cause problems in the downstream analysis as they appear as an intermediate type.
          “Cells” with a high probability of being a doublet should be excluded.
          The probability of being a doublet is calculated using ‘scDblFinder’.
          For each sample, the default threshold tries to minimize both the deviation in the
          expected number of doublets and the error of a trained classifier. For more details see
          {' '}
          <a href='https://bioconductor.org/packages/devel/bioc/vignettes/scDblFinder/inst/doc/scDblFinder.html#thresholding' rel='noreferrer' target='_blank'>scDblFinder thresholding</a>
          .
        </span>,
      multiSample: true,
      render: (key) => (
        <SingleComponentMultipleDataContainer
          defaultActiveKey={sampleKeys}
          inputsList={inputsList}
          baseComponentRenderer={(sample) => (
            <DoubletScores
              experimentId={experimentId}
              filtering
              key={key}
              sampleId={sample.key}
              sampleIds={sampleKeys}
              onConfigChange={() => onConfigChange(key)}
              stepDisabled={!processingConfig[key].enabled}
            />
          )}
        />
      ),
    },
    {
      key: 'dataIntegration',
      name: getUserFriendlyQCStepName('dataIntegration'),
      multiSample: false,
      render: (key, expId) => (
        <DataIntegration
          experimentId={expId}
          key={key}
          onConfigChange={() => onConfigChange(key)}
          disableDataIntegration={sampleKeys && sampleKeys.length === 1}
        />
      ),
    },
    {
      key: 'configureEmbedding',
      name: getUserFriendlyQCStepName('configureEmbedding'),
      description: 'Cells and clusters are visualized in a 2-dimensional embedding. The UMAP or t-SNE embedding plot can be selected and customized. The clustering method (e.g. Louvain) and resolution are set here.',
      multiSample: false,
      render: (key, expId) => (
        <ConfigureEmbedding
          experimentId={expId}
          key={key}
          onConfigChange={() => onConfigChange(key)}
        />
      ),
    },
  ];

  const currentStep = steps[stepIdx];

  // check that the order and identities of the QC steps above match
  // the canonical representation
  console.assert(_.isEqual(qcSteps, steps.map((s) => s.key)));

  const changeStepId = (newStepIdx) => {
    setStepIdx(newStepIdx);
  };

  const renderRunButton = (runMessage, useSmall = true) => (
    <Tooltip title='Run data processing with the changed settings'>
      <Button
        data-testid='runFilterButton'
        type='primary'
        onClick={() => setRunQCModalVisible(true)}
        style={{ minWidth: '80px' }}
        size={useSmall ? 'small' : 'medium'}
      >
        {runMessage}
      </Button>
    </Tooltip>
  );

  const renderRunOrDiscardButtons = () => {
    if (pipelineHadErrors) {
      return renderRunButton('Run Data Processing', false);
    } if (changesOutstanding) {
      return (
        <Alert
          message={<>Your new settings are not yet applied</>}
          type='info'
          showIcon
          style={{
            paddingTop: '3px', paddingBottom: '3px', paddingLeft: '10px', paddingRight: '10px',
          }}
          action={(
            <Space size='small'>
              {renderRunButton('Run', true)}
              <Tooltip title='Discard your changes since the last run'>
                <Button
                  id='discardChangesButton'
                  data-testid='discardChangesButton'
                  type='primary'
                  onClick={() => { dispatch(discardChangedQCFilters()); }}
                  style={{ width: '80px' }}
                  size='small'
                >
                  Discard
                </Button>
              </Tooltip>
            </Space>
          )}
        />
      );
    }
  };

  // Called when the pipeline is triggered to be run by the user.
  const onPipelineRun = () => {
    setRunQCModalVisible(false);
    dispatch(runQC(experimentId));
  };

  const renderTitle = () => {
    const stepEnabled = processingConfig[currentStep.key]?.enabled;
    const prefiltered = processingConfig[currentStep.key]?.prefiltered || false;

    return (
      <>
        <Row justify='space-between'>
          <Col style={{ paddingBottom: '8px' }}>
            {/* Should be just wide enough that no ellipsis appears */}
            <Row>
              <Col style={{ paddingBottom: '8px', paddingRight: '8px' }}>
                <Space size='small'>
                  <Select
                    value={stepIdx}
                    onChange={(idx) => {
                      changeStepId(idx);
                    }}
                    style={{ fontWeight: 'bold', width: 290 }}
                    placeholder='Jump to a step...'
                  >
                    {
                      steps.map(
                        ({ name, key }, i) => {
                          const disabledByPipeline = (pipelineNotFinished && !isStepComplete(key));
                          const text = `${i + 1}. ${name}`;

                          return (
                            <Option
                              value={i}
                              key={key}
                              disabled={
                                disabledByPipeline
                              }
                            >
                              {processingConfig[key]?.enabled === false ? (
                                <>
                                  {/* disabled */}
                                  <Text
                                    type='secondary'
                                  >
                                    <CloseOutlined />
                                  </Text>
                                  <span
                                    style={{ marginLeft: '0.25rem', textDecoration: 'line-through' }}
                                  >
                                    {text}
                                  </span>
                                </>
                              ) : !disabledByPipeline ? (
                                <>
                                  {/* finished */}
                                  <Text
                                    type='success'
                                  >
                                    <CheckOutlined />
                                  </Text>
                                  <span
                                    style={{ marginLeft: '0.25rem' }}
                                  >
                                    {text}
                                  </span>
                                </>
                              ) : pipelineRunning && !isStepComplete(key) ? (
                                <>
                                  {/* incomplete */}
                                  <Text
                                    type='warning'
                                    strong
                                  >
                                    <EllipsisOutlined />
                                  </Text>
                                  <span style={{ marginLeft: '0.25rem' }}>{text}</span>
                                </>
                              ) : pipelineNotFinished
                                && !pipelineRunning
                                && !isStepComplete(key) ? (
                                <>
                                  <Text
                                    type='danger'
                                    strong
                                  >
                                    <WarningOutlined />
                                  </Text>
                                  <span style={{ marginLeft: '0.25rem' }}>{text}</span>
                                </>
                              ) : <></>}
                            </Option>
                          );
                        },
                      )
                    }
                  </Select>
                  {currentStep.description && (
                    <Tooltip title={currentStep.description}>
                      <Button icon={<InfoCircleOutlined />} />
                    </Tooltip>
                  )}
                  {currentStep.multiSample && (
                    <Tooltip title={`${!stepEnabled ? 'Enable this filter' : 'Disable this filter'}`}>
                      <Button
                        disabled={prefiltered}
                        data-testid='enableFilterButton'
                        onClick={async () => {
                          await dispatch(saveProcessingSettings(experimentId, currentStep.key));
                          if (!processingConfig.meta.saveSettingsError) {
                            dispatch(setQCStepEnabled(
                              currentStep.key, !stepEnabled,
                            ));
                          }
                        }}
                      >
                        {
                          stepEnabled ? 'Disable' : 'Enable'
                        }
                      </Button>
                    </Tooltip>
                  )}
                </Space>
              </Col>
              <Col>
                {renderRunOrDiscardButtons()}
              </Col>
            </Row>
          </Col>
          <Col>
            <Row align='middle' justify='space-between'>
              <Col>
                <StatusIndicator
                  experimentId={experimentId}
                  allSteps={steps}
                  currentStep={stepIdx}
                  completedSteps={completedSteps}
                />
                <Space size='small'>
                  <Tooltip title='Previous'>
                    <Button
                      data-testid='pipelinePrevStep'
                      disabled={stepIdx === 0}
                      icon={<LeftOutlined />}
                      onClick={() => changeStepId(Math.max(stepIdx - 1, 0))}
                      size='small'
                    />
                  </Tooltip>
                  {stepIdx !== steps.length - 1 ? (
                    <Tooltip title='Next'>
                      <Button
                        data-testid='pipelineNextStep'
                        onClick={() => {
                          const newStepIdx = Math.min(stepIdx + 1, steps.length - 1);
                          changeStepId(newStepIdx);
                        }}
                        disabled={steps[stepIdx + 1] !== undefined
                          && pipelineNotFinished
                          && !isStepComplete(steps[stepIdx + 1].key)}
                        icon={<RightOutlined />}
                        size='small'
                      />
                    </Tooltip>
                  )
                    : (
                      <Tooltip title='Finish QC'>
                        <Button
                          type='primary'
                          disabled={steps[stepIdx + 1]
                            && pipelineNotFinished
                            && !isStepComplete(steps[stepIdx + 1].key)}
                          icon={<CheckOutlined />}
                          size='small'
                          onClick={() => navigateTo(modules.DATA_EXPLORATION, { experimentId })}
                        />
                      </Tooltip>
                    )}
                </Space>
              </Col>
            </Row>
          </Col>
        </Row>
      </>
    );
  };

  const renderContent = () => {
    const { render, key } = currentStep;

    if (pipelineRunning && !isStepComplete(key)) {
      return <div><PipelineRedirectToDataProcessing pipelineStatus='runningStep' /></div>;
    }

    if (pipelineNotFinished && !isStepComplete(key)) {
      return (
        <div>
          <div style={{ display: 'flex', justifyContent: 'center' }}>
            <PlatformError
              description={'We don\'t have anything for this step.'}
              reason='The last run ended before this step could be finished.'
              onClick={() => { onPipelineRun(); }}
            />
          </div>
        </div>
      );
    }

    if (samples.meta.loading
      || processingConfig.meta.loading
      || Object.keys(processingConfig).length <= 1
    ) {
      return (
        <div className='preloadContextSkeleton' style={{ padding: '16px 0px' }}>
          <Skeleton.Input style={{ width: '100%', height: 400 }} active />
        </div>
      );
    }

    if (samples.meta.error || processingConfig.meta.loadingSettingsError) {
      return (
        <PlatformError
          error={samples.meta.error.toString()
            || processingConfig.meta.loadingSettingsError.toString()}
          onClick={() => { dispatch(loadSamples(experimentId)); }}
        />
      );
    }

    return (
      <Space direction='vertical' style={{ width: '100%' }}>
        {
          'enabled' in processingConfig[key] && !processingConfig[key].enabled ? (
            <Alert
              message={processingConfig[key]?.prefiltered
                ? 'This filter is disabled because the one of the sample(s) is pre-filtered. Click \'Next\' to continue processing your data.'
                : 'This filter is disabled. You can still modify and save changes, but the filter will not be applied to your data.'}
              type='info'
              showIcon
            />
          ) : <></>
        }

        {render(key, experimentId)}
      </Space>
    );
  };

  return (
    <>
      <Header
        experimentId={experimentId}
        experimentData={experimentData}
        title='Data Processing'
      />
      <Space direction='vertical' style={{ width: '100%', padding: '0 10px' }}>

        {runQCModalVisible && (
          <Modal
            title='Run data processing with the changed settings'
            visible
            onCancel={() => setRunQCModalVisible(false)}
            onOk={() => onPipelineRun()}
            okText='Start'
          >
            <p>
              This might take several minutes.
              Your navigation within Cellenics will be restricted during this time.
              Do you want to start?
            </p>
          </Modal>
        )}
        <Card
          title={renderTitle()}
        >
          {renderContent()}
        </Card>
      </Space>
    </>
  );
}
Example #12
Source File: index.jsx    From prometheusPro with MIT License 4 votes vote down vote up
render() {
    const { submitting } = this.props;
    const {
      form: { getFieldDecorator, getFieldValue },
    } = this.props;
    const formItemLayout = {
      labelCol: {
        xs: {
          span: 24,
        },
        sm: {
          span: 7,
        },
      },
      wrapperCol: {
        xs: {
          span: 24,
        },
        sm: {
          span: 12,
        },
        md: {
          span: 10,
        },
      },
    };
    const submitFormLayout = {
      wrapperCol: {
        xs: {
          span: 24,
          offset: 0,
        },
        sm: {
          span: 10,
          offset: 7,
        },
      },
    };
    return (
      <PageHeaderWrapper content="表单页用于向用户收集或验证信息,基础表单常见于数据项较少的表单场景。">
        <Card bordered={false}>
          <Form
            onSubmit={this.handleSubmit}
            hideRequiredMark
            style={{
              marginTop: 8,
            }}
          >
            <FormItem {...formItemLayout} label="标题">
              {getFieldDecorator('title', {
                rules: [
                  {
                    required: true,
                    message: '请输入标题',
                  },
                ],
              })(<Input placeholder="给目标起个名字" />)}
            </FormItem>
            <FormItem {...formItemLayout} label="起止日期">
              {getFieldDecorator('date', {
                rules: [
                  {
                    required: true,
                    message: '请选择起止日期',
                  },
                ],
              })(
                <RangePicker
                  style={{
                    width: '100%',
                  }}
                  placeholder={['开始日期', '结束日期']}
                />,
              )}
            </FormItem>
            <FormItem {...formItemLayout} label="目标描述">
              {getFieldDecorator('goal', {
                rules: [
                  {
                    required: true,
                    message: '请输入目标描述',
                  },
                ],
              })(
                <TextArea
                  style={{
                    minHeight: 32,
                  }}
                  placeholder="请输入你的阶段性工作目标"
                  rows={4}
                />,
              )}
            </FormItem>
            <FormItem {...formItemLayout} label="衡量标准">
              {getFieldDecorator('standard', {
                rules: [
                  {
                    required: true,
                    message: '请输入衡量标准',
                  },
                ],
              })(
                <TextArea
                  style={{
                    minHeight: 32,
                  }}
                  placeholder="请输入衡量标准"
                  rows={4}
                />,
              )}
            </FormItem>
            <FormItem
              {...formItemLayout}
              label={
                <span>
                  客户
                  <em className={styles.optional}>
                    (选填)
                    <Tooltip title="目标的服务对象">
                      <InfoCircleOutlined
                        style={{
                          marginRight: 4,
                        }}
                      />
                    </Tooltip>
                  </em>
                </span>
              }
            >
              {getFieldDecorator('client')(
                <Input placeholder="请描述你服务的客户,内部客户直接 @姓名/工号" />,
              )}
            </FormItem>
            <FormItem
              {...formItemLayout}
              label={
                <span>
                  邀评人
                  <em className={styles.optional}>(选填)</em>
                </span>
              }
            >
              {getFieldDecorator('invites')(
                <Input placeholder="请直接 @姓名/工号,最多可邀请 5 人" />,
              )}
            </FormItem>
            <FormItem
              {...formItemLayout}
              label={
                <span>
                  权重
                  <em className={styles.optional}>(选填)</em>
                </span>
              }
            >
              {getFieldDecorator('weight')(<InputNumber placeholder="请输入" min={0} max={100} />)}
              <span className="ant-form-text">%</span>
            </FormItem>
            <FormItem {...formItemLayout} label="目标公开" help="客户、邀评人默认被分享">
              <div>
                {getFieldDecorator('public', {
                  initialValue: '1',
                })(
                  <Radio.Group>
                    <Radio value="1">公开</Radio>
                    <Radio value="2">部分公开</Radio>
                    <Radio value="3">不公开</Radio>
                  </Radio.Group>,
                )}
                <FormItem
                  style={{
                    marginBottom: 0,
                  }}
                >
                  {getFieldDecorator('publicUsers')(
                    <Select
                      mode="multiple"
                      placeholder="公开给"
                      style={{
                        margin: '8px 0',
                        display: getFieldValue('public') === '2' ? 'block' : 'none',
                      }}
                    >
                      <Option value="1">同事甲</Option>
                      <Option value="2">同事乙</Option>
                      <Option value="3">同事丙</Option>
                    </Select>,
                  )}
                </FormItem>
              </div>
            </FormItem>
            <FormItem
              {...submitFormLayout}
              style={{
                marginTop: 32,
              }}
            >
              <Button type="primary" htmlType="submit" loading={submitting}>
                提交
              </Button>
              <Button
                style={{
                  marginLeft: 8,
                }}
              >
                保存
              </Button>
            </FormItem>
          </Form>
        </Card>
      </PageHeaderWrapper>
    );
  }
Example #13
Source File: IntroduceRow.jsx    From prometheusPro with MIT License 4 votes vote down vote up
IntroduceRow = ({ loading, visitData }) => (
  <Row gutter={24} type="flex">
    <Col {...topColResponsiveProps}>
      <ChartCard
        bordered={false}
        title="总销售额"
        action={
          <Tooltip title="指标说明">
            <InfoCircleOutlined />
          </Tooltip>
        }
        loading={loading}
        total={() => <Yuan>126560</Yuan>}
        footer={<Field label="日销售额" value={`¥${numeral(12423).format('0,0')}`} />}
        contentHeight={46}
      >
        <Trend
          flag="up"
          style={{
            marginRight: 16,
          }}
        >
          周同比
          <span className={styles.trendText}>12%</span>
        </Trend>
        <Trend flag="down">
          日同比
          <span className={styles.trendText}>11%</span>
        </Trend>
      </ChartCard>
    </Col>

    <Col {...topColResponsiveProps}>
      <ChartCard
        bordered={false}
        loading={loading}
        title="访问量"
        action={
          <Tooltip title="指标说明">
            <InfoCircleOutlined />
          </Tooltip>
        }
        total={numeral(8846).format('0,0')}
        footer={<Field label="日访问量" value={numeral(1234).format('0,0')} />}
        contentHeight={46}
      >
        <MiniArea color="#975FE4" data={visitData} />
      </ChartCard>
    </Col>
    <Col {...topColResponsiveProps}>
      <ChartCard
        bordered={false}
        loading={loading}
        title="支付笔数"
        action={
          <Tooltip title="指标说明">
            <InfoCircleOutlined />
          </Tooltip>
        }
        total={numeral(6560).format('0,0')}
        footer={<Field label="转化率" value="60%" />}
        contentHeight={46}
      >
        <MiniBar data={visitData} />
      </ChartCard>
    </Col>
    <Col {...topColResponsiveProps}>
      <ChartCard
        loading={loading}
        bordered={false}
        title="运营活动效果"
        action={
          <Tooltip title="指标说明">
            <InfoCircleOutlined />
          </Tooltip>
        }
        total="78%"
        footer={
          <div
            style={{
              whiteSpace: 'nowrap',
              overflow: 'hidden',
            }}
          >
            <Trend
              flag="up"
              style={{
                marginRight: 16,
              }}
            >
              周同比
              <span className={styles.trendText}>12%</span>
            </Trend>
            <Trend flag="down">
              日同比
              <span className={styles.trendText}>11%</span>
            </Trend>
          </div>
        }
        contentHeight={46}
      >
        <MiniProgress percent={78} strokeWidth={8} target={80} color="#13C2C2" />
      </ChartCard>
    </Col>
  </Row>
)
Example #14
Source File: IntroduceRow.jsx    From the-eye-knows-the-garbage with MIT License 4 votes vote down vote up
IntroduceRow = ({ loading }) => {
    const [data, setData] = useState({})
    useEffect(() => {
        queryCount().then(r => setData(r.data))
    }, [])
    let cards = []
    const color_map = ['#FFBA95', '#E77048', '#858DE4', '#353B9D', '#FFDF84', '#FFB837', '#35908F', '#3DC2C4', '#BC91FF', '#9E56FC', '#3D9CFF', '#79C3FF']
    for (let dataKey in data) {
        const visitData = [
            {
                "x": "2020-07-18",
                "y": 7
            },
            {
                "x": "2020-07-19",
                "y": 5
            },
            {
                "x": "2020-07-20",
                "y": 4
            },
            {
                "x": "2020-07-21",
                "y": 2
            },
            {
                "x": "2020-07-22",
                "y": 4
            },
            {
                "x": "2020-07-23",
                "y": 7
            },
            {
                "x": "2020-07-24",
                "y": 5
            },
            {
                "x": "2020-07-25",
                "y": 6
            },
            {
                "x": "2020-07-26",
                "y": 5
            },
            {
                "x": "2020-07-27",
                "y": 9
            },
            {
                "x": "2020-07-28",
                "y": 6
            },
            {
                "x": "2020-07-29",
                "y": 3
            },
            {
                "x": "2020-07-30",
                "y": 1
            },
            {
                "x": "2020-07-31",
                "y": 5
            },
            {
                "x": "2020-08-01",
                "y": 3
            },
            {
                "x": "2020-08-02",
                "y": 6
            },
            {
                "x": "2020-08-03",
                "y": 5
            }
        ]
        cards.push(<Col key={dataKey} {...topColResponsiveProps}>
            <ChartCard
                bordered={false}
                loading={loading}
                title={dataKey}
                action={
                    <Tooltip
                        title={dataKey}
                    >
                        <InfoCircleOutlined />
                    </Tooltip>
                }
                total={numeral(data[dataKey]).format('0,0')}
                contentHeight={46}
            >
                <MiniArea color={color_map[getRandomInt(0, 11)]} data={visitData} />
            </ChartCard>
        </Col>)
    }
    return <Row gutter={24} type="flex">
        {cards}
    </Row>
}
Example #15
Source File: tasks.js    From hashcat.launcher with MIT License 4 votes vote down vote up
render() {
		const { taskKey, task } = this.state;

		return (
			<>
				<PageHeader
					title="Tasks"
				/>
				<Content style={{ padding: '16px 24px' }}>
					<Row gutter={16} className="height-100 tree-height-100">
						<Col className="max-height-100" span={5}>
							<Tree
								showIcon
								blockNode
								treeData={this.state.data}
								onSelect={this.onSelect}
								selectedKeys={[taskKey]}
								style={{
									height: '100%',
									paddingRight: '.5rem',
									overflow: 'auto',
									background: '#0a0a0a',
									border: '1px solid #303030'
								}}
							/>
						</Col>
						<Col className="max-height-100" span={19}>
							{task ? (
								<Row gutter={[16, 14]} className="height-100" style={{ flexDirection: "column", flexWrap: "nowrap" }}>
									<Col flex="0 0 auto">
										<Row gutter={[16, 14]}>
											<Col span={24}>
												<PageHeader
													title={task.id}
													tags={
														task.stats.hasOwnProperty("status") ? (	
															HASHCAT_STATUS_BADGE_WARNING.indexOf(task.stats["status"]) > -1 ? (
																<Tag color="warning">{HASHCAT_STATUS_MESSAGES[task.stats["status"]]}</Tag>
															) : HASHCAT_STATUS_BADGE_PROCESSING.indexOf(task.stats["status"]) > -1 ? (
																<Tag color="processing">{HASHCAT_STATUS_MESSAGES[task.stats["status"]]}</Tag>
															) : HASHCAT_STATUS_BADGE_ERROR.indexOf(task.stats["status"]) > -1 ? (
																<Tag color="error">{HASHCAT_STATUS_MESSAGES[task.stats["status"]]}</Tag>
															) : HASHCAT_STATUS_BADGE_SUCCESS.indexOf(task.stats["status"]) > -1 ? (
																<Tag color="success">{HASHCAT_STATUS_MESSAGES[task.stats["status"]]}</Tag>
															) : HASHCAT_STATUS_BADGE_PINK.indexOf(task.stats["status"]) > -1 ? (
																<Tag color="pink">{HASHCAT_STATUS_MESSAGES[task.stats["status"]]}</Tag>
															) : HASHCAT_STATUS_BADGE_YELLOW.indexOf(task.stats["status"]) > -1 ? (
																<Tag color="yellow">{HASHCAT_STATUS_MESSAGES[task.stats["status"]]}</Tag>
															) : (
																<Tag color="default">{HASHCAT_STATUS_MESSAGES[task.stats["status"]]}</Tag>
															)
														) : null
													}
													style={{ padding: 0 }}
													extra={
														<Form layout="inline">
															<Form.Item
																label="Priority"
															>
																<InputNumber
																	min={-1}
																	max={999}
																	value={task.priority}
																	onChange={this.onChangePriority}
																	readOnly={this.state.isReadOnlyPriority}
																	bordered={false}
																/>
															</Form.Item>
															<Button
																icon={<ControlOutlined />}
																onClick={this.onClickArguments}
																style={{ marginRight: '1rem' }}
															>
																Arguments
															</Button>
															<Popconfirm
																placement="topRight"
																title="Are you sure you want to delete this task?"
																onConfirm={this.onClickDelete}
																okText="Yes"
																cancelText="No"
															>
																<Button
																	type="danger"
																	icon={<DeleteOutlined />}
																	loading={this.state.isLoadingDelete}
																>
																	Delete
																</Button>
															</Popconfirm>
														</Form>
													}
												/>
											</Col>
											<Col span={24}>
												{task.stats.hasOwnProperty("progress") ? (
													<Progress type="line" percent={Math.trunc((task.stats["progress"][0] / task.stats["progress"][1])*100)} />
												) : (
													<Progress type="line" percent={0} />
												)}
											</Col>
											<Col span={24}>
												<Row gutter={[12, 10]}>
													<Col>
														<Button
															type="primary"
															icon={<PlayCircleOutlined />}
															onClick={this.onClickStart}
															loading={this.state.isLoadingStart}
														>
															Start
														</Button>
													</Col>
													<Col>
														<Button
															icon={<ReloadOutlined />}
															onClick={this.onClickRefresh}
															loading={this.state.isLoadingRefresh}
														>
															Refresh
														</Button>
													</Col>
													<Col>
														<Button
															icon={<PauseOutlined />}
															onClick={this.onClickPause}
															loading={this.state.isLoadingPause}
														>
															Pause
														</Button>
													</Col>
													<Col>
														<Button
															icon={<CaretRightOutlined />}
															onClick={this.onClickResume}
															loading={this.state.isLoadingResume}
														>
															Resume
														</Button>
													</Col>
													<Col>
														<Button
															icon={<EnvironmentOutlined />}
															onClick={this.onClickCheckpoint}
															loading={this.state.isLoadingCheckpoint}
														>
															Checkpoint
														</Button>
													</Col>
													<Col>
														<Button
															icon={<StepForwardOutlined />}
															onClick={this.onClickSkip}
															loading={this.state.isLoadingSkip}
														>
															Skip
														</Button>
													</Col>
													<Col>
														<Popconfirm
															placement="topRight"
															title="Are you sure you want to quit this task?"
															onConfirm={this.onClickQuit}
															okText="Yes"
															cancelText="No"
														>
															<Button
																type="danger"
																icon={<CloseOutlined />}
																loading={this.state.isLoadingQuit}
															>
																Quit
															</Button>
														</Popconfirm>
													</Col>
												</Row>
											</Col>
										</Row>
									</Col>
									<Col flex="1 1 auto">
										<Row gutter={[16, 14]} className="height-100">
											<Col className="max-height-100" span={16}>
												<Descriptions
													column={2}
													layout="horizontal"
													bordered
												>
													{task.stats.hasOwnProperty("status") && (
														<Descriptions.Item label="Status" span={2}>
															{HASHCAT_STATUS_BADGE_WARNING.indexOf(task.stats["status"]) > -1 ? (
																<Badge status="warning" text={HASHCAT_STATUS_MESSAGES[task.stats["status"]]} />
															) : HASHCAT_STATUS_BADGE_PROCESSING.indexOf(task.stats["status"]) > -1 ? (
																<Badge status="processing" text={HASHCAT_STATUS_MESSAGES[task.stats["status"]]} />
															) : HASHCAT_STATUS_BADGE_ERROR.indexOf(task.stats["status"]) > -1 ? (
																<Badge status="error" text={HASHCAT_STATUS_MESSAGES[task.stats["status"]]} />
															) : HASHCAT_STATUS_BADGE_SUCCESS.indexOf(task.stats["status"]) > -1 ? (
																<Badge status="success" text={HASHCAT_STATUS_MESSAGES[task.stats["status"]]} />
															) : HASHCAT_STATUS_BADGE_PINK.indexOf(task.stats["status"]) > -1 ? (
																<Badge color="pink" text={HASHCAT_STATUS_MESSAGES[task.stats["status"]]} />
															) : HASHCAT_STATUS_BADGE_YELLOW.indexOf(task.stats["status"]) > -1 ? (
																<Badge color="yellow" text={HASHCAT_STATUS_MESSAGES[task.stats["status"]]} />
															) : (
																<Badge status="default" text={HASHCAT_STATUS_MESSAGES[task.stats["status"]]} />
															)}
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("target") && (
														<Descriptions.Item label="Target" span={2}>
															{task.stats["target"]}
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("progress") && (
														<Descriptions.Item label="Progress" span={2}>
															{task.stats["progress"][0] + " / " + task.stats["progress"][1] + " (" + Math.trunc((task.stats["progress"][0] / task.stats["progress"][1])*100) + "%)"}
															{task.stats.hasOwnProperty("guess") && (
																<Tooltip title={
																	<Descriptions bordered size="small" column={1} layout="horizontal">
																		{task.stats.guess.guess_base !== null ? (
																			<Descriptions.Item label="Guess Base">{task.stats.guess.guess_base} ({task.stats.guess.guess_base_offset}/{task.stats.guess.guess_base_count})</Descriptions.Item>
																		) : (
																			<Descriptions.Item label="Guess Base">-</Descriptions.Item>
																		)}
																		{task.stats.guess.guess_mod !== null ? (
																			<Descriptions.Item label="Guess Mod">{task.stats.guess.guess_mod} ({task.stats.guess.guess_mod_offset}/{task.stats.guess.guess_mod_count})</Descriptions.Item>
																		) : (
																			<Descriptions.Item label="Guess Mod">-</Descriptions.Item>
																		)}
																	</Descriptions>
																}>
																	<InfoCircleOutlined style={{ marginLeft: ".5rem" }} />
																</Tooltip>
															)}
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("rejected") && (
														<Descriptions.Item label="Rejected" span={1}>
															{task.stats["rejected"]}
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("restore_point") && (
														<Descriptions.Item label="Restore point" span={1}>
															{task.stats["restore_point"]}
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("recovered_hashes") && (
														<Descriptions.Item label="Recovered hashes" span={1}>
															{task.stats["recovered_hashes"][0] + " / " + task.stats["recovered_hashes"][1] + " (" + Math.trunc((task.stats["recovered_hashes"][0] / task.stats["recovered_hashes"][1])*100) + "%)"}
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("recovered_salts") && (
														<Descriptions.Item label="Recovered salts" span={1}>
															{task.stats["recovered_salts"][0] + " / " + task.stats["recovered_salts"][1] + " (" + Math.trunc((task.stats["recovered_salts"][0] / task.stats["recovered_salts"][1])*100) + "%)"}
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("devices") && (
														<Descriptions.Item label="Speed" span={2}>
															{humanizeSpeed(totalSpeed(task.stats["devices"]))}
															<Tooltip title={
																<Table
																	columns={[
																		{
																			title: 'ID',
																			dataIndex: 'id',
																			key: 'ID'
																		},
																		{
																			title: 'Speed',
																			dataIndex: 'speed',
																			key: 'Speed'
																		},
																		{
																			title: 'Temp',
																			dataIndex: 'temp',
																			key: 'Temp'
																		},
																		{
																			title: 'Util',
																			dataIndex: 'util',
																			key: 'Util'
																		}
																	]}
																	dataSource={task.stats["devices"].map(device =>
																		({
																			key: device.device_id,
																			id: device.device_id,
																			speed: humanizeSpeed(device.speed),
																			temp: device.hasOwnProperty("temp") ? device.temp + " °C": "-",
																			util: device.util + "%",
																		})
																	)}
																	size="small"
																	pagination={false}
																	style={{ overflow: 'auto' }}
																/>
															}>
																<InfoCircleOutlined style={{ marginLeft: ".5rem" }} />
															</Tooltip>
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("time_start") && (
														<Descriptions.Item label="Started" span={1}>
															<Tooltip title={moment.unix(task.stats["time_start"]).format("MMMM Do YYYY, HH:mm")}>
																{moment.unix(task.stats["time_start"]).fromNow()}
															</Tooltip>
														</Descriptions.Item>
													)}
													{task.stats.hasOwnProperty("estimated_stop") && (
														<Descriptions.Item label="ETA" span={1}>
															<Tooltip title={moment.unix(task.stats["estimated_stop"]).format("MMMM Do YYYY, HH:mm")}>
																{moment.unix(task.stats["estimated_stop"]).fromNow()}
															</Tooltip>
														</Descriptions.Item>
													)}
												</Descriptions>
											</Col>
											<Col className="max-height-100" span={8}>
												<div className="height-100" style={{ display: "flex", flexDirection: "column" }}>
												<span><CodeOutlined /> Terminal</span>
												<pre style={{
													flex: 'auto',
													overflow: 'auto',
													padding: '.5rem',
													margin: '0',
													border: '1px solid #303030'
												}}>
													{task.journal.map(j => j.message + "\n")}
												</pre>
												</div>
											</Col>
										</Row>
									</Col>
								</Row>
							) : (
								"No selected task."
							)}
						</Col>
					</Row>
				</Content>
			</>
		)
	}
Example #16
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 #17
Source File: PlotContainer.jsx    From ui with MIT License 4 votes vote down vote up
PlotContainer = (props) => {
  const {
    experimentId,
    plotUuid, plotType, plotInfo,
    plotStylingConfig, defaultActiveKey,
    extraToolbarControls, extraControlPanels,
    showReset,
    children,
  } = props;

  const dispatch = useDispatch();

  const [resetDisabled, setResetDisabled] = useState(true);
  const [tileDirection, setTileDirection] = useState(DEFAULT_ORIENTATION);
  const { config } = useSelector((state) => state.componentConfig[plotUuid] || {});
  const debounceSave = useCallback(
    _.debounce(() => dispatch(savePlotConfig(experimentId, plotUuid)), 2000), [],
  );

  const updatePlotWithChanges = (obj) => {
    dispatch(updatePlotConfig(plotUuid, obj));
  };

  const isConfigEqual = (currentConfig, initialConfig) => {
    const isEqual = Object.keys(initialConfig).every((key) => {
      // By pass plot data because we want to compare settings not data
      if (key === 'plotData') return true;
      if (initialConfig.keepValuesOnReset?.includes(key)) return true;
      if (typeof currentConfig[key] === 'object') {
        return JSON.stringify(currentConfig[key]) === JSON.stringify(initialConfig[key]);
      }

      return currentConfig[key] === initialConfig[key];
    });

    return isEqual;
  };

  const handleResize = () => {
    const direction = window.innerWidth > 1024 ? 'row' : 'column';
    if (tileDirection !== direction) setTileDirection(direction);
  };

  useEffect(() => {
    window.addEventListener('resize', handleResize);
  }, []);

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

    if (isConfigEqual(config, initialPlotConfigStates[plotType])) {
      setResetDisabled(true);
      return;
    }
    setResetDisabled(false);
  }, [config]);

  const onClickReset = () => {
    dispatch(resetPlotConfig(experimentId, plotUuid, plotType));
    setResetDisabled(true);
  };

  if (!config) {
    return <Skeleton active paragraph={{ rows: 1 }} title={{ width: 500 }} />;
  }

  const renderPlotToolbarControls = () => (
    <Space style={{ marginRight: '0.5em' }}>
      {extraToolbarControls}
      {showReset ? (
        <Button
          key='reset'
          type='primary'
          size='small'
          onClick={onClickReset}
          disabled={resetDisabled}
        >
          Reset
        </Button>
      ) : ''}
      {plotInfo ? (
        <Tooltip title={plotInfo}>
          <Button size='small' icon={<InfoCircleOutlined />} />
        </Tooltip>
      ) : ''}
    </Space>
  );

  const TILE_MAP = {
    [PLOT]: {
      toolbarControls: renderPlotToolbarControls(),
      component: () => children,
      style: {
        display: 'flex',
        backgroundColor: 'white',
        justifyContent: 'center',
        alignContent: 'center',
        height: '100%',
      },
    },
    [CONTROLS]: {
      toolbarControls: [],
      component: (width, height) => (
        <div style={{ height, overflowY: 'auto' }}>
          <PlotStyling
            formConfig={plotStylingConfig}
            config={config}
            onUpdate={updatePlotWithChanges}
            extraPanels={extraControlPanels}
            defaultActiveKey={defaultActiveKey}
          />
        </div>
      ),
      style: { margin: '-10px' },
    },
  };

  const windows = {
    direction: tileDirection,
    first: PLOT,
    second: CONTROLS,
    splitPercentage: 75,
  };

  return (
    <MultiTileContainer
      style={{ backgroundColor: 'white' }}
      tileMap={TILE_MAP}
      initialArrangement={windows}
    />
  );
}
Example #18
Source File: DiffExprCompute.jsx    From ui with MIT License 4 votes vote down vote up
DiffExprCompute = (props) => {
  const {
    experimentId, onCompute,
  } = props;

  const dispatch = useDispatch();
  const { properties, hierarchy } = useSelector(getCellSets());
  const [isFormValid, setIsFormValid] = useState(false);
  const [numSamples, setNumSamples] = useState(0);
  const comparisonGroup = useSelector((state) => state.differentialExpression.comparison.group);
  const selectedComparison = useSelector((state) => state.differentialExpression.comparison.type);
  const { basis, cellSet, compareWith } = comparisonGroup?.[selectedComparison] || {};

  /**
   * Loads cell set on initial render if it does not already exist in the store.
   */
  useEffect(() => {
    dispatch(loadCellSets(experimentId));
  }, []);

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

    const samples = hierarchy?.find(
      (rootNode) => (rootNode.key === 'sample'),
    )?.children;

    setNumSamples(samples.length);

    // Auto select the only sample if there is only one sample
    if (samples.length === 1) {
      const theOnlySampleOption = {
        ...comparisonGroup[ComparisonType.WITHIN],
        type: ComparisonType.WITHIN,
        basis: `sample/${samples[0].key}`
      }
      dispatch(setComparisonGroup(theOnlySampleOption));
    }

  }, [Object.keys(properties).length]);

  // Evaluate if the selected comparisons can be run. Returns results
  // that can be used to display appropriate warnings and errors if it cannot be run.
  const canRunDiffExpr = useCallback(() => {
    return checkCanRunDiffExpr(
      properties,
      hierarchy,
      comparisonGroup,
      selectedComparison
    )
  }, [basis, cellSet, compareWith, numSamples]);

  const validateForm = () => {
    if (!cellSet || !compareWith || !basis) {
      setIsFormValid(false);
      return;
    }

    setIsFormValid(true);
  };

  // Validate form when the groups selected changes.
  useEffect(() => {
    validateForm();
  }, [comparisonGroup[selectedComparison]]);

  /**
   * Updates the selected clusters.
   * @param {string} cellSet The key of the cell set.
   * @param {string} option The option string (`cellSet` or `compareWith`).
   */
  const onSelectCluster = (cellSet, option) => {
    dispatch(setComparisonGroup({
      ...comparisonGroup[selectedComparison],
      type: selectedComparison,
      [option]:
        cellSet,
    }));
  };

  /**
   * Constructs a form item, a `Select` field with selectable clusters.
   */
  const renderClusterSelectorItem = ({
    title, option, filterType,
  }) => {
    // Depending on the cell set type specified, set the default name
    const placeholder = filterType === 'metadataCategorical' ? 'sample/group' : 'cell set';

    const tree = composeTree(hierarchy, properties, filterType);

    const renderChildren = (rootKey, children) => {
      if (!children || children.length === 0) { return (<></>); }

      // If this is the `compareWith` option, we need to add `the rest` under the group previously selected.
      if (option === 'compareWith' && comparisonGroup[selectedComparison]?.cellSet?.startsWith(`${rootKey}/`)) {
        children.unshift({ key: `rest`, name: `Rest of ${properties[rootKey].name}` });
      }

      const shouldDisable = (rootKey, key) => {
        // Should always disable something already selected.
        const isAlreadySelected = Object.values(comparisonGroup[selectedComparison]).includes(`${rootKey}/${key}`);

        // or a cell set that is not in the same group as selected previously in `cellSet`
        const parentGroup = getCellSetClassKey(comparisonGroup[selectedComparison]?.cellSet);
        const isNotInTheSameGroup = rootKey !== parentGroup;

        return isAlreadySelected || (option === 'compareWith' && isNotInTheSameGroup);
      }

      if (comparisonGroup[selectedComparison]) {
        return children.map(({ key, name }) => {
          const uniqueKey = `${rootKey}/${key}`;

          return <Option key={uniqueKey} disabled={shouldDisable(rootKey, key)}>
            {name}
          </Option>
        });
      }
    };

    return (
      <Form.Item label={title}>
        <Select
          placeholder={`Select a ${placeholder}...`}
          style={{ width: 200 }}
          onChange={(cellSet) => onSelectCluster(cellSet, option)}
          value={comparisonGroup[selectedComparison][option] ?? null}
          size='small'
          aria-label={title}
        >
          {
            option === 'basis' &&
            <Option key='all'>
              All
            </Option>
          }
          {
            option === 'compareWith' &&
            <Option key='background'>
              All other cells
            </Option>
          }
          {
            tree && tree.map(({ key, children }) => (
              <OptGroup label={properties[key]?.name} key={key}>
                {renderChildren(key, [...children])}
              </OptGroup>
            ))
          }
        </Select>
      </Form.Item >
    );
  };

  return (
    <Form size='small' layout='vertical'>
      <Radio.Group
        onChange={(e) => {
          dispatch(setComparisonType(e.target.value));
        }} defaultValue={selectedComparison}>
        <Radio
          value={ComparisonType.WITHIN}>
          <Space>
            Compare cell sets within a sample/group
            <Tooltip overlay={(
              <span>
                For finding marker genes that distinguish one cluster from another. The calculation uses the presto implementation of the Wilcoxon rank sum test and auROC analysis. For more information see the
                {' '}
                <a
                  href='http://htmlpreview.github.io/?https://github.com/immunogenomics/presto/blob/master/docs/getting-started.html'
                  target='_blank'
                  rel='noreferrer'
                >
                  presto vignette
                </a>.
              </span>
            )}
            >
              <InfoCircleOutlined />
            </Tooltip>
          </Space>
        </Radio>
        <Radio
          value={ComparisonType.BETWEEN}
          disabled={numSamples === 1}
        >
          <Space>
            {
              numSamples === 1 ? (
                <Tooltip
                  overlay={(<span>Comparison between samples/groups is not possible with a dataset that contains only 1 sample</span>)}
                >
                  Compare a selected cell set between samples/groups
                </Tooltip>
              ) : (
                'Compare a selected cell set between samples/groups'
              )
            }
            <Tooltip overlay={(
              <span>
                For finding genes that are differentially expressed between two experimental groups. This analysis uses a
                {' '}
                <a
                  href='http://bioconductor.org/books/3.14/OSCA.workflows/segerstolpe-human-pancreas-smart-seq2.html#segerstolpe-comparison'
                  target='_blank'
                  rel='noreferrer'
                >
                  pseudobulk limma-voom workflow
                </a>.
              </span>
            )}
            >
              <InfoCircleOutlined />
            </Tooltip>
          </Space>
        </Radio>
      </Radio.Group>

      {selectedComparison === ComparisonType.WITHIN
        ? (
          <>
            {renderClusterSelectorItem({
              title: 'Compare cell set:',
              option: 'cellSet',
              filterType: 'cellSets',
            })}

            {renderClusterSelectorItem({
              title: 'and cell set:',
              option: 'compareWith',
              filterType: 'cellSets',
            })}

            {renderClusterSelectorItem({
              title: 'within sample/group:',
              option: 'basis',
              filterType: 'metadataCategorical',
            })}
          </>
        ) : (
          <>
            {renderClusterSelectorItem({
              title: 'Compare cell set:',
              option: 'basis',
              filterType: 'cellSets',
            })}

            {renderClusterSelectorItem({
              title: 'between sample/group:',
              option: 'cellSet',
              filterType: 'metadataCategorical',
            })}

            {renderClusterSelectorItem({
              title: 'and sample/group:',
              option: 'compareWith',
              filterType: 'metadataCategorical',
            })}
          </>
        )}
      <Space direction='vertical'>
        {
          isFormValid && canRunDiffExpr() === canRunDiffExprResults.INSUFFCIENT_CELLS_ERROR ?
            <Alert
              message="Error"
              description={
                <>
                  One or more of the selected samples/groups does not contain enough cells in the selected cell set.
                  Therefore, the analysis can not be run. Select other cell set(s) or samples/groups to compare.
                </>
              }
              type="error"
              showIcon
            /> :
            isFormValid && canRunDiffExpr() === canRunDiffExprResults.INSUFFICIENT_CELLS_WARNING ?
              <Alert
                message="Warning"
                description={
                  <>
                    For the selected comparison, there are fewer than 3 samples with the minimum number of cells (10).
                    Only logFC values will be calculated and results should be used for exploratory purposes only.
                  </>
                }
                type="warning"
                showIcon
              />
              :
              <></>
        }
        <Space direction='horizontal'>
          <Button
            size='small'
            disabled={!isFormValid ||
              [
                canRunDiffExprResults.FALSE,
                canRunDiffExprResults.INSUFFCIENT_CELLS_ERROR
              ].includes(canRunDiffExpr())
            }
            onClick={() => onCompute()}
          >
            Compute
          </Button>
        </Space>
      </Space>
    </Form>
  );
}
Example #19
Source File: ParticipantDetail.js    From react-portal with MIT License 4 votes vote down vote up
ParticipantsDetails = props => {
	const [info, setInfo] = useState(null);
	const [eventsData, setEventsData] = useState([]);
	const [isLoading, setIsLoading] = useState(false);

	useEffect(() => {
		(async () => {
			setIsLoading(true);
			try {
				const params = { pid: props.participantId };
				const { data } = await getParticipantsDetailService(params);

				setInfo(data.profileData);
				setEventsData(attendanceCalc(data.events));
				setIsLoading(false);
			} catch (err) {
				_notification("warning", "Error", err.message);
			}
		})();
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, []);

	const attendanceCalc = events => {
		if (events) {
			events.forEach(event => {
				let start = new Date(event.details.startDate);
				let end = new Date(event.details.endDate);
				let data = [];
				let dayAttend = [];
				dayAttend = event.attendance.daysAttended.map(d => {
					return d.split("T")[0];
				});

				let status;
				for (let d = start; d <= end; d.setDate(d.getDate() + 1)) {
					if (
						dayAttend.includes(
							moment(new Date(d)).format("YYYY-MM-DD")
						)
					) {
						status = "Present";
					} else if (
						!dayAttend.includes(
							moment(new Date(d)).format("YYYY-MM-DD")
						) &&
						moment(new Date(d)).format("YYYY-MM-DD") <
							moment(Date.now()).format("YYYY-MM-DD")
					) {
						status = "Absent";
					} else if (
						!dayAttend.includes(
							moment(new Date(d)).format("YYYY-MM-DD")
						)
					) {
						status = "Pending";
					}
					data.push({
						status,
						date: moment(new Date(d)).format("YYYY-MM-DD")
					});
				}
				event.attendance.dayWiseAttendance = data;
			});
			return events;
		}
	};

	return (
		<>
			<Skeleton avatar loading={isLoading} active>
				{info ? (
					<Card loading={isLoading}>
						<Card.Meta
							avatar={
								<Avatar src="https://avatars.dicebear.com/v2/identicon/12324.svg" />
							}
							title={`${info.name} (${info.email})`}
							description={
								<>
									<PhoneOutlined /> {info.phone}{" "}
									<InfoCircleOutlined /> {info.branch},{" "}
									{info.year}
								</>
							}
						/>
					</Card>
				) : null}
				<br />
				<br />
				<h3>Events Information</h3>
				<br />
				<Timeline>
					{eventsData.length !== 0 ? (
						eventsData.map((event, id) => (
							<Timeline.Item
								key={id}
								color={
									event.status === "not attended"
										? "red"
										: "green"
								}
							>
								<p>
									<span style={{ fontWeight: "700" }}>
										{event.details.title}
									</span>{" "}
									<Tag>{event.status.toUpperCase()}</Tag>
									<Tag
										color={
											event.isRsvpAccepted
												? "green"
												: "red"
										}
									>
										{event.isRsvpAccepted
											? "RSVP: Accepted"
											: "RSVP: Not Accepted"}
									</Tag>
								</p>
								<p>{event.details.description}</p>
								<p>
									{new Date(
										event.details.startDate
									).toDateString()}{" "}
									to{" "}
									{new Date(
										event.details.endDate
									).toDateString()}{" "}
									({event.details.venue})
								</p>
								<p style={{ fontWeight: "600" }}>Attendance</p>
								<div style={{ display: "flex" }}>
									{event.attendance.dayWiseAttendance &&
										event.attendance.dayWiseAttendance.map(
											(attendance, id) => {
												return (
													<Tag
														key={id}
														color={
															attendance.status ===
															"Pending"
																? "#108ee9"
																: attendance.status ===
																  "Present"
																? "#87d068"
																: "#f50"
														}
													>
														{moment(
															attendance.date
														).format("DD/MM/YYYY")}
														- {attendance.status}
													</Tag>
												);
											}
										)}
								</div>
							</Timeline.Item>
						))
					) : (
						<div>Not regeistered in any Event</div>
					)}
				</Timeline>
			</Skeleton>
		</>
	);
}
Example #20
Source File: index.jsx    From react-sendbird-messenger with GNU General Public License v3.0 4 votes vote down vote up
export function Header({ detailVisible = false, toggleShowDetail = () => {} }) {
    const {
        channel,
        setShowVideoCall,
        directCall,
        setDirectCall,
        setMediaAccess,
    } = useDashboard()
    const {
        requireMediaAccess,
        dial,
        accept,
        onRinging,
        onAudioInputDeviceChanged,
        onAudioOutputDeviceChanged,
        onVideoInputDeviceChanged,
        dispose,
    } = useSendBird()

    const [showIncomingCall, setShowIncomingCall] = useState(false)

    const listenOnRinging = async () => {
        const { call } = await onRinging()
        console.log(call.caller.nickname, call.caller.userId)

        const mediaAccess = await requireMediaAccess()
        setMediaAccess(mediaAccess)

        setDirectCall(call)
        setShowIncomingCall(true)

        call.onEstablished = (call) => {
            // ...
            console.log('onEstablished', call)
        }

        call.onConnected = (call) => {
            // ...
            console.log('onConnected', call)
        }

        call.onEnded = (call) => {
            // ...
            console.log('onEnded')
            call.end()
            dispose(mediaAccess)
            setDirectCall(null)
            setShowVideoCall(false)
        }

        call.onRemoteAudioSettingsChanged = (call) => {
            // ...
            console.log('onRemoteAudioSettingsChanged', call)
            if (call.isRemoteAudioEnabled) {
                console.log('isRemoteAudioEnabled', call)
                // The remote user has been unmuted.
                // TODO: Display an unmuted icon.
            } else {
                console.log('isLocalAudioEnabled', call)

                // The remote user has been muted.
                // TODO: Display and toggles a muted icon.
            }
        }

        call.onRemoteVideoSettingsChanged = (call) => {
            // ...
            console.log('onRemoteVideoSettingsChanged', call)
        }
    }

    const listenOnAudioInputDeviceChanged = async () => {
        const { call } = await onAudioInputDeviceChanged()
        console.log(call)
    }

    const listenOnAudioOutputDeviceChanged = async () => {
        const { call } = await onAudioOutputDeviceChanged()
        console.log(call)
    }

    const listenOnVideoInputDeviceChanged = async () => {
        const { call } = await onVideoInputDeviceChanged()
        console.log(call)
    }

    useLayoutEffect(() => {
        listenOnRinging()
        listenOnAudioInputDeviceChanged()
        listenOnAudioOutputDeviceChanged()
        listenOnVideoInputDeviceChanged()
    })

    const handleAudioCall = () => {
        console.log('handleAudioCall')
    }

    const handleVideoCall = () => {
        setShowVideoCall(true)
        setShowIncomingCall(false)

        setTimeout(async () => {
            const mediaAccess = await requireMediaAccess()
            // console.log(mediaAccess)

            const callee = channel.members.find(
                (element) => element.userId !== localStorage.getItem('userId')
            ).userId
            const call = await dial(callee)
            // console.log(call)
            setMediaAccess(mediaAccess)
            setDirectCall(call)
        }, 500)
    }

    const handleOk = () => {
        // console.log(directCall)

        setShowVideoCall(true)
        setShowIncomingCall(false)

        setTimeout(async () => {
            accept(directCall)
        }, 500)
    }

    const handleCancel = () => {
        directCall.end()
        setDirectCall(null)
        setShowIncomingCall(false)
    }

    const formatChannel = channelDto(channel)

    const url = formatChannel.url
    const shortName = capitalizeFirstLetter(
        firstCharacterOfEachString(formatChannel.name)
    )
    const name = formatChannel.name

    return (
        <Fragment>
            <Row
                style={{
                    height: 60,
                    display: 'flex',
                    justifyContent: 'space-between',
                    alignItems: 'center',
                    padding: '0 12px',
                    borderBottom: `1px solid ${THIRD_COLOR}`,
                }}
            >
                <Col
                    style={{
                        display: 'flex',
                        alignItems: 'center',
                    }}
                >
                    <Avatar
                        style={{
                            color: PRIMARY_COLOR,
                            backgroundColor: SECONDARY_COLOR,
                            marginRight: 12,
                        }}
                        src={url}
                    >
                        {shortName}
                    </Avatar>
                    <Title style={{ margin: 0 }} level={4}>
                        {name}
                    </Title>
                </Col>
                <Col style={{ display: 'flex' }}>
                    <ScaleIn>
                        <Button
                            style={{ border: 0 }}
                            type="ghost"
                            icon={
                                <PhoneOutlined
                                    style={{ color: PRIMARY_COLOR }}
                                />
                            }
                            size="large"
                            onClick={handleAudioCall}
                        />
                    </ScaleIn>
                    <ScaleIn>
                        <Button
                            style={{ border: 0 }}
                            type="ghost"
                            icon={
                                <VideoCameraOutlined
                                    style={{ color: PRIMARY_COLOR }}
                                />
                            }
                            size="large"
                            onClick={handleVideoCall}
                        />
                    </ScaleIn>
                    <ScaleIn>
                        <Button
                            style={{ border: 0 }}
                            type="ghost"
                            icon={
                                <InfoCircleOutlined
                                    style={{
                                        color: detailVisible && PRIMARY_COLOR,
                                    }}
                                />
                            }
                            size="large"
                            onClick={toggleShowDetail}
                        />
                    </ScaleIn>
                </Col>
            </Row>

            <IncomingCallModal
                caller={directCall?.caller}
                visible={showIncomingCall}
                onOk={handleOk}
                onCancel={handleCancel}
            />
        </Fragment>
    )
}
Example #21
Source File: index.jsx    From react-sendbird-messenger with GNU General Public License v3.0 4 votes vote down vote up
export function Header({
    visible = false,
    onCancel = () => {},
    showDetail = () => {},
    handleAudioCall = () => {},
    handleVideoCall = () => {},
}) {
    const { channel } = useDashboard()

    const formatChannel = channelDto(channel)

    const name = formatChannel.name

    return (
        <Row
            style={{
                height: 60,
                display: 'flex',
                justifyContent: 'space-between',
                alignItems: 'center',
                padding: '0 12px',
            }}
        >
            <Col
                style={{
                    display: 'flex',
                    justifyContent: 'flex-start',
                }}
                span={3}
            >
                <Button
                    style={{ border: 0 }}
                    type="ghost"
                    icon={<LeftOutlined style={{ color: PRIMARY_COLOR }} />}
                    size="large"
                    onClick={onCancel}
                />
            </Col>
            <Col
                style={{
                    display: 'flex',
                    justifyContent: 'flex-start',
                }}
                span={12}
            >
                {name}
            </Col>
            <Col
                style={{
                    display: 'flex',
                    justifyContent: 'flex-end',
                }}
                span={9}
            >
                <Button
                    style={{ border: 0 }}
                    type="ghost"
                    icon={<PhoneOutlined style={{ color: PRIMARY_COLOR }} />}
                    size="large"
                    onClick={handleAudioCall}
                />
                <Button
                    style={{ border: 0 }}
                    type="ghost"
                    icon={
                        <VideoCameraOutlined style={{ color: PRIMARY_COLOR }} />
                    }
                    size="large"
                    onClick={handleVideoCall}
                />
                <Button
                    style={{ border: 0 }}
                    type="ghost"
                    icon={
                        <InfoCircleOutlined
                            style={{
                                color: visible && PRIMARY_COLOR,
                            }}
                        />
                    }
                    size="large"
                    onClick={showDetail}
                />
            </Col>
        </Row>
    )
}
Example #22
Source File: index.jsx    From react-sendbird-messenger with GNU General Public License v3.0 4 votes vote down vote up
export function Header({ detailVisible = false, toggleShowDetail = () => {} }) {
    const { channel, setShowVideoCall } = useDashboard()

    const [showIncomingCall, setShowIncomingCall] = useState(false)

    const handleAudioCall = () => {
        setShowIncomingCall((prevState) => !prevState)
    }

    const handleVideoCall = () => {
        setShowIncomingCall((prevState) => !prevState)
    }

    const handleOk = () => {
        setShowVideoCall(true)
        setShowIncomingCall(false)
    }

    const handleCancel = () => {
        setShowIncomingCall(false)
    }

    const url = channel.url
    const shortName = capitalizeFirstLetter(
        firstCharacterOfEachString(channel.name)
    )
    const name = channel.name

    return (
        <Fragment>
            <Row
                style={{
                    height: 60,
                    display: 'flex',
                    justifyContent: 'space-between',
                    alignItems: 'center',
                    padding: '0 12px',
                    borderBottom: `1px solid ${THIRD_COLOR}`,
                }}
            >
                <Col
                    style={{
                        display: 'flex',
                        alignItems: 'center',
                    }}
                >
                    <Avatar
                        style={{
                            color: PRIMARY_COLOR,
                            backgroundColor: SECONDARY_COLOR,
                            marginRight: 12,
                        }}
                        src={url}
                    >
                        {shortName}
                    </Avatar>
                    <Title style={{ margin: 0 }} level={4}>
                        {name}
                    </Title>
                </Col>
                <Col>
                    <Button
                        style={{ border: 0 }}
                        type="ghost"
                        icon={
                            <PhoneOutlined style={{ color: PRIMARY_COLOR }} />
                        }
                        size="large"
                        onClick={handleAudioCall}
                    />
                    <Button
                        style={{ border: 0 }}
                        type="ghost"
                        icon={
                            <VideoCameraOutlined
                                style={{ color: PRIMARY_COLOR }}
                            />
                        }
                        size="large"
                        onClick={handleVideoCall}
                    />
                    <Button
                        style={{ border: 0 }}
                        type="ghost"
                        icon={
                            <InfoCircleOutlined
                                style={{
                                    color: detailVisible && PRIMARY_COLOR,
                                }}
                            />
                        }
                        size="large"
                        onClick={toggleShowDetail}
                    />
                </Col>
            </Row>

            <IncomingCallModal
                visible={showIncomingCall}
                onOk={handleOk}
                onCancel={handleCancel}
            />
        </Fragment>
    )
}
Example #23
Source File: index.jsx    From react-sendbird-messenger with GNU General Public License v3.0 4 votes vote down vote up
export function Header({
    visible = false,
    onCancel = () => {},
    showDetail = () => {},
    showIncomingCall = () => {},
}) {
    const { channel } = useDashboard()

    const name = channel?.name

    return (
        <Row
            style={{
                height: 60,
                display: 'flex',
                justifyContent: 'space-between',
                alignItems: 'center',
                padding: '0 12px',
            }}
        >
            <Col
                style={{
                    display: 'flex',
                    justifyContent: 'flex-start',
                }}
                span={3}
            >
                <Button
                    style={{ border: 0 }}
                    type="ghost"
                    icon={<LeftOutlined style={{ color: PRIMARY_COLOR }} />}
                    size="large"
                    onClick={onCancel}
                />
            </Col>
            <Col
                style={{
                    display: 'flex',
                    justifyContent: 'flex-start',
                }}
                span={12}
            >
                {name}
            </Col>
            <Col
                style={{
                    display: 'flex',
                    justifyContent: 'flex-end',
                }}
                span={9}
            >
                <Button
                    style={{ border: 0 }}
                    type="ghost"
                    icon={<PhoneOutlined style={{ color: PRIMARY_COLOR }} />}
                    size="large"
                    onClick={showIncomingCall}
                />
                <Button
                    style={{ border: 0 }}
                    type="ghost"
                    icon={
                        <VideoCameraOutlined style={{ color: PRIMARY_COLOR }} />
                    }
                    size="large"
                    onClick={showIncomingCall}
                />
                <Button
                    style={{ border: 0 }}
                    type="ghost"
                    icon={
                        <InfoCircleOutlined
                            style={{
                                color: visible && PRIMARY_COLOR,
                            }}
                        />
                    }
                    size="large"
                    onClick={showDetail}
                />
            </Col>
        </Row>
    )
}