in x-pack/solutions/observability/plugins/slo/public/pages/slo_details/components/header_control.tsx [36:395]
export function HeaderControl({ slo }: Props) {
const { services } = useKibana();
const {
application: { navigateToUrl, capabilities },
http: { basePath },
triggersActionsUi: { ruleTypeRegistry, actionTypeRegistry },
} = services;
const hasApmReadCapabilities = capabilities.apm.show;
const { data: permissions } = usePermissions();
const { triggerAction } = useActionModal();
const {
isDeletingSlo,
isResettingSlo,
isEnablingSlo,
isDisablingSlo,
removeDeleteQueryParam,
removeResetQueryParam,
removeEnableQueryParam,
removeDisableQueryParam,
} = useGetQueryParams();
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const [isRuleFlyoutVisible, setRuleFlyoutVisibility] = useState<boolean>(false);
const [isEditRuleFlyoutOpen, setIsEditRuleFlyoutOpen] = useState(false);
const { data: rulesBySlo, refetchRules } = useFetchRulesForSlo({
sloIds: [slo.id],
});
const rules = rulesBySlo?.[slo.id] ?? [];
const handleActionsClick = () => setIsPopoverOpen((value) => !value);
const closePopover = () => setIsPopoverOpen(false);
const navigate = useCallback(
(url: string) => setTimeout(() => navigateToUrl(url)),
[navigateToUrl]
);
useEffect(() => {
if (isDeletingSlo) {
triggerAction({
type: 'delete',
item: slo,
onConfirm: () => {
navigate(basePath.prepend(paths.slos));
},
});
removeDeleteQueryParam();
}
if (isResettingSlo) {
triggerAction({ type: 'reset', item: slo });
removeResetQueryParam();
}
if (isEnablingSlo) {
triggerAction({ type: 'enable', item: slo });
removeEnableQueryParam();
}
if (isDisablingSlo) {
triggerAction({ type: 'disable', item: slo });
removeDisableQueryParam();
}
});
const onCloseRuleFlyout = () => {
setRuleFlyoutVisibility(false);
};
const handleOpenRuleFlyout = () => {
closePopover();
setRuleFlyoutVisibility(true);
};
const {
handleNavigateToRules,
sloEditUrl,
remoteDeleteUrl,
remoteResetUrl,
remoteEnableUrl,
remoteDisableUrl,
} = useSloActions({
slo,
rules,
setIsEditRuleFlyoutOpen,
setIsActionsPopoverOpen: setIsPopoverOpen,
});
const handleNavigateToApm = () => {
const url = convertSliApmParamsToApmAppDeeplinkUrl(slo);
if (url) {
navigateToUrl(basePath.prepend(url));
}
};
const handleClone = () => {
triggerAction({ type: 'clone', item: slo });
};
const handleDelete = () => {
if (!!remoteDeleteUrl) {
window.open(remoteDeleteUrl, '_blank');
} else {
triggerAction({
type: 'delete',
item: slo,
onConfirm: () => {
navigate(basePath.prepend(paths.slos));
setIsPopoverOpen(false);
},
});
removeDeleteQueryParam();
}
};
const handleReset = () => {
if (!!remoteResetUrl) {
window.open(remoteResetUrl, '_blank');
} else {
triggerAction({
type: 'reset',
item: slo,
onConfirm: () => {
setIsPopoverOpen(false);
},
});
removeResetQueryParam();
}
};
const handleEnable = () => {
if (!!remoteEnableUrl) {
window.open(remoteEnableUrl, '_blank');
} else {
triggerAction({
type: 'enable',
item: slo,
onConfirm: () => {
setIsPopoverOpen(false);
},
});
removeEnableQueryParam();
}
};
const handleDisable = () => {
if (!!remoteDisableUrl) {
window.open(remoteDisableUrl, '_blank');
} else {
triggerAction({
type: 'disable',
item: slo,
onConfirm: () => {
setIsPopoverOpen(false);
},
});
removeDisableQueryParam();
}
};
const isRemote = !!slo?.remote;
const hasUndefinedRemoteKibanaUrl = !!slo?.remote && slo?.remote?.kibanaUrl === '';
const showRemoteLinkIcon = isRemote ? (
<EuiIcon
type="popout"
size="s"
css={{
marginLeft: '10px',
}}
/>
) : null;
return (
<>
<EuiPopover
data-test-subj="sloDetailsHeaderControlPopover"
button={
<EuiButton
data-test-subj="o11yHeaderControlActionsButton"
fill
iconSide="right"
iconType="arrowDown"
iconSize="s"
onClick={handleActionsClick}
>
{i18n.translate('xpack.slo.sloDetails.headerControl.actions', {
defaultMessage: 'Actions',
})}
</EuiButton>
}
isOpen={isPopoverOpen}
closePopover={closePopover}
>
<EuiContextMenuPanel
size="m"
items={[
<EuiContextMenuItem
key="edit"
disabled={!permissions?.hasAllWriteRequested || hasUndefinedRemoteKibanaUrl}
icon="pencil"
href={sloEditUrl}
target={isRemote ? '_blank' : undefined}
toolTipContent={
hasUndefinedRemoteKibanaUrl ? NOT_AVAILABLE_FOR_UNDEFINED_REMOTE_KIBANA_URL : ''
}
data-test-subj="sloDetailsHeaderControlPopoverEdit"
>
{i18n.translate('xpack.slo.sloDetails.headerControl.edit', {
defaultMessage: 'Edit',
})}
{showRemoteLinkIcon}
</EuiContextMenuItem>,
<EuiContextMenuItem
key="createBurnRateRule"
disabled={!permissions?.hasAllWriteRequested || isRemote}
icon="bell"
onClick={handleOpenRuleFlyout}
data-test-subj="sloDetailsHeaderControlPopoverCreateRule"
toolTipContent={isRemote ? NOT_AVAILABLE_FOR_REMOTE : ''}
>
{i18n.translate('xpack.slo.sloDetails.headerControl.createBurnRateRule', {
defaultMessage: 'Create new alert rule',
})}
</EuiContextMenuItem>,
<EuiContextMenuItem
key="manageRules"
disabled={!permissions?.hasAllWriteRequested || hasUndefinedRemoteKibanaUrl}
icon="gear"
onClick={handleNavigateToRules}
data-test-subj="sloDetailsHeaderControlPopoverManageRules"
toolTipContent={
hasUndefinedRemoteKibanaUrl ? NOT_AVAILABLE_FOR_UNDEFINED_REMOTE_KIBANA_URL : ''
}
>
{i18n.translate('xpack.slo.sloDetails.headerControl.manageRules', {
defaultMessage: 'Manage burn rate {count, plural, one {rule} other {rules}}',
values: { count: rules.length },
})}
{showRemoteLinkIcon}
</EuiContextMenuItem>,
]
.concat(
!!slo && isApmIndicatorType(slo.indicator) ? (
<EuiContextMenuItem
key="exploreInApm"
icon="bullseye"
disabled={!hasApmReadCapabilities || isRemote}
onClick={handleNavigateToApm}
data-test-subj="sloDetailsHeaderControlPopoverExploreInApm"
toolTipContent={isRemote ? NOT_AVAILABLE_FOR_REMOTE : ''}
>
{i18n.translate('xpack.slo.sloDetails.headerControl.exploreInApm', {
defaultMessage: 'Service details',
})}
</EuiContextMenuItem>
) : (
[]
)
)
.concat(
slo.enabled ? (
<EuiContextMenuItem
key="disable"
icon="stop"
disabled={!permissions?.hasAllWriteRequested || hasUndefinedRemoteKibanaUrl}
onClick={handleDisable}
toolTipContent={
hasUndefinedRemoteKibanaUrl ? NOT_AVAILABLE_FOR_UNDEFINED_REMOTE_KIBANA_URL : ''
}
data-test-subj="sloActionsDisable"
>
{i18n.translate('xpack.slo.item.actions.disable', { defaultMessage: 'Disable' })}
{showRemoteLinkIcon}
</EuiContextMenuItem>
) : (
<EuiContextMenuItem
key="enable"
icon="play"
disabled={!permissions?.hasAllWriteRequested || hasUndefinedRemoteKibanaUrl}
onClick={handleEnable}
toolTipContent={
hasUndefinedRemoteKibanaUrl ? NOT_AVAILABLE_FOR_UNDEFINED_REMOTE_KIBANA_URL : ''
}
data-test-subj="sloActionsEnable"
>
{i18n.translate('xpack.slo.item.actions.enable', { defaultMessage: 'Enable' })}
{showRemoteLinkIcon}
</EuiContextMenuItem>
),
<EuiContextMenuItem
key="clone"
disabled={!permissions?.hasAllWriteRequested || hasUndefinedRemoteKibanaUrl}
icon="copy"
onClick={handleClone}
data-test-subj="sloDetailsHeaderControlPopoverClone"
toolTipContent={
hasUndefinedRemoteKibanaUrl ? NOT_AVAILABLE_FOR_UNDEFINED_REMOTE_KIBANA_URL : ''
}
>
{i18n.translate('xpack.slo.slo.item.actions.clone', {
defaultMessage: 'Clone',
})}
{showRemoteLinkIcon}
</EuiContextMenuItem>,
<EuiContextMenuItem
key="delete"
icon="trash"
disabled={!permissions?.hasAllWriteRequested || hasUndefinedRemoteKibanaUrl}
onClick={handleDelete}
data-test-subj="sloDetailsHeaderControlPopoverDelete"
toolTipContent={
hasUndefinedRemoteKibanaUrl ? NOT_AVAILABLE_FOR_UNDEFINED_REMOTE_KIBANA_URL : ''
}
>
{i18n.translate('xpack.slo.slo.item.actions.delete', {
defaultMessage: 'Delete',
})}
{showRemoteLinkIcon}
</EuiContextMenuItem>,
<EuiContextMenuItem
key="reset"
icon="refresh"
disabled={!permissions?.hasAllWriteRequested || hasUndefinedRemoteKibanaUrl}
onClick={handleReset}
data-test-subj="sloDetailsHeaderControlPopoverReset"
toolTipContent={
hasUndefinedRemoteKibanaUrl ? NOT_AVAILABLE_FOR_UNDEFINED_REMOTE_KIBANA_URL : ''
}
>
{i18n.translate('xpack.slo.slo.item.actions.reset', {
defaultMessage: 'Reset',
})}
{showRemoteLinkIcon}
</EuiContextMenuItem>
)}
/>
</EuiPopover>
<EditBurnRateRuleFlyout
rule={rules?.[0]}
isEditRuleFlyoutOpen={isEditRuleFlyoutOpen}
setIsEditRuleFlyoutOpen={setIsEditRuleFlyoutOpen}
refetchRules={refetchRules}
/>
{isRuleFlyoutVisible ? (
<RuleFormFlyout
plugins={{ ...services, actionTypeRegistry, ruleTypeRegistry }}
consumer={sloFeatureId}
ruleTypeId={SLO_BURN_RATE_RULE_TYPE_ID}
onCancel={onCloseRuleFlyout}
onSubmit={onCloseRuleFlyout}
initialValues={{ name: `${slo.name} burn rate`, params: { sloId: slo.id } }}
shouldUseRuleProducer
/>
) : null}
</>
);
}