Grouping templating polishing 2 (#1947)

Fixes for:
Suggestions in the code,
Heartbeat,
Deleting integration, 
Editing regexp route,
Style changes
etc
This commit is contained in:
Yulia Shanyrova 2023-05-16 15:23:40 +02:00 committed by GitHub
parent 319cc72cdd
commit 5fae708d0a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 57 additions and 62 deletions

View file

@ -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<string>(regexpBody);
const templateJinja2Body = store.alertReceiveChannelStore.channelFilters[channelFilterId]?.filtering_term_as_jinja2;

View file

@ -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<boolean>(false);
const [chatOps, setChatOps] = useState(undefined);
@ -169,6 +171,7 @@ const IntegrationTemplate = observer((props: IntegrationTemplateProps) => {
alertReceiveChannelId={id}
onEditPayload={onEditPayload}
onSelectAlertGroup={onSelectAlertGroup}
templates={templates}
/>
{isCheatSheetVisible ? (
<CheatSheet cheatSheetData={getCheatSheet(template.displayName)} onClose={onCloseCheatSheet} />
@ -187,7 +190,7 @@ const IntegrationTemplate = observer((props: IntegrationTemplateProps) => {
<MonacoEditor
value={templateBody}
data={undefined}
data={templates}
showLineNumbers={true}
height={'85vh'}
onChange={getChangeHandler()}
@ -195,7 +198,6 @@ const IntegrationTemplate = observer((props: IntegrationTemplateProps) => {
</div>
</>
)}
{/* {alertGroupPayload || resultError ? ( */}
<Result
alertReceiveChannelId={id}
templateName={template.name}
@ -206,13 +208,6 @@ const IntegrationTemplate = observer((props: IntegrationTemplateProps) => {
error={resultError}
onSaveAndFollowLink={onSaveAndFollowLink}
/>
{/* ) : (
<div className={cx('template-block-result')}>
<div className={cx('template-block-title')}>
<Text>Please select Alert group to see end result</Text>
</div>
</div>
)} */}
</div>
</div>
</Drawer>

View file

@ -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<string>(undefined);
@ -80,7 +82,7 @@ const TemplatesAlertGroupsList = (props: TemplatesAlertGroupsListProps) => {
<div className={cx('alert-groups-list')}>
<MonacoEditor
value={JSON.stringify(selectedAlertPayload, null, 4)}
data={undefined}
data={templates}
height={'85vh'}
onChange={getChangeHandler()}
showLineNumbers
@ -142,7 +144,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'}

View file

@ -183,11 +183,11 @@ export const HeartIcon = (_props: IconProps) => (
<g>
<path
d="M222.5,453.7c6.1,6.1,14.3,9.5,22.9,9.5c8.5,0,16.9-3.5,22.9-9.5L448,274c27.3-27.3,42.3-63.6,42.4-102.1
c0-38.6-15-74.9-42.3-102.2S384.6,27.4,346,27.4c-37.9,0-73.6,14.5-100.7,40.9c-27.2-26.5-63-41.1-101-41.1
c-38.5,0-74.7,15-102,42.2C15,96.7,0,133,0,171.6c0,38.5,15.1,74.8,42.4,102.1L222.5,453.7z M59.7,86.8
c22.6-22.6,52.7-35.1,84.7-35.1s62.2,12.5,84.9,35.2l7.4,7.4c2.3,2.3,5.4,3.6,8.7,3.6l0,0c3.2,0,6.4-1.3,8.7-3.6l7.2-7.2
c22.7-22.7,52.8-35.2,84.9-35.2c32,0,62.1,12.5,84.7,35.1c22.7,22.7,35.1,52.8,35.1,84.8s-12.5,62.1-35.2,84.8L251,436.4
c-2.9,2.9-8.2,2.9-11.2,0l-180-180c-22.7-22.7-35.2-52.8-35.2-84.8C24.6,139.6,37.1,109.5,59.7,86.8z"
c0-38.6-15-74.9-42.3-102.2S384.6,27.4,346,27.4c-37.9,0-73.6,14.5-100.7,40.9c-27.2-26.5-63-41.1-101-41.1
c-38.5,0-74.7,15-102,42.2C15,96.7,0,133,0,171.6c0,38.5,15.1,74.8,42.4,102.1L222.5,453.7z M59.7,86.8
c22.6-22.6,52.7-35.1,84.7-35.1s62.2,12.5,84.9,35.2l7.4,7.4c2.3,2.3,5.4,3.6,8.7,3.6l0,0c3.2,0,6.4-1.3,8.7-3.6l7.2-7.2
c22.7-22.7,52.8-35.2,84.9-35.2c32,0,62.1,12.5,84.7,35.1c22.7,22.7,35.1,52.8,35.1,84.8s-12.5,62.1-35.2,84.8L251,436.4
c-2.9,2.9-8.2,2.9-11.2,0l-180-180c-22.7-22.7-35.2-52.8-35.2-84.8C24.6,139.6,37.1,109.5,59.7,86.8z"
/>
</g>
</svg>

View file

@ -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 });

View file

@ -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<ExpandedIntegrationRouteDisplayP
function handleEditRoutingTemplate(channelFilter, channelFilterId) {
if (channelFilter.filtering_term_type === 0) {
onEditRegexpTemplate(channelFilter.filtering_term, channelFilter.filtering_term_as_jinja2, channelFilterId);
onEditRegexpTemplate(channelFilterId);
} else {
openEditTemplateModal('route_template', channelFilterId);
}

View file

@ -42,7 +42,7 @@ import MaintenanceForm from 'containers/MaintenanceForm/MaintenanceForm';
import TeamName from 'containers/TeamName/TeamName';
import UserDisplayWithAvatar from 'containers/UserDisplay/UserDisplayWithAvatar';
import { WithPermissionControlTooltip } from 'containers/WithPermissionControl/WithPermissionControlTooltip';
import { HeartGreenIcon, HeartRedIcon } from 'icons';
import { HeartIcon, HeartRedIcon } from 'icons';
import { AlertReceiveChannel } from 'models/alert_receive_channel/alert_receive_channel.types';
import { ChannelFilter } from 'models/channel_filter';
import { MaintenanceType } from 'models/maintenance/maintenance.types';
@ -372,6 +372,7 @@ class Integration2 extends React.Component<Integration2Props, Integration2State>
? this.getRoutingTemplate(channelFilterIdForEdit)
: templates[selectedTemplate?.name]
}
templates={templates}
/>
)}
{isEditRegexpRouteTemplateModalOpen && (
@ -484,7 +485,10 @@ class Integration2 extends React.Component<Integration2Props, Integration2State>
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<Integration2Props, Integration2State>
<TooltipBadge
text={undefined}
className={cx('heartbeat-badge')}
borderType={alertReceiveChannel.heartbeat?.last_heartbeat_time_verbal ? 'success' : 'danger'}
customIcon={heartbeatStatus ? <HeartGreenIcon /> : <HeartRedIcon />}
tooltipTitle={`Last heartbeat: ${alertReceiveChannel.heartbeat?.last_heartbeat_time_verbal || 'never'}`}
borderType={heartbeatStatus ? 'success' : 'danger'}
customIcon={heartbeatStatus ? <HeartIcon /> : <HeartRedIcon />}
tooltipTitle={`Last heartbeat: ${alertReceiveChannel.heartbeat?.last_heartbeat_time_verbal}`}
tooltipContent={undefined}
/>
);

View file

@ -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<IntegrationsProps, IntegrationsState>
const columns = [
{
width: '25%',
width: '35%',
title: 'Name',
key: 'name',
render: this.renderName,
@ -129,7 +130,7 @@ class Integrations extends React.Component<IntegrationsProps, IntegrationsState>
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<IntegrationsProps, IntegrationsState>
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<IntegrationsProps, IntegrationsState>
return (
<PluginLink query={{ page: 'integrations_2', id: item.id }}>
<Text type="link" size="medium">
<Emoji className={cx('title')} text={item.verbal_name} />
<Emoji
className={cx('title')}
text={
item.verbal_name.length > MAX_LINE_LENGTH
? item.verbal_name.substring(0, MAX_LINE_LENGTH) + '...'
: item.verbal_name
}
/>
</Text>
</PluginLink>
);
@ -292,13 +300,13 @@ class Integrations extends React.Component<IntegrationsProps, IntegrationsState>
const heartbeatStatus = Boolean(heartbeat?.status);
return (
<div>
{alertReceiveChannel.is_available_for_integration_heartbeat && (
{alertReceiveChannel.is_available_for_integration_heartbeat && heartbeat?.last_heartbeat_time_verbal && (
<TooltipBadge
text={undefined}
className={cx('heartbeat-badge')}
borderType={heartbeat?.last_heartbeat_time_verbal ? 'success' : 'danger'}
customIcon={heartbeatStatus ? <HeartGreenIcon /> : <HeartRedIcon />}
tooltipTitle={`Last heartbeat: ${heartbeat?.last_heartbeat_time_verbal || 'never'}`}
borderType={heartbeatStatus ? 'success' : 'danger'}
customIcon={heartbeatStatus ? <HeartIcon /> : <HeartRedIcon />}
tooltipTitle={`Last heartbeat: ${heartbeat?.last_heartbeat_time_verbal}`}
tooltipContent={undefined}
/>
)}
@ -337,7 +345,16 @@ class Integrations extends React.Component<IntegrationsProps, IntegrationsState>
<IconButton tooltip="Settings" name="cog" onClick={() => this.onIntegrationEditClick(item.id)} />
</WithPermissionControlTooltip>
<WithPermissionControlTooltip key="edit" userAction={UserActions.IntegrationsWrite}>
<WithConfirm>
<WithConfirm
description={
<Text>
<Emoji
className={cx('title')}
text={`Are you sure you want to delete ${item.verbal_name} integration?`}
/>
</Text>
}
>
<IconButton
tooltip="Delete"
name="trash-alt"
@ -368,9 +385,9 @@ class Integrations extends React.Component<IntegrationsProps, IntegrationsState>
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);