mirror of
https://github.com/grafana/grafana.git
synced 2025-02-12 16:45:43 -06:00
145 lines
4.2 KiB
TypeScript
145 lines
4.2 KiB
TypeScript
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;
|
|
`,
|
|
};
|
|
};
|