@ant-design/icons#WarningOutlined JavaScript Examples

The following examples show how to use @ant-design/icons#WarningOutlined. 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: fileListItem.js    From virtuoso-design-system with MIT License 5 votes vote down vote up
FileListItem = ({
  name,
  extension,
  size,
  tooltipText,
  warning,
  button,
  decryptedExt,
  tabIndex,
  className,
}) => {
  const tooltip = (
    <>
      <div className={styles.tooltipTitle}>
        {warning && <WarningOutlined className={styles.warnIcon} />}

        <span className={styles.fileNameWrap}>
          <span className={styles.fileName}>{name}</span>
          <span className={styles.fileExtension}>{extension}</span>
        </span>
      </div>
      <Text className={styles.tooltipText}>{tooltipText}</Text>
    </>
  );

  return (
    /* eslint-disable jsx-a11y/no-noninteractive-tabindex */
    // eslint-disable-next-line jsx-a11y/no-static-element-interactions
    <div
      className={cn(styles.item, className)}
      data-testid="item-wrapper"
      aria-label={`${name}${extension}`}
      tabIndex={tabIndex}
    >
      <div
        className={cn(styles.inner, {
          [styles.warning]: warning,
          [styles.noButton]: !button,
        })}
      >
        <div className={styles.icon}>
          {warning ? (
            <WarningOutlined className={styles.warnIcon} />
          ) : (
            <IconTypeFile name={decryptedExt.toUpperCase()} />
          )}
        </div>
        <div className={styles.fileInfo}>
          <div className={`${styles.fileInfoName} ${styles.fileNameWrap}`}>
            <span className={styles.fileName}>{name}</span>
            <span className={styles.fileExtension}>{extension}</span>
          </div>
          <div className={styles.fileInfoText}>{size}</div>
          <Tooltip placement="topRight" title={tooltip} color="white">
            <div className={styles.hoverElement}>{button}</div>
          </Tooltip>
        </div>
      </div>
    </div>
    /* eslint-enable jsx-a11y/no-noninteractive-tabindex */
  );
}
Example #2
Source File: Teams.js    From ctf_platform with MIT License 4 votes vote down vote up
render() {
        return (
            <Layout className="layout-style">

                <Modal
                    title={<span>Create New Team <UsergroupAddOutlined /></span>}
                    visible={this.state.createTeamModal}
                    footer={null}
                    onCancel={() => { this.setState({ createTeamModal: false }) }}
                >
                    <CreateTeamForm setState={this.setState.bind(this)} obtainScore={this.props.obtainScore.bind(this)} loadTeamDetails={this.loadTeamDetails.bind(this)} setTeam={this.props.setTeam.bind(this)} />
                </Modal>

                {this.state.loading ? (
                    <div style={{ position: "absolute", left: "55%", transform: "translate(-55%, 0%)", zIndex: 10 }}>
                        <Ellipsis color="#177ddc" size={120} ></Ellipsis>
                    </div>
                ) : (
                    <div>
                        {this.props.team === "teams-disabled" ? (
                            <div style={{ display: "flex", placeContent: "center center", textAlign: "center", fontSize: "130%", width: "100%", height: "100%" }}>
                                <div>
                                    <TeamOutlined style={{ fontSize: "600%", color: "#177ddc" }} />
                                    <div>
                                        <h1>It seem's like teams are disabled.</h1>
                                        <p>If you believe this is an error, please contact the admins.</p>
                                    </div>
                                </div>
                            </div>
                        ) : (
                            <div>
                                {this.state.notFound ? (
                                    <div style={{ display: "flex", placeContent: "center center", textAlign: "center", fontSize: "130%", width: "100%", height: "100%" }}>
                                        <div>
                                            <TeamOutlined style={{ fontSize: "600%", color: "#177ddc" }} />
                                            <div>
                                                <h1>We were unable to find this team.</h1>
                                            </div>
                                        </div>
                                    </div>
                                ) : (
                                    <div>
                                        {this.state.teamName ?
                                            (
                                                <Layout style={{ height: "100%", width: "100%", padding: "3%", backgroundColor: "rgba(0, 0, 0, 0)" }}>
                                                    <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: "2ch" }}>
                                                        <div style={{ display: "flex" }}>
                                                            <div style={{ display: "flex", marginRight: "5ch", alignItems: "center", justifyItems: "center" }}>
                                                                <Avatar.Group
                                                                    maxCount={3}
                                                                >
                                                                    {this.state.members.map((member) => {
                                                                        return (
                                                                            <Avatar style={{ backgroundColor: "transparent", marginRight: "3ch", width: "10ch", height: "10ch" }} size='large' src={"/static/profile/" + member + ".webp"} />
                                                                        )
                                                                    })}

                                                                </ Avatar.Group>
                                                                <h1 style={{ fontSize: "5ch" }}>{this.state.teamName}</h1>
                                                            </div>
                                                            <div>
                                                                <h1 style={{ fontSize: "5ch", color: "#faad14" }}><span style={{ color: "#d48806", fontSize: "1.5ch" }}><u>Team Score:</u> </span>{this.state.teamScore}</h1>
                                                            </div>
                                                        </div>
                                                    </div>

                                                    {this.state.teamName === this.props.team && (
                                                        <div style={{ backgroundColor: "rgba(0, 0, 0, 0.3)", border: "5px solid transparent", borderRadius: "20px", width: "fit-content", padding: "20px" }}>
                                                            <h4 style={{ fontSize: "2ch", color: "#49aa19" }}>You are part of this team</h4>
                                                            <div style={{ marginTop: "2ch" }}>
                                                                <div style={{ display: "flex", marginBottom: "2ch" }}>
                                                                    <Input value={window.location.origin + "/Team/Join/" + this.state.code} />
                                                                    <Button type="primary" style={{ marginLeft: "1ch" }} icon={<LinkOutlined />} onClick={async () => {
                                                                        await navigator.clipboard.writeText(window.location.origin + "/Team/Join/" + this.state.code);
                                                                        message.success("Invite link copied to clipboard.")

                                                                    }}>Copy Invite Link</Button>
                                                                </div>
                                                                <Button style={{ marginRight: "1ch" }} danger type="primary" onClick={() => {
                                                                    confirm({
                                                                        title: "Leave Team?",
                                                                        content: <span>Are you sure you want to leave: <b><u>{this.state.teamName}</u></b>?</span>,
                                                                        icon: <WarningOutlined />,
                                                                        maskClosable: true,
                                                                        okText: "Leave Team",
                                                                        confirmLoading: this.state.joinLoading,
                                                                        onOk: (close) => { this.leaveTeam(close) },
                                                                        onCancel: () => { },
                                                                    });
                                                                }}>Leave Team</Button>
                                                            </div>
                                                        </div>
                                                    )}

                                                    <Divider />
                                                    <h1 style={{ fontSize: "3ch" }}>Individual Member's Scoring</h1>
                                                    <Table style={{ marginTop: "2vh" }} dataSource={this.state.userScores} pagination={{ pageSize: 10 }} locale={{
                                                        emptyText: (
                                                            <div style={{ display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", marginTop: "10vh" }}>
                                                                <FileUnknownTwoTone style={{ color: "#177ddc", fontSize: "400%", zIndex: 1 }} />
                                                                <h1 style={{ fontSize: "200%" }}>{this.state.teamName} has not completed any challenges/bought any hints</h1>
                                                            </div>
                                                        )
                                                    }}>
                                                        <Column width={30} title="Username" dataIndex="username" key="username"
                                                            render={(text, row, index) => {
                                                                return <Link to={"/Profile/" + text}><a style={{ fontWeight: 700 }}>{text}</a></Link>;
                                                            }}
                                                        />
                                                        <Column width={30} title="Total Score" dataIndex="score" key="score" />
                                                    </Table>
                                                    <Divider />
                                                    <h1 style={{ fontSize: "3ch" }}>Team Score History</h1>
                                                    <div style={{ height: 375, width: "100%", backgroundColor: "rgba(0, 0, 0, 0.3)", border: "5px solid transparent", borderRadius: "20px", padding: "10px", margin: "10px" }}>
                                                        <ResponsiveContainer width="90%" height={350}>
                                                            <AreaChart height={350} data={this.state.graphData}
                                                                margin={{ top: 10, right: 15, left: 15, bottom: 15 }}>

                                                                <defs>
                                                                    <linearGradient id="color1" x1="0" y1="0" x2="0" y2="1">
                                                                        <stop offset="5%" stopColor="#791a1f" stopOpacity={0.3} />
                                                                        <stop offset="95%" stopColor="#f89f9a" stopOpacity={0.1} />
                                                                    </linearGradient>
                                                                </defs>
                                                                <XAxis dataKey="Time">
                                                                    <Label offset={-5} position="insideBottom" style={{ fill: 'rgba(207, 207, 207, 1)' }}>
                                                                        Time
                                                                    </Label>
                                                                </XAxis>
                                                                <YAxis >
                                                                    <Label offset={-10} position='insideLeft' style={{ fill: 'rgba(207, 207, 207, 1)' }}>
                                                                        Score
                                                                    </Label>
                                                                </YAxis>
                                                                <CartesianGrid strokeDasharray="3 3" />

                                                                <Tooltip labelStyle={{ backgroundColor: "#1c2b3e" }} contentStyle={{ backgroundColor: "#1c2b3e" }} wrapperStyle={{ backgroundColor: "#1c2b3e" }} />
                                                                <Area isAnimationActive={false} type="monotone" dataKey="Score" stroke="#d32029" fillOpacity={1} fill="url(#color1)" />
                                                            </AreaChart>
                                                        </ResponsiveContainer>

                                                    </div>
                                                    <Table style={{ marginTop: "2vh" }} dataSource={this.state.scores} pagination={{ pageSize: 10 }} locale={{
                                                        emptyText: (
                                                            <div style={{ display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", marginTop: "10vh" }}>
                                                                <FileUnknownTwoTone style={{ color: "#177ddc", fontSize: "400%", zIndex: 1 }} />
                                                                <h1 style={{ fontSize: "200%" }}>{this.state.teamName} has not completed any challenges/bought any hints</h1>
                                                            </div>
                                                        )
                                                    }}>
                                                        <Column width={30} title="Username" dataIndex="username" key="username"
                                                            render={(text, row, index) => {
                                                                return <Link to={"/Profile/" + text}><a style={{ fontWeight: 700 }}>{text}</a></Link>;
                                                            }}
                                                        />
                                                        <Column width={1} title="Challenge/Hint" dataIndex="challenge" key="challenge"
                                                            render={(text, row, index) => {
                                                                if (row.challengeID !== "") return <Link to={"/Challenges/" + row.challengeID}><a style={{ fontWeight: 700 }}>{text}</a></Link>;
                                                                else return (<span>{text}</span>);
                                                            }} />
                                                        <Column width={30} title="Score Change" dataIndex="score" key="score" />
                                                        <Column width={30} title="Solved Timestamp" dataIndex="time" key="time" />
                                                    </Table>
                                                </Layout>

                                            ) :
                                            (
                                                <div style={{ display: "flex", placeContent: "center center", textAlign: "center", fontSize: "130%", width: "100%", height: "100%" }}>
                                                    <div>
                                                        <TeamOutlined style={{ fontSize: "600%", color: "#177ddc" }} />
                                                        <div>
                                                            <h1>The world's a dangerous place</h1> <h2>Don't go alone, join/create a team today!</h2>
                                                        </div>
                                                        <Button icon={<UsergroupAddOutlined />} type="primary" size="large" onClick={() => { this.setState({ createTeamModal: true }) }}>Create a Team</Button>
                                                        <div style={{ marginTop: "3ch" }}>
                                                            <span>Got an <b>invite link <LinkOutlined />?</b></span>
                                                            <div>
                                                                <Button style={{ marginTop: "1ch" }} size="large" type="primary" icon={<LinkOutlined />} onClick={() => {
                                                                    navigator.clipboard.readText().then(text => {
                                                                        if (!(/^.*\/Team\/Join\/[0-9a-fA-F]{32}$/.test(text))) message.error("Invalid link. Please check that you have copied the link correctly.", 3)
                                                                        else {
                                                                            const code = text.split("/Team/Join/")
                                                                            this.getCodeDetails(code[1])
                                                                        }

                                                                    }).catch(err => {
                                                                        console.log(err)
                                                                        message.error("Failed to read link from your clipboard.", 5)
                                                                        message.info("Please ensure that you have allowed permissions for reading of clipboard text.", 5)
                                                                    })

                                                                }}>Paste &amp; Use Link</Button>
                                                            </div>
                                                        </div>
                                                    </div>
                                                </div>
                                            )
                                        }
                                    </div>
                                )}
                            </div>

                        )}

                    </div>
                )}

            </Layout>
        )
    }
Example #3
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 #4
Source File: MainWindow.js    From ikago-web with MIT License 4 votes vote down vote up
render() {
    return (
      <Layout>
        <Header className="header">
          <a className="header-a" href="https://github.com/zhxie/ikago">
            <img className="header-icon" src={logo} alt="icon" />
          </a>
          <p className="header-title">{this.state.name}</p>
          <p className="header-subtitle">{this.state.version}</p>
        </Header>
        <Content className="content">
          <Row gutter={16}>
            <Col className="content-col" xs={24} sm={12} md={12} lg={6} xl={4}>
              <Card className="content-card" hoverable>
                <Statistic
                  prefix={(() => {
                    if (this.state.active) {
                      return <CheckOutlined />;
                    } else if (this.state.inactive) {
                      return <WarningOutlined />;
                    } else {
                      return <LoadingOutlined />;
                    }
                  })()}
                  title="Status"
                  value={(() => {
                    if (this.state.active) {
                      return 'Active';
                    } else if (this.state.inactive) {
                      return 'Inactive';
                    } else {
                      return 'Connecting';
                    }
                  })()}
                  valueStyle={{
                    color: (() => {
                      if (!this.state.inactive) {
                        return '#000';
                      } else {
                        return '#cf1322';
                      }
                    })()
                  }}
                />
              </Card>
            </Col>
            <Col className="content-col" xs={24} sm={12} md={12} lg={6} xl={4}>
              <Card className="content-card" hoverable>
                <Statistic
                  precision={2}
                  prefix={<ClockCircleOutlined />}
                  title="Operation Time"
                  value={this.convertTime(this.state.time)}
                />
              </Card>
            </Col>
            <Col className="content-col" xs={24} sm={12} md={12} lg={6} xl={4}>
              <Card
                hoverable
                onClick={() => {
                  this.setState({
                    showTotal: !this.state.showTotal
                  });
                }}
              >
                <Statistic
                  precision={1}
                  prefix={<ArrowUpOutlined />}
                  suffix={(() => {
                    if (this.state.showTotal) {
                      return this.mapSizeUnit(this.state.outboundSizeTotal);
                    } else {
                      return this.mapSizeUnit(this.state.outboundSize) + '/s';
                    }
                  })()}
                  title="Outbound"
                  value={(() => {
                    if (this.state.showTotal) {
                      return this.convertSize(this.state.outboundSizeTotal);
                    } else {
                      return this.convertSize(this.state.outboundSize);
                    }
                  })()}
                />
              </Card>
            </Col>
            <Col className="content-col" xs={24} sm={12} md={12} lg={6} xl={4}>
              <Card
                hoverable
                onClick={() => {
                  this.setState({
                    showTotal: !this.state.showTotal
                  });
                }}
              >
                <Statistic
                  precision={1}
                  prefix={<ArrowDownOutlined />}
                  suffix={(() => {
                    if (this.state.showTotal) {
                      return this.mapSizeUnit(this.state.inboundSizeTotal);
                    } else {
                      return this.mapSizeUnit(this.state.inboundSize) + '/s';
                    }
                  })()}
                  title="Inbound"
                  value={(() => {
                    if (this.state.showTotal) {
                      return this.convertSize(this.state.inboundSizeTotal);
                    } else {
                      return this.convertSize(this.state.inboundSize);
                    }
                  })()}
                />
              </Card>
            </Col>
            <Col className="content-col" xs={24} sm={12} md={12} lg={6} xl={4}>
              <Card className="content-card" hoverable>
                <Statistic
                  prefix={<HourglassOutlined />}
                  suffix={this.state.ping < 0 ? '' : 'ms'}
                  title="Delay"
                  value={(() => {
                    if (this.state.ping === -1) {
                      return 'N/A';
                    } else if (this.state.ping === -2) {
                      return 'Timeout';
                    } else {
                      return this.state.ping;
                    }
                  })()}
                  valueStyle={{
                    color: (() => {
                      if (this.state.ping === -2) {
                        return '#cf1322';
                      } else if (this.state.ping >= 100) {
                        return '#faad14';
                      } else {
                        return '#000';
                      }
                    })()
                  }}
                />
              </Card>
            </Col>
            <Col className="content-col" xs={24} sm={12} md={12} lg={6} xl={4}>
              <Card
                hoverable
                onClick={() => {
                  this.setState({
                    configure: true
                  });
                }}
              >
                <Statistic prefix={<SettingOutlined />} title="Configure" value={this.convertPath(this.state.path)} />
              </Card>
              <ConfigurationForm
                visible={this.state.configure}
                onOk={(values) => {
                  localStorage.setItem('path', values.path);
                  localStorage.setItem('showTotal', values.showTotal ? 'true' : 'false');
                  this.setState({
                    configure: false,
                    path: values.path,
                    showTotal: values.showTotal,
                    active: this.state.path !== values.path ? false : this.state.active,
                    inactive: this.state.path !== values.path ? false : this.state.inactive
                  });
                }}
                onCancel={() => {
                  this.setState({
                    configure: false
                  });
                }}
                initialValues={{ path: this.state.path, showTotal: this.state.showTotal }}
              />
            </Col>
          </Row>
          <Row gutter={16}>
            <Col className="content-col-table" sm={24} md={24} lg={12}>
              <Table dataSource={this.mapNodes(this.state.local)} pagination={false} size="middle">
                <Column title="Source" key="source" align="left" render={this.showNode} />
                <Column title="Outbound" key="outboundSize" align="center" render={this.showOutbound} width={200} />
                <Column title="Inbound" key="inboundSize" align="center" render={this.showInbound} width={200} />
              </Table>
            </Col>
            <Col className="content-col-table" sm={24} md={24} lg={12}>
              <Table dataSource={this.mapNodes(this.state.remote)} pagination={false} size="middle">
                <Column title="Destination" key="source" align="left" render={this.showNode} />
                <Column title="Outbound" key="outboundSize" align="center" render={this.showOutbound} width={200} />
                <Column title="Inbound" key="inboundSize" align="center" render={this.showInbound} width={200} />
              </Table>
            </Col>
          </Row>
        </Content>
      </Layout>
    );
  }