@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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 < 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 |
GenesVsUMIsConfig = (props) => {
const {
// eslint-disable-next-line no-unused-vars
config, disabled, plotType, updateSettings,
} = props;
return (
<>
<Form.Item label={(
<span>
Fit type
<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 |
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 |
StyledInfoCircleOutlined = styled(InfoCircleOutlined)`
font-size: 40px;
margin-right: 13px;
`
Example #11
Source File: index.jsx From ui with MIT License | 4 votes |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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>
)
}