diff --git a/grafana-plugin/src/containers/EditRegexpRouteTemplateModal/EditRegexpRouteTemplateModal.tsx b/grafana-plugin/src/containers/EditRegexpRouteTemplateModal/EditRegexpRouteTemplateModal.tsx index b5b366b8..c7f2390f 100644 --- a/grafana-plugin/src/containers/EditRegexpRouteTemplateModal/EditRegexpRouteTemplateModal.tsx +++ b/grafana-plugin/src/containers/EditRegexpRouteTemplateModal/EditRegexpRouteTemplateModal.tsx @@ -29,7 +29,9 @@ interface EditRegexpRouteTemplateModalProps { const EditRegexpRouteTemplateModal = observer((props: EditRegexpRouteTemplateModalProps) => { const { onHide, onUpdateRoute, channelFilterId, onOpenEditIntegrationTemplate, alertReceiveChannelId } = props; const store = useStore(); + const regexpBody = store.alertReceiveChannelStore.channelFilters[channelFilterId]?.filtering_term; + const [regexpTemplateBody, setRegexpTemplateBody] = useState(regexpBody); const templateJinja2Body = store.alertReceiveChannelStore.channelFilters[channelFilterId]?.filtering_term_as_jinja2; diff --git a/grafana-plugin/src/containers/IntegrationTemplate/IntegrationTemplate.tsx b/grafana-plugin/src/containers/IntegrationTemplate/IntegrationTemplate.tsx index 74181a85..539e645e 100644 --- a/grafana-plugin/src/containers/IntegrationTemplate/IntegrationTemplate.tsx +++ b/grafana-plugin/src/containers/IntegrationTemplate/IntegrationTemplate.tsx @@ -18,6 +18,7 @@ import Text from 'components/Text/Text'; import TemplatePreview from 'containers/TemplatePreview/TemplatePreview'; import TemplatesAlertGroupsList from 'containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList'; import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types'; +import { AlertTemplatesDTO } from 'models/alert_templates'; import { Alert } from 'models/alertgroup/alertgroup.types'; import { ChannelFilter } from 'models/channel_filter/channel_filter.types'; import LocationHelper from 'utils/LocationHelper'; @@ -31,13 +32,14 @@ interface IntegrationTemplateProps { channelFilterId?: ChannelFilter['id']; template: TemplateForEdit; templateBody: string; + templates: AlertTemplatesDTO[]; onHide: () => void; onUpdateTemplates: (values: any) => void; onUpdateRoute: (values: any, channelFilterId?: ChannelFilter['id']) => void; } const IntegrationTemplate = observer((props: IntegrationTemplateProps) => { - const { id, onHide, template, onUpdateTemplates, onUpdateRoute, templateBody, channelFilterId } = props; + const { id, onHide, template, onUpdateTemplates, onUpdateRoute, templateBody, channelFilterId, templates } = props; const [isCheatSheetVisible, setIsCheatSheetVisible] = useState(false); const [chatOps, setChatOps] = useState(undefined); @@ -169,6 +171,7 @@ const IntegrationTemplate = observer((props: IntegrationTemplateProps) => { alertReceiveChannelId={id} onEditPayload={onEditPayload} onSelectAlertGroup={onSelectAlertGroup} + templates={templates} /> {isCheatSheetVisible ? ( @@ -187,7 +190,7 @@ const IntegrationTemplate = observer((props: IntegrationTemplateProps) => { { )} - {/* {alertGroupPayload || resultError ? ( */} { error={resultError} onSaveAndFollowLink={onSaveAndFollowLink} /> - {/* ) : ( -
-
- Please select Alert group to see end result -
-
- )} */} diff --git a/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.tsx b/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.tsx index dfd746bf..636915d9 100644 --- a/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.tsx +++ b/grafana-plugin/src/containers/TemplatesAlertGroupsList/TemplatesAlertGroupsList.tsx @@ -7,6 +7,7 @@ import { debounce } from 'lodash-es'; import MonacoEditor, { MONACO_LANGUAGE } from 'components/MonacoEditor/MonacoEditor'; import Text from 'components/Text/Text'; import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types'; +import { AlertTemplatesDTO } from 'models/alert_templates'; import { Alert } from 'models/alertgroup/alertgroup.types'; import { MONACO_PAYLOAD_OPTIONS } from 'pages/integration_2/Integration2.config'; import { useStore } from 'state/useStore'; @@ -16,13 +17,14 @@ import styles from './TemplatesAlertGroupsList.module.css'; const cx = cn.bind(styles); interface TemplatesAlertGroupsListProps { + templates: AlertTemplatesDTO[]; alertReceiveChannelId: AlertReceiveChannel['id']; onSelectAlertGroup?: (alertGroup: Alert) => void; onEditPayload?: (payload: string) => void; } const TemplatesAlertGroupsList = (props: TemplatesAlertGroupsListProps) => { - const { alertReceiveChannelId, onEditPayload, onSelectAlertGroup } = props; + const { alertReceiveChannelId, templates, onEditPayload, onSelectAlertGroup } = props; const store = useStore(); const [alertGroupsList, setAlertGroupsList] = useState(undefined); const [selectedAlertPayload, setSelectedAlertPayload] = useState(undefined); @@ -80,7 +82,7 @@ const TemplatesAlertGroupsList = (props: TemplatesAlertGroupsListProps) => {
{ disabled={true} useAutoCompleteList={false} language={MONACO_LANGUAGE.json} - data={undefined} + data={templates} monacoOptions={MONACO_PAYLOAD_OPTIONS} showLineNumbers={false} height={'85vh'} diff --git a/grafana-plugin/src/icons/index.tsx b/grafana-plugin/src/icons/index.tsx index c5675c28..3e0141c8 100644 --- a/grafana-plugin/src/icons/index.tsx +++ b/grafana-plugin/src/icons/index.tsx @@ -183,11 +183,11 @@ export const HeartIcon = (_props: IconProps) => ( diff --git a/grafana-plugin/src/models/alert_receive_channel/alert_receive_channel.ts b/grafana-plugin/src/models/alert_receive_channel/alert_receive_channel.ts index 688dba43..20826934 100644 --- a/grafana-plugin/src/models/alert_receive_channel/alert_receive_channel.ts +++ b/grafana-plugin/src/models/alert_receive_channel/alert_receive_channel.ts @@ -109,27 +109,6 @@ export class AlertReceiveChannelStore extends BaseStore { @action async updateItems(query: any = '') { - // const filters = typeof query === 'string' ? { search: query } : query; - // const { search } = filters; - // const { count, results } = await makeRequest(this.path, { params: { search, page } }); - - // this.items = { - // ...this.items, - // ...results.reduce( - // (acc: { [key: number]: AlertReceiveChannel }, item: AlertReceiveChannel) => ({ - // ...acc, - // [item.id]: omit(item, 'heartbeat'), - // }), - // {} - // ), - // }; - - // this.searchResult = result.map((item: AlertReceiveChannel) => item.id); - // this.searchResult = { - // count, - // results: results.map((item: AlertReceiveChannel) => item.id), - // }; - const params = typeof query === 'string' ? { search: query } : query; const result = await makeRequest(this.path, { params }); diff --git a/grafana-plugin/src/pages/integration_2/ExpandedIntegrationRouteDisplay.tsx b/grafana-plugin/src/pages/integration_2/ExpandedIntegrationRouteDisplay.tsx index e8a55bbe..cdd857dd 100644 --- a/grafana-plugin/src/pages/integration_2/ExpandedIntegrationRouteDisplay.tsx +++ b/grafana-plugin/src/pages/integration_2/ExpandedIntegrationRouteDisplay.tsx @@ -34,11 +34,7 @@ interface ExpandedIntegrationRouteDisplayProps { routeIndex: number; templates: AlertTemplatesDTO[]; openEditTemplateModal: (templateName: string | string[], channelFilterId?: ChannelFilter['id']) => void; - onEditRegexpTemplate: ( - templateRegexpBody: string, - templateJijja2Body: string, - channelFilterId: ChannelFilter['id'] - ) => void; + onEditRegexpTemplate: (channelFilterId: ChannelFilter['id']) => void; } interface ExpandedIntegrationRouteDisplayState { @@ -253,7 +249,7 @@ const ExpandedIntegrationRouteDisplay: React.FC ? this.getRoutingTemplate(channelFilterIdForEdit) : templates[selectedTemplate?.name] } + templates={templates} /> )} {isEditRegexpRouteTemplateModalOpen && ( @@ -484,7 +485,10 @@ class Integration2 extends React.Component const heartbeatStatus = Boolean(heartbeat?.status); - if (!alertReceiveChannel.heartbeat) { + if ( + !alertReceiveChannel.is_available_for_integration_heartbeat || + alertReceiveChannel.heartbeat?.last_heartbeat_time_verbal === null + ) { return null; } @@ -492,9 +496,9 @@ class Integration2 extends React.Component : } - tooltipTitle={`Last heartbeat: ${alertReceiveChannel.heartbeat?.last_heartbeat_time_verbal || 'never'}`} + borderType={heartbeatStatus ? 'success' : 'danger'} + customIcon={heartbeatStatus ? : } + tooltipTitle={`Last heartbeat: ${alertReceiveChannel.heartbeat?.last_heartbeat_time_verbal}`} tooltipContent={undefined} /> ); diff --git a/grafana-plugin/src/pages/integrations_2/Integrations2.tsx b/grafana-plugin/src/pages/integrations_2/Integrations2.tsx index b6d3769b..ded78648 100644 --- a/grafana-plugin/src/pages/integrations_2/Integrations2.tsx +++ b/grafana-plugin/src/pages/integrations_2/Integrations2.tsx @@ -23,7 +23,7 @@ import IntegrationForm2 from 'containers/IntegrationForm/IntegrationForm2'; import RemoteFilters from 'containers/RemoteFilters/RemoteFilters'; import TeamName from 'containers/TeamName/TeamName'; import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip'; -import { HeartGreenIcon, HeartRedIcon } from 'icons'; +import { HeartIcon, HeartRedIcon } from 'icons'; import { AlertReceiveChannel, MaintenanceMode } from 'models/alert_receive_channel/alert_receive_channel.types'; import IntegrationHelper from 'pages/integration_2/Integration2.helper'; import { PageProps, WithStoreProps } from 'state/types'; @@ -36,6 +36,7 @@ import styles from './Integrations2.module.scss'; const cx = cn.bind(styles); const FILTERS_DEBOUNCE_MS = 500; const ITEMS_PER_PAGE = 15; +const MAX_LINE_LENGTH = 40; interface IntegrationsState extends PageBaseState { integrationsFilters: Filters; @@ -116,7 +117,7 @@ class Integrations extends React.Component const columns = [ { - width: '25%', + width: '35%', title: 'Name', key: 'name', render: this.renderName, @@ -129,7 +130,7 @@ class Integrations extends React.Component render: (item: AlertReceiveChannel) => this.renderIntegrationStatus(item, alertReceiveChannelStore), }, { - width: '25%', + width: '20%', title: 'Datasource', key: 'datasource', render: (item: AlertReceiveChannel) => this.renderDatasource(item, alertReceiveChannelStore), @@ -147,7 +148,7 @@ class Integrations extends React.Component render: (item: AlertReceiveChannel) => this.renderHeartbeat(item, alertReceiveChannelStore, heartbeatStore), }, { - width: '20%', + width: '15%', title: 'Team', render: (item: AlertReceiveChannel) => this.renderTeam(item, grafanaTeamStore.items), }, @@ -229,7 +230,14 @@ class Integrations extends React.Component return ( - + MAX_LINE_LENGTH + ? item.verbal_name.substring(0, MAX_LINE_LENGTH) + '...' + : item.verbal_name + } + /> ); @@ -292,13 +300,13 @@ class Integrations extends React.Component const heartbeatStatus = Boolean(heartbeat?.status); return (
- {alertReceiveChannel.is_available_for_integration_heartbeat && ( + {alertReceiveChannel.is_available_for_integration_heartbeat && heartbeat?.last_heartbeat_time_verbal && ( : } - tooltipTitle={`Last heartbeat: ${heartbeat?.last_heartbeat_time_verbal || 'never'}`} + borderType={heartbeatStatus ? 'success' : 'danger'} + customIcon={heartbeatStatus ? : } + tooltipTitle={`Last heartbeat: ${heartbeat?.last_heartbeat_time_verbal}`} tooltipContent={undefined} /> )} @@ -337,7 +345,16 @@ class Integrations extends React.Component this.onIntegrationEditClick(item.id)} /> - + + + + } + > applyFilters = () => { const { store } = this.props; const { alertReceiveChannelStore } = store; - const { integrationsFilters } = this.state; + const { integrationsFilters, page } = this.state; - return alertReceiveChannelStore.updateItems(integrationsFilters); + return alertReceiveChannelStore.updatePaginatedItems(integrationsFilters, page); }; debouncedUpdateIntegrations = debounce(this.applyFilters, FILTERS_DEBOUNCE_MS);