forked from grafana.jool/grafana-jool
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
4.8 KiB
168 lines
4.8 KiB
import React, { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
|
import { Button, HorizontalGroup, IconButton } from '@grafana/ui';
|
|
import { AmRouteReceiver, FormAmRoute } from '../../types/amroutes';
|
|
import { prepareItems } from '../../utils/dynamicTable';
|
|
import { DynamicTable, DynamicTableColumnProps, DynamicTableItemProps } from '../DynamicTable';
|
|
import { AmRoutesExpandedForm } from './AmRoutesExpandedForm';
|
|
import { AmRoutesExpandedRead } from './AmRoutesExpandedRead';
|
|
import { Matchers } from '../silences/Matchers';
|
|
import { matcherFieldToMatcher } from '../../utils/alertmanager';
|
|
|
|
export interface AmRoutesTableProps {
|
|
isAddMode: boolean;
|
|
onChange: (routes: FormAmRoute[]) => void;
|
|
onCancelAdd: () => void;
|
|
receivers: AmRouteReceiver[];
|
|
routes: FormAmRoute[];
|
|
readOnly?: boolean;
|
|
}
|
|
|
|
type RouteTableColumnProps = DynamicTableColumnProps<FormAmRoute>;
|
|
type RouteTableItemProps = DynamicTableItemProps<FormAmRoute>;
|
|
|
|
export const AmRoutesTable: FC<AmRoutesTableProps> = ({
|
|
isAddMode,
|
|
onCancelAdd,
|
|
onChange,
|
|
receivers,
|
|
routes,
|
|
readOnly = false,
|
|
}) => {
|
|
const [editMode, setEditMode] = useState(false);
|
|
|
|
const [expandedId, setExpandedId] = useState<string | number>();
|
|
|
|
const expandItem = useCallback((item: RouteTableItemProps) => setExpandedId(item.id), []);
|
|
|
|
const collapseItem = useCallback(() => setExpandedId(undefined), []);
|
|
|
|
const cols: RouteTableColumnProps[] = [
|
|
{
|
|
id: 'matchingCriteria',
|
|
label: 'Matching labels',
|
|
// eslint-disable-next-line react/display-name
|
|
renderCell: (item) => <Matchers matchers={item.data.object_matchers.map(matcherFieldToMatcher)} />,
|
|
size: 10,
|
|
},
|
|
{
|
|
id: 'groupBy',
|
|
label: 'Group by',
|
|
renderCell: (item) => item.data.groupBy.join(', ') || '-',
|
|
size: 5,
|
|
},
|
|
{
|
|
id: 'receiverChannel',
|
|
label: 'Contact point',
|
|
renderCell: (item) => item.data.receiver || '-',
|
|
size: 5,
|
|
},
|
|
...(readOnly
|
|
? []
|
|
: [
|
|
{
|
|
id: 'actions',
|
|
label: 'Actions',
|
|
// eslint-disable-next-line react/display-name
|
|
renderCell: (item, index) => {
|
|
if (item.renderExpandedContent) {
|
|
return null;
|
|
}
|
|
|
|
const expandWithCustomContent = () => {
|
|
expandItem(item);
|
|
setEditMode(true);
|
|
};
|
|
|
|
return (
|
|
<HorizontalGroup>
|
|
<Button
|
|
aria-label="Edit route"
|
|
icon="pen"
|
|
onClick={expandWithCustomContent}
|
|
size="sm"
|
|
type="button"
|
|
variant="secondary"
|
|
>
|
|
Edit
|
|
</Button>
|
|
<IconButton
|
|
aria-label="Delete route"
|
|
name="trash-alt"
|
|
onClick={() => {
|
|
const newRoutes = [...routes];
|
|
|
|
newRoutes.splice(index, 1);
|
|
|
|
onChange(newRoutes);
|
|
}}
|
|
type="button"
|
|
/>
|
|
</HorizontalGroup>
|
|
);
|
|
},
|
|
size: '100px',
|
|
} as RouteTableColumnProps,
|
|
]),
|
|
];
|
|
|
|
const items = useMemo(() => prepareItems(routes), [routes]);
|
|
|
|
// expand the last item when adding
|
|
useEffect(() => {
|
|
if (isAddMode && items.length) {
|
|
setExpandedId(items[items.length - 1].id);
|
|
}
|
|
}, [isAddMode, items]);
|
|
|
|
return (
|
|
<DynamicTable
|
|
cols={cols}
|
|
isExpandable={true}
|
|
items={items}
|
|
testIdGenerator={() => 'am-routes-row'}
|
|
onCollapse={collapseItem}
|
|
onExpand={expandItem}
|
|
isExpanded={(item) => expandedId === item.id}
|
|
renderExpandedContent={(item: RouteTableItemProps, index) =>
|
|
isAddMode || editMode ? (
|
|
<AmRoutesExpandedForm
|
|
onCancel={() => {
|
|
if (isAddMode) {
|
|
onCancelAdd();
|
|
}
|
|
setEditMode(false);
|
|
}}
|
|
onSave={(data) => {
|
|
const newRoutes = [...routes];
|
|
|
|
newRoutes[index] = {
|
|
...newRoutes[index],
|
|
...data,
|
|
};
|
|
setEditMode(false);
|
|
onChange(newRoutes);
|
|
}}
|
|
receivers={receivers}
|
|
routes={item.data}
|
|
/>
|
|
) : (
|
|
<AmRoutesExpandedRead
|
|
onChange={(data) => {
|
|
const newRoutes = [...routes];
|
|
|
|
newRoutes[index] = {
|
|
...item.data,
|
|
...data,
|
|
};
|
|
|
|
onChange(newRoutes);
|
|
}}
|
|
receivers={receivers}
|
|
routes={item.data}
|
|
readOnly={readOnly}
|
|
/>
|
|
)
|
|
}
|
|
/>
|
|
);
|
|
};
|
|
|