Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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 @@ -4,6 +4,7 @@ import { type PropsWithChildren, type ReactNode, useMemo, useState } from 'react
import { useNavigate } from 'react-router-dom'
import { match } from 'ts-pattern'
import { type AnyService } from '@qovery/domains/services/data-access'
import { useDeploymentStatus } from '@qovery/domains/services/feature'
import {
APPLICATION_MONITORING_ALERTS_URL,
APPLICATION_MONITORING_ALERT_EDIT_URL,
Expand Down Expand Up @@ -101,6 +102,10 @@ export function AlertRulesOverview({
const { openModal, closeModal } = useModal()
const { openModalConfirmation } = useModalConfirmation()
const navigate = useNavigate()
const { data: deploymentStatus } = useDeploymentStatus({
environmentId: service?.environment?.id,
serviceId: service?.id,
})

const { mutate: deleteAlertRule } = useDeleteAlertRule({ organizationId })

Expand Down Expand Up @@ -156,6 +161,13 @@ export function AlertRulesOverview({
[selectedAlertRuleIds.size, selectableAlertRules.length]
)

const canCreateAlerts = useMemo(() => {
return (
deploymentStatus?.service_deployment_status !== undefined &&
deploymentStatus?.service_deployment_status !== 'NEVER_DEPLOYED'
)
}, [deploymentStatus])

const toggleSelectAll = (checked: boolean) => {
if (checked) {
const allIds = new Set(selectableAlertRules.map((alertRule) => alertRule.id))
Expand Down Expand Up @@ -240,10 +252,14 @@ export function AlertRulesOverview({
)}
</p>
{onCreateKeyAlerts && (
<Button size="md" className="gap-1.5" onClick={onCreateKeyAlerts}>
<Icon iconName="plus-large" className="text-xs" />
New alert
</Button>
<Tooltip content="You need to deploy your service to create alerts" disabled={canCreateAlerts}>
<div>
<Button size="md" className="gap-1.5" onClick={onCreateKeyAlerts} disabled={!canCreateAlerts}>
<Icon iconName="plus-large" className="text-xs" />
New alert
</Button>
</div>
</Tooltip>
)}
</div>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export function AlertingCreationFlow({
service?.min_running_instances !== service?.max_running_instances

if (!containerName) return
if (hasPublicPort && !ingressName) return
if (hasPublicPort && !(ingressName || httpRouteName)) return
if (hasAutoscaling && !hpaName) return

try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AlertRuleState } from 'qovery-typescript-axios'
import { renderWithProviders, screen } from '@qovery/shared/util-tests'
import { renderWithProviders, screen, within } from '@qovery/shared/util-tests'
import { ServiceAlerting } from './service-alerting'

const mockUseParams = jest.fn()
Expand All @@ -8,6 +8,7 @@ const mockUseAlertRulesGhosted = jest.fn()
const mockUseDeleteAlertRule = jest.fn()
const mockUseEnvironment = jest.fn()
const mockUseService = jest.fn()
const mockUseDeploymentStatus = jest.fn()

jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
Expand All @@ -32,6 +33,7 @@ jest.mock('../../hooks/use-environment/use-environment', () => ({

jest.mock('@qovery/domains/services/feature', () => ({
useService: (params: unknown) => mockUseService(params),
useDeploymentStatus: (params: unknown) => mockUseDeploymentStatus(params),
}))

describe('ServiceAlerting', () => {
Expand Down Expand Up @@ -93,6 +95,30 @@ describe('ServiceAlerting', () => {
mockUseDeleteAlertRule.mockReturnValue({
mutate: jest.fn(),
})
mockUseDeploymentStatus.mockReturnValue({
data: { service_deployment_status: 'DEPLOYED' },
isFetched: true,
})
Comment thread
rmnbrd marked this conversation as resolved.
})

it('should display tooltip explaining alerts require deployment when service was never deployed', async () => {
mockUseDeploymentStatus.mockReturnValue({
data: { service_deployment_status: 'NEVER_DEPLOYED' },
isFetched: true,
})

const { userEvent } = renderWithProviders(<ServiceAlerting />)

const headerToolbar = screen.getByRole('heading', { name: 'Alert rules' }).parentElement
expect(headerToolbar).toBeInTheDocument()
const newAlertButton = within(headerToolbar as HTMLElement).getByRole('button', { name: /new alert/i })
await userEvent.hover(newAlertButton.parentElement ?? newAlertButton)

expect(
await screen.findByRole('tooltip', {
name: 'You need to deploy your service to create alerts',
})
).toBeInTheDocument()
})

it('should render loader when environment is not loaded', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { type PropsWithChildren } from 'react'
import { type PropsWithChildren, useMemo } from 'react'
import { useParams } from 'react-router-dom'
import { type AnyService } from '@qovery/domains/services/data-access'
import { useService } from '@qovery/domains/services/feature'
import { Button, Chart, Heading, Icon, Section, useModal } from '@qovery/shared/ui'
import { useDeploymentStatus, useService } from '@qovery/domains/services/feature'
import { Button, Chart, Heading, Icon, Section, Tooltip, useModal } from '@qovery/shared/ui'
import { AlertRulesOverview } from '../../alerting/alert-rules-overview/alert-rules-overview'
import { CreateKeyAlertsModal } from '../../alerting/create-key-alerts-modal/create-key-alerts-modal'
import { useEnvironment } from '../../hooks/use-environment/use-environment'
Expand All @@ -15,6 +15,10 @@ interface ServiceAlertingContentProps extends PropsWithChildren {

function ServiceAlertingContent({ organizationId, projectId, service, children }: ServiceAlertingContentProps) {
const { openModal, closeModal } = useModal()
const { data: deploymentStatus } = useDeploymentStatus({
environmentId: service?.environment?.id,
serviceId: service?.id,
})

const createKeyAlertsModal = () => {
openModal({
Expand All @@ -32,15 +36,33 @@ function ServiceAlertingContent({ organizationId, projectId, service, children }
})
}

const canCreateAlerts = useMemo(() => {
return (
deploymentStatus?.service_deployment_status !== undefined &&
deploymentStatus?.service_deployment_status !== 'NEVER_DEPLOYED'
)
}, [deploymentStatus])
Comment thread
rmnbrd marked this conversation as resolved.

return (
<Section className="w-full px-8 py-6 pb-20">
<div className="mb-8 border-b border-neutral-250">
<div className="flex w-full items-center justify-between pb-5">
<Heading level={1}>Alert rules</Heading>
<Button variant="outline" color="neutral" size="md" className="gap-1.5" onClick={createKeyAlertsModal}>
<Icon iconName="circle-plus" iconStyle="regular" className="text-xs" />
New alert
</Button>
<Tooltip content="You need to deploy your service to create alerts" disabled={canCreateAlerts}>
<div>
<Button
variant="outline"
color="neutral"
size="md"
className="gap-1.5"
onClick={createKeyAlertsModal}
disabled={!canCreateAlerts}
>
<Icon iconName="circle-plus" iconStyle="regular" className="text-xs" />
New alert
</Button>
</div>
</Tooltip>
</div>
</div>
<AlertRulesOverview organizationId={organizationId} service={service} onCreateKeyAlerts={createKeyAlertsModal}>
Expand Down
Loading