Skip to content

Commit

Permalink
[8.x] [ResponseOps][Alerting] Show missing Slack connectors in the ne…
Browse files Browse the repository at this point in the history
…w rule form (#202315) (#202934)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[ResponseOps][Alerting] Show missing Slack connectors in the new rule
form (#202315)](#202315)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Georgiana-Andreea
Onoleață","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-12-04T14:05:38Z","message":"[ResponseOps][Alerting]
Show missing Slack connectors in the new rule form (#202315)\n\nCloses
https://github.com/elastic/kibana/issues/201673\r\n\r\n##
Summary\r\n\r\n- changed the logic to create the connectorsMap (which
gives us the\r\nconnector type filters):\r\n- Only the '**slack'** and
**'slack API'** connector types include a\r\n`subtype` array. I updated
the logic so that when the `actionTypeModel`\r\nhas **hideInUi** set to
true (indicating a 'slack API' connector), it\r\nsearches for a
**'slack'** connector in the subtype. If a **'slack'**\r\nconnector is
found, `otherActionTypeId` is set to 'slack'; otherwise, it\r\nis set to
`undefined`. This effectively \"maps\" the 'slack API' type to\r\nthe
'slack' type within the `connectorsMap`\r\n\r\n- changed the logic to
create the `filteredConnectors` (which gives us\r\nthe connectors to
display, filtered after the type):\r\n- The **selectedConnectorType**
can only be '**slack'** because, in the\r\n`connectorsMap`, the '**slack
API'** option has already been mapped to\r\n'**slack'** and is no longer
included as a separate type.\r\n- If the `subtype` includes **'slack',**
the filter will return\r\nconnectors with `actionTypeId` of either
'slack' or 'slack API'.\r\n- This ensures that both 'slack' and 'slack
API' connectors are\r\ndisplayed, as 'slack API' is associated with the
'slack' type through\r\nthe subtype.\r\n
\r\n\r\n\r\nhttps://github.com/user-attachments/assets/9cccaf42-b6db-4eea-b2fd-8f37f0e24745\r\n\r\n##
Release note\r\nFix Slack API connectors not displayed under Slack
connector type when\r\nadding new connector to
rule.","sha":"2884d903de43c5f846a96385215b303397826973","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","release_note:fix","Team:ResponseOps","v9.0.0","backport:prev-minor","v8.17.0","v8.16.2"],"title":"[ResponseOps][Alerting]
Show missing Slack connectors in the new rule
form","number":202315,"url":"https://github.com/elastic/kibana/pull/202315","mergeCommit":{"message":"[ResponseOps][Alerting]
Show missing Slack connectors in the new rule form (#202315)\n\nCloses
https://github.com/elastic/kibana/issues/201673\r\n\r\n##
Summary\r\n\r\n- changed the logic to create the connectorsMap (which
gives us the\r\nconnector type filters):\r\n- Only the '**slack'** and
**'slack API'** connector types include a\r\n`subtype` array. I updated
the logic so that when the `actionTypeModel`\r\nhas **hideInUi** set to
true (indicating a 'slack API' connector), it\r\nsearches for a
**'slack'** connector in the subtype. If a **'slack'**\r\nconnector is
found, `otherActionTypeId` is set to 'slack'; otherwise, it\r\nis set to
`undefined`. This effectively \"maps\" the 'slack API' type to\r\nthe
'slack' type within the `connectorsMap`\r\n\r\n- changed the logic to
create the `filteredConnectors` (which gives us\r\nthe connectors to
display, filtered after the type):\r\n- The **selectedConnectorType**
can only be '**slack'** because, in the\r\n`connectorsMap`, the '**slack
API'** option has already been mapped to\r\n'**slack'** and is no longer
included as a separate type.\r\n- If the `subtype` includes **'slack',**
the filter will return\r\nconnectors with `actionTypeId` of either
'slack' or 'slack API'.\r\n- This ensures that both 'slack' and 'slack
API' connectors are\r\ndisplayed, as 'slack API' is associated with the
'slack' type through\r\nthe subtype.\r\n
\r\n\r\n\r\nhttps://github.com/user-attachments/assets/9cccaf42-b6db-4eea-b2fd-8f37f0e24745\r\n\r\n##
Release note\r\nFix Slack API connectors not displayed under Slack
connector type when\r\nadding new connector to
rule.","sha":"2884d903de43c5f846a96385215b303397826973"}},"sourceBranch":"main","suggestedTargetBranches":["8.17","8.16"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/202315","number":202315,"mergeCommit":{"message":"[ResponseOps][Alerting]
Show missing Slack connectors in the new rule form (#202315)\n\nCloses
https://github.com/elastic/kibana/issues/201673\r\n\r\n##
Summary\r\n\r\n- changed the logic to create the connectorsMap (which
gives us the\r\nconnector type filters):\r\n- Only the '**slack'** and
**'slack API'** connector types include a\r\n`subtype` array. I updated
the logic so that when the `actionTypeModel`\r\nhas **hideInUi** set to
true (indicating a 'slack API' connector), it\r\nsearches for a
**'slack'** connector in the subtype. If a **'slack'**\r\nconnector is
found, `otherActionTypeId` is set to 'slack'; otherwise, it\r\nis set to
`undefined`. This effectively \"maps\" the 'slack API' type to\r\nthe
'slack' type within the `connectorsMap`\r\n\r\n- changed the logic to
create the `filteredConnectors` (which gives us\r\nthe connectors to
display, filtered after the type):\r\n- The **selectedConnectorType**
can only be '**slack'** because, in the\r\n`connectorsMap`, the '**slack
API'** option has already been mapped to\r\n'**slack'** and is no longer
included as a separate type.\r\n- If the `subtype` includes **'slack',**
the filter will return\r\nconnectors with `actionTypeId` of either
'slack' or 'slack API'.\r\n- This ensures that both 'slack' and 'slack
API' connectors are\r\ndisplayed, as 'slack API' is associated with the
'slack' type through\r\nthe subtype.\r\n
\r\n\r\n\r\nhttps://github.com/user-attachments/assets/9cccaf42-b6db-4eea-b2fd-8f37f0e24745\r\n\r\n##
Release note\r\nFix Slack API connectors not displayed under Slack
connector type when\r\nadding new connector to
rule.","sha":"2884d903de43c5f846a96385215b303397826973"}},{"branch":"8.17","label":"v8.17.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.16","label":"v8.16.2","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Georgiana-Andreea Onoleață <[email protected]>
  • Loading branch information
kibanamachine and georgianaonoleata1904 authored Dec 4, 2024
1 parent d26bdb1 commit 0d1d013
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,92 @@ describe('ruleActionsConnectorsModal', () => {
expect(screen.queryByText('connector2')).not.toBeInTheDocument();
});

test('should not render connector filter if hideInUi is true', async () => {
const actionTypeRegistry = new TypeRegistry<ActionTypeModel>();
actionTypeRegistry.register(
getActionTypeModel('1', {
id: 'actionType-1',
subtype: [
{ id: 'actionType-1', name: 'connector-1' },
{ id: 'actionType-2', name: 'connector-2' },
],
})
);
actionTypeRegistry.register(
getActionTypeModel('2', {
id: 'actionType-2',
hideInUi: true,
subtype: [
{ id: 'actionType-1', name: 'connector-1' },
{ id: 'actionType-2', name: 'connector-2' },
],
})
);
useRuleFormState.mockReturnValue({
plugins: {
actionTypeRegistry,
},
formData: {
actions: [],
},
connectors: mockConnectors,
connectorTypes: mockActionTypes,
});

render(
<RuleActionsConnectorsModal onClose={mockOnClose} onSelectConnector={mockOnSelectConnector} />
);
const filterButtonGroup = screen.getByTestId('ruleActionsConnectorsModalFilterButtonGroup');
expect(within(filterButtonGroup).getByText('actionType: 1')).toBeInTheDocument();
expect(within(filterButtonGroup).queryByText('actionType: 2')).not.toBeInTheDocument();
expect(within(filterButtonGroup).getByText('All')).toBeInTheDocument();

expect(screen.getAllByTestId('ruleActionsConnectorsModalFilterButton').length).toEqual(2);
});

test('should display connectors if hideInUi is true and it has subtype', async () => {
const actionTypeRegistry = new TypeRegistry<ActionTypeModel>();
actionTypeRegistry.register(
getActionTypeModel('1', {
id: 'actionType-1',
subtype: [
{ id: 'actionType-1', name: 'connector-1' },
{ id: 'actionType-2', name: 'connector-2' },
],
})
);
actionTypeRegistry.register(
getActionTypeModel('2', {
id: 'actionType-2',
hideInUi: true,
subtype: [
{ id: 'actionType-1', name: 'connector-1' },
{ id: 'actionType-2', name: 'connector-2' },
],
})
);
useRuleFormState.mockReturnValue({
plugins: {
actionTypeRegistry,
},
formData: {
actions: [],
},
connectors: mockConnectors,
connectorTypes: mockActionTypes,
});

render(
<RuleActionsConnectorsModal onClose={mockOnClose} onSelectConnector={mockOnSelectConnector} />
);
const filterButtonGroup = screen.getByTestId('ruleActionsConnectorsModalFilterButtonGroup');

await userEvent.click(within(filterButtonGroup).getByText('actionType: 1'));
expect(screen.getAllByTestId('ruleActionsConnectorsModalCard').length).toEqual(2);
expect(screen.getByText('connector-1')).toBeInTheDocument();
expect(screen.getByText('connector-2')).toBeInTheDocument();
});

test('should not render connector if actionsParamsField doesnt exist', () => {
const actionTypeRegistry = new TypeRegistry<ActionTypeModel>();
actionTypeRegistry.register(getActionTypeModel('1', { id: 'actionType-1' }));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,7 @@ export const RuleActionsConnectorsModal = (props: RuleActionsConnectorsModalProp
if (!actionType) {
return false;
}
if (actionTypeModel.hideInUi) {
return false;
}

if (!actionTypeModel.actionParamsFields) {
return false;
}
Expand All @@ -93,6 +91,7 @@ export const RuleActionsConnectorsModal = (props: RuleActionsConnectorsModalProp
if (!actionType.enabledInConfig && !checkEnabledResult.isEnabled) {
return false;
}

return true;
});
}, [connectors, connectorTypes, preconfiguredConnectors, actionTypeRegistry]);
Expand Down Expand Up @@ -120,29 +119,43 @@ export const RuleActionsConnectorsModal = (props: RuleActionsConnectorsModalProp

const connectorsMap: ConnectorsMap | null = useMemo(() => {
return availableConnectors.reduce<ConnectorsMap>((result, { actionTypeId }) => {
if (result[actionTypeId]) {
result[actionTypeId].total += 1;
const actionTypeModel = actionTypeRegistry.get(actionTypeId);
const subtype = actionTypeModel.subtype;

const shownActionTypeId = actionTypeModel.hideInUi
? subtype?.filter((type) => type.id !== actionTypeId)[0].id
: undefined;

const currentActionTypeId = shownActionTypeId ? shownActionTypeId : actionTypeId;

if (result[currentActionTypeId]) {
result[currentActionTypeId].total += 1;
} else {
result[actionTypeId] = {
actionTypeId,
result[currentActionTypeId] = {
actionTypeId: currentActionTypeId,
total: 1,
name: connectorTypes.find(({ id }) => actionTypeId === id)?.name || '',
name: connectorTypes.find(({ id }) => id === currentActionTypeId)?.name || '',
};
}

return result;
}, {});
}, [availableConnectors, connectorTypes]);
}, [availableConnectors, connectorTypes, actionTypeRegistry]);

const filteredConnectors = useMemo(() => {
return availableConnectors
.filter(({ actionTypeId }) => {
const subtype = actionTypeRegistry.get(actionTypeId).subtype?.map((type) => type.id);

if (selectedConnectorType === 'all' || selectedConnectorType === '') {
return true;
}
if (selectedConnectorType === actionTypeId) {
return true;

if (subtype?.includes(selectedConnectorType)) {
return subtype.includes(actionTypeId);
}
return false;

return selectedConnectorType === actionTypeId;
})
.filter(({ actionTypeId, name }) => {
const trimmedSearchValue = searchValue.trim().toLocaleLowerCase();
Expand Down

0 comments on commit 0d1d013

Please sign in to comment.