mirror of https://github.com/grafana/grafana
Live: add rule for datasource (#40738)
parent
1095f69740
commit
4680a8454f
@ -0,0 +1,144 @@ |
||||
import React, { useEffect, useState } from 'react'; |
||||
import { getBackendSrv } from '@grafana/runtime'; |
||||
import { Tag, useStyles, IconButton } from '@grafana/ui'; |
||||
import { css } from '@emotion/css'; |
||||
import { GrafanaTheme } from '@grafana/data'; |
||||
import { Rule, Output, RuleType } from './types'; |
||||
import { RuleModal } from './RuleModal'; |
||||
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv'; |
||||
|
||||
function renderOutputTags(key: string, output?: Output): React.ReactNode { |
||||
if (!output?.type) { |
||||
return null; |
||||
} |
||||
return <Tag key={key} name={output.type} />; |
||||
} |
||||
|
||||
interface Props { |
||||
rules: Rule[]; |
||||
onRuleChanged: () => void; |
||||
selectRule?: Rule; |
||||
} |
||||
|
||||
export const PipelineTable: React.FC<Props> = (props) => { |
||||
const { rules } = props; |
||||
const [isOpen, setOpen] = useState(false); |
||||
const [selectedRule, setSelectedRule] = useState<Rule>(); |
||||
const [clickColumn, setClickColumn] = useState<RuleType>('converter'); |
||||
const styles = useStyles(getStyles); |
||||
|
||||
const onRowClick = (rule: Rule, event?: any) => { |
||||
if (!rule) { |
||||
return; |
||||
} |
||||
let column = event?.target?.getAttribute('data-column'); |
||||
if (!column || column === 'pattern') { |
||||
column = 'converter'; |
||||
} |
||||
setClickColumn(column); |
||||
setSelectedRule(rule); |
||||
setOpen(true); |
||||
}; |
||||
|
||||
// Supports selecting a rule from external config (after add rule)
|
||||
useEffect(() => { |
||||
if (props.selectRule) { |
||||
onRowClick(props.selectRule); |
||||
} |
||||
}, [props.selectRule]); |
||||
|
||||
const onRemoveRule = (pattern: string) => { |
||||
getBackendSrv() |
||||
.delete(`api/live/channel-rules`, JSON.stringify({ pattern: pattern })) |
||||
.catch((e) => console.error(e)) |
||||
.finally(() => { |
||||
props.onRuleChanged(); |
||||
}); |
||||
}; |
||||
|
||||
const renderPattern = (pattern: string) => { |
||||
if (pattern.startsWith('ds/')) { |
||||
const idx = pattern.indexOf('/', 4); |
||||
if (idx > 3) { |
||||
const uid = pattern.substring(3, idx); |
||||
const ds = getDatasourceSrv().getInstanceSettings(uid); |
||||
if (ds) { |
||||
return ( |
||||
<div> |
||||
<Tag name={ds.name} colorIndex={1} /> |
||||
<span>{pattern.substring(idx + 1)}</span> |
||||
</div> |
||||
); |
||||
} |
||||
} |
||||
} |
||||
return pattern; |
||||
}; |
||||
|
||||
return ( |
||||
<div> |
||||
<div className="admin-list-table"> |
||||
<table className="filter-table filter-table--hover form-inline"> |
||||
<thead> |
||||
<tr> |
||||
<th>Channel</th> |
||||
<th>Converter</th> |
||||
<th>Processor</th> |
||||
<th>Output</th> |
||||
<th style={{ width: 10 }}> </th> |
||||
</tr> |
||||
</thead> |
||||
<tbody> |
||||
{rules.map((rule) => ( |
||||
<tr key={rule.pattern} onClick={(e) => onRowClick(rule, e)} className={styles.row}> |
||||
<td data-pattern={rule.pattern} data-column="pattern"> |
||||
{renderPattern(rule.pattern)} |
||||
</td> |
||||
<td data-pattern={rule.pattern} data-column="converter"> |
||||
{rule.settings?.converter?.type} |
||||
</td> |
||||
<td data-pattern={rule.pattern} data-column="processor"> |
||||
{rule.settings?.frameProcessors?.map((processor) => ( |
||||
<span key={rule.pattern + processor.type}>{processor.type}</span> |
||||
))} |
||||
</td> |
||||
<td data-pattern={rule.pattern} data-column="output"> |
||||
{rule.settings?.frameOutputs?.map((output) => ( |
||||
<span key={rule.pattern + output.type}>{renderOutputTags('out', output)}</span> |
||||
))} |
||||
</td> |
||||
<td> |
||||
<IconButton |
||||
name="trash-alt" |
||||
onClick={(e) => { |
||||
e.stopPropagation(); |
||||
onRemoveRule(rule.pattern); |
||||
}} |
||||
></IconButton> |
||||
</td> |
||||
</tr> |
||||
))} |
||||
</tbody> |
||||
</table> |
||||
</div> |
||||
{isOpen && selectedRule && ( |
||||
<RuleModal |
||||
rule={selectedRule} |
||||
isOpen={isOpen} |
||||
onClose={() => { |
||||
setOpen(false); |
||||
}} |
||||
clickColumn={clickColumn} |
||||
/> |
||||
)} |
||||
</div> |
||||
); |
||||
}; |
||||
|
||||
const getStyles = (theme: GrafanaTheme) => { |
||||
return { |
||||
row: css` |
||||
cursor: pointer; |
||||
`,
|
||||
}; |
||||
}; |
||||
Loading…
Reference in new issue