Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added UI support for the default action group for Alert Type Model #57603

Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -101,5 +101,6 @@ export function getAlertType(): AlertTypeModel {
return validationResult;
},
defaultActionMessage: 'Alert [{{ctx.metadata.name}}] has exceeded the threshold',
defaultActionGroup: 'alert',
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ describe('alert_form', () => {
return { errors: {} };
},
alertParamsExpression: () => <Fragment />,
defaultActionGroup: 'testDefaultActionGroup',
};

const actionType = {
Expand Down Expand Up @@ -158,6 +159,7 @@ describe('alert_form', () => {
alertTypeRegistry.has.mockReturnValue(true);
actionTypeRegistry.list.mockReturnValue([actionType]);
actionTypeRegistry.has.mockReturnValue(true);
actionTypeRegistry.get.mockReturnValue(actionType);

const initialAlert = ({
name: 'test',
Expand Down Expand Up @@ -221,6 +223,12 @@ describe('alert_form', () => {
'[data-test-subj="my-action-type-ActionTypeSelectOption"]'
);
expect(actionTypeSelectOptions.exists()).toBeTruthy();

actionTypeSelectOptions.first().simulate('click');
const actionTypeForm = wrapper.find(
'[data-test-subj="alertActionAccordion-testDefaultActionGroup"]'
);
expect(actionTypeForm.exists()).toBeTruthy();
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ import {
ActionTypeIndex,
ActionConnector,
AlertTypeIndex,
ActionGroup,
} from '../../../types';
import { SectionLoading } from '../../components/section_loading';
import { ConnectorAddModal } from '../action_connector_form/connector_add_modal';
Expand Down Expand Up @@ -119,7 +118,9 @@ export const AlertForm = ({
const [alertThrottleUnit, setAlertThrottleUnit] = useState<string>('m');
const [isAddActionPanelOpen, setIsAddActionPanelOpen] = useState<boolean>(true);
const [connectors, setConnectors] = useState<ActionConnector[]>([]);
const [defaultActionGroup, setDefaultActionGroup] = useState<ActionGroup | undefined>(undefined);
const [defaultActionGroup, setDefaultActionGroup] = useState<string>(
alertTypeModel?.defaultActionGroup ?? 'default'
);
const [activeActionItem, setActiveActionItem] = useState<ActiveActionConnectorState | undefined>(
undefined
);
Expand Down Expand Up @@ -171,8 +172,8 @@ export const AlertForm = ({
for (const alertTypeItem of alertTypes) {
index[alertTypeItem.id] = alertTypeItem;
}
if (alert.alertTypeId) {
setDefaultActionGroup(index[alert.alertTypeId].actionGroups[0]);
if (!alertTypeModel?.defaultActionGroup && alert.alertTypeId && index[alert.alertTypeId]) {
setDefaultActionGroup(index[alert.alertTypeId].actionGroups[0].id);
}
setAlertTypesIndex(index);
} catch (e) {
Expand Down Expand Up @@ -266,7 +267,7 @@ export const AlertForm = ({
alert.actions.push({
id: '',
actionTypeId: actionTypeModel.id,
group: defaultActionGroup?.id ?? 'Alert',
group: defaultActionGroup,
params: {},
});
setActionProperty('id', freeConnectors[0].id, alert.actions.length - 1);
Expand All @@ -278,7 +279,7 @@ export const AlertForm = ({
alert.actions.push({
id: '',
actionTypeId: actionTypeModel.id,
group: defaultActionGroup?.id ?? 'Alert',
group: defaultActionGroup,
params: {},
});
setActionProperty('id', alert.actions.length, alert.actions.length - 1);
Expand All @@ -294,12 +295,15 @@ export const AlertForm = ({
onClick={() => {
setAlertProperty('alertTypeId', item.id);
setAlertTypeModel(item);
if (
if (item.defaultActionGroup) {
setDefaultActionGroup(item.defaultActionGroup);
} else if (
!alertTypeModel?.defaultActionGroup &&
alertTypesIndex &&
alertTypesIndex[item.id] &&
alertTypesIndex[item.id].actionGroups.length > 0
) {
setDefaultActionGroup(alertTypesIndex[item.id].actionGroups[0]);
setDefaultActionGroup(alertTypesIndex[item.id].actionGroups[0].id);
}
}}
>
Expand Down Expand Up @@ -356,7 +360,7 @@ export const AlertForm = ({
id,
}));
const actionTypeRegisterd = actionTypeRegistry.get(actionConnector.actionTypeId);
if (actionTypeRegisterd === null || actionItem.group !== defaultActionGroup?.id) return null;
if (!actionTypeRegisterd || actionItem.group !== defaultActionGroup) return null;
const ParamsFieldsComponent = actionTypeRegisterd.actionParamsFields;
const actionParamsErrors: { errors: IErrorObject } =
Object.keys(actionsErrors).length > 0 ? actionsErrors[actionItem.id] : { errors: {} };
Expand All @@ -368,7 +372,7 @@ export const AlertForm = ({
id={index.toString()}
className="euiAccordionForm"
buttonContentClassName="euiAccordionForm__button"
data-test-subj="alertActionAccordion"
data-test-subj={`alertActionAccordion-${defaultActionGroup}`}
buttonContent={
<EuiFlexGroup gutterSize="s" alignItems="center">
<EuiFlexItem grow={false}>
Expand Down Expand Up @@ -465,7 +469,9 @@ export const AlertForm = ({
errors={actionParamsErrors.errors}
editAction={setActionParamsProperty}
messageVariables={
alertTypesIndex ? alertTypesIndex[alert.alertTypeId].actionVariables : undefined
alertTypesIndex && alertTypesIndex[alert.alertTypeId]
? alertTypesIndex[alert.alertTypeId].actionVariables
: undefined
}
defaultMessage={alertTypeModel?.defaultActionMessage ?? undefined}
/>
Expand All @@ -479,15 +485,15 @@ export const AlertForm = ({
? actionTypesIndex[actionItem.actionTypeId].name
: actionItem.actionTypeId;
const actionTypeRegisterd = actionTypeRegistry.get(actionItem.actionTypeId);
if (actionTypeRegisterd === null || actionItem.group !== defaultActionGroup?.id) return null;
if (!actionTypeRegisterd || actionItem.group !== defaultActionGroup) return null;
return (
<EuiAccordion
initialIsOpen={true}
key={index}
id={index.toString()}
className="euiAccordionForm"
buttonContentClassName="euiAccordionForm__button"
data-test-subj="alertActionAccordion"
data-test-subj={`alertActionAccordion-${defaultActionGroup}`}
buttonContent={
<EuiFlexGroup gutterSize="s" alignItems="center">
<EuiFlexItem grow={false}>
Expand Down
2 changes: 2 additions & 0 deletions x-pack/plugins/triggers_actions_ui/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export interface ActionGroup {
id: string;
name: string;
}

export interface AlertType {
id: string;
name: string;
Expand All @@ -95,6 +96,7 @@ export interface AlertTypeModel {
validate: (alertParams: any) => ValidationResult;
alertParamsExpression: React.FunctionComponent<any>;
defaultActionMessage?: string;
defaultActionGroup?: string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking this would belong nicely next to actionGroups on the server side? here: https://github.com/elastic/kibana/blob/master/x-pack/plugins/alerting/server/types.ts#L66. Then we return the defaultActionGroup with the /types API. Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. I will update the PR the way you proposed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make it optional? And then the same logic to return the first one, if not specified? Probably makes sense to do that, as long as we can do it in one place; we shouldn't repeat that default calculation on the client, if we can.

}

export interface IErrorObject {
Expand Down