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
71 changes: 14 additions & 57 deletions libs/domains/clusters/feature/src/lib/cluster-card/cluster-card.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { Link, useRouter } from '@tanstack/react-router'
import posthog from 'posthog-js'
import { type Cluster, type ClusterStatus } from 'qovery-typescript-axios'
import { useContext } from 'react'
import { match } from 'ts-pattern'
import { DevopsCopilotContext } from '@qovery/shared/devops-copilot/feature'
import {
AnimatedGradientText,
Badge,
Button,
Icon,
Indicator,
Link as LinkUI,
Expand All @@ -24,20 +20,6 @@ import { ClusterRunningStatusIndicator } from '../cluster-running-status-indicat
import { useClusterRunningStatusSocket } from '../hooks/use-cluster-running-status-socket/use-cluster-running-status-socket'

function Subtitle({ cluster, clusterDeploymentStatus }: { cluster: Cluster; clusterDeploymentStatus?: ClusterStatus }) {
const { setDevopsCopilotOpen, sendMessageRef } = useContext(DevopsCopilotContext)

const handleLaunchDiagnostic = () => {
posthog.capture('ai-copilot-troubleshoot-triggered', {
source: 'cluster-card',
cluster_id: cluster.id,
trigger_reason: 'error',
})

const message = `Why did my cluster deployment fail? (cluster id: ${cluster.id})`
setDevopsCopilotOpen(true)
sendMessageRef?.current?.(message)
}

return match(clusterDeploymentStatus?.status)
.with('DEPLOYMENT_QUEUED', 'DELETE_QUEUED', 'STOP_QUEUED', 'RESTART_QUEUED', (s) => (
<span className="text-ssm font-normal text-neutral-subtle">{upperCaseFirstLetter(s).replace('_', ' ')}...</span>
Expand All @@ -64,46 +46,21 @@ function Subtitle({ cluster, clusterDeploymentStatus }: { cluster: Cluster; clus
</LinkUI>
))
.with('BUILD_ERROR', 'DELETE_ERROR', 'DEPLOYMENT_ERROR', 'STOP_ERROR', 'RESTART_ERROR', () => (
<Tooltip
classNameContent="group rounded-full cursor-pointer pl-3 pr-1.5"
side="bottom"
align="center"
content={
<div
className="flex items-center gap-1.5"
onClick={(e) => {
e.preventDefault()
e.stopPropagation()
handleLaunchDiagnostic()
}}
>
<Icon iconName="sparkles" iconStyle="solid" className="text-brand" />
<span className="text-ssm">Ask for diagnostic</span>
<Button
size="xs"
variant="surface"
iconOnly
radius="full"
className="ml-0.5 group-hover:bg-surface-neutral-componentHover"
>
<Icon iconName="arrow-right" />
</Button>
</div>
}
<LinkUI
to="/organization/$organizationId/cluster/$clusterId/cluster-logs"
params={{
organizationId: cluster.organization.id,
clusterId: cluster.id,
}}
color="red"
underline
size="sm"
className="truncate"
onClick={(e) => e.stopPropagation()}
>
<button
type="button"
onClick={(e) => {
e.preventDefault()
e.stopPropagation()
handleLaunchDiagnostic()
}}
className="flex max-w-max items-center gap-0.5 text-sm font-medium text-negative transition hover:text-negative-hover hover:underline"
>
Last deployment failed
<Icon iconName="arrow-up-right" />
</button>
</Tooltip>
Last deployment failed
<Icon iconName="arrow-up-right" />
</LinkUI>
))
.with('INVALID_CREDENTIALS', () => (
<LinkUI
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,10 @@ describe('ClusterLastDeploymentSection', () => {
screen.getByRole('button', { name: 'Launch diagnostic' }).click()

expect(mockSetDevopsCopilotOpen).toHaveBeenCalledWith(true)
expect(mockSendMessage).toHaveBeenCalledWith('Why did my cluster deployment fail? (deployment id: execution-1)')
expect(mockSendMessage).toHaveBeenCalledWith('Why did my cluster deployment fail? (cluster id: cluster-1)')
expect(posthog.capture).toHaveBeenCalledWith('ai-copilot-troubleshoot-triggered', {
source: 'cluster-last-deployment',
troubleshoot_type: 'cluster',
deployment_id: 'execution-1',
cluster_id: 'cluster-1',
trigger_reason: 'error',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,12 +116,13 @@ export function ClusterLastDeploymentSection({

posthog.capture('ai-copilot-troubleshoot-triggered', {
source: 'cluster-last-deployment',
troubleshoot_type: 'cluster',
deployment_id: clusterStatus.last_execution_id,
cluster_id: clusterId,
trigger_reason: 'error',
})

const message = `Why did my cluster deployment fail?${clusterStatus.last_execution_id ? ` (deployment id: ${clusterStatus.last_execution_id})` : ''}`
const message = `Why did my cluster deployment fail? (cluster id: ${clusterId})`

setDevopsCopilotOpen(true)
sendMessageRef?.current?.(message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export function ClusterHeaderLogs({ cluster, clusterStatus, refScrollSection, da
onClick={() => {
posthog.capture('ai-copilot-troubleshoot-triggered', {
source: 'cluster-logs',
troubleshoot_type: 'cluster',
cluster_id: cluster.id,
})
const message = `Why did my cluster deployment fail? (cluster id: ${cluster.id})`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ const EnvironmentLastDeploymentContent = () => {

posthog.capture('ai-copilot-troubleshoot-triggered', {
source: 'environment-last-deployment',
troubleshoot_type: 'deployment',
deployment_id: lastDeployment.identifier.execution_id,
trigger_reason: 'error',
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ function DeploymentLogsBody({
onClick={() => {
posthog.capture('ai-copilot-troubleshoot-triggered', {
source: 'deployment-logs',
troubleshoot_type: 'deployment',
deployment_id: executionId,
trigger_reason: isCrashLoopDetected ? 'crash-loop' : 'error',
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ function ServiceLastDeploymentContent({ serviceId, serviceType, service }: Servi
const handleLaunchDiagnostic = () => {
posthog.capture('ai-copilot-troubleshoot-triggered', {
source: 'service-last-deployment',
troubleshoot_type: 'deployment',
deployment_id: lastDeployment.identifier.execution_id,
trigger_reason: 'error',
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import clsx from 'clsx'
import { memo } from 'react'
import { Button, Icon, LoaderSpinner, Tooltip, truncateText } from '@qovery/shared/ui'
import { Button, Icon, LoaderSpinner, Tooltip } from '@qovery/shared/ui'
import { type Thread } from '../hooks/use-threads/use-threads'
import { isToday, isWithinLastSevenDays, isWithinLastThirtyDays, isYesterday } from '../utils/date-utils/date-utils'

Expand Down Expand Up @@ -64,13 +64,13 @@ export const DevopsCopilotHistory = ({
<div
onClick={() => setThreadId(thread.id)}
className={clsx(
'cursor-pointer rounded-md p-2 text-sm text-neutral transition-colors hover:bg-surface-neutral-subtle',
'cursor-pointer truncate rounded-md p-2 text-sm text-neutral transition-colors hover:bg-surface-neutral-subtle',
{
'bg-surface-brand-subtle text-brand': threadId === thread.id,
}
)}
>
{thread.title.length >= 28 ? `${truncateText(thread.title, 28)}...` : thread.title}
{thread.title}
</div>
</Tooltip>
))}
Expand All @@ -80,7 +80,7 @@ export const DevopsCopilotHistory = ({

if ((isLoading && threads.length === 0) || error) {
return (
<div className="flex h-full w-80 items-center justify-center border-r border-neutral px-3">
<div className="flex h-full w-64 shrink-0 items-center justify-center border-r border-neutral px-3">
{error ? <span className="text-sm text-negative">{error}</span> : <LoaderSpinner />}
</div>
)
Expand All @@ -89,7 +89,7 @@ export const DevopsCopilotHistory = ({
const groupedThreads = groupThreadsByTimeAgo(threads)

return (
<div className="flex h-full w-80 flex-col justify-between border-r border-neutral">
<div className="flex h-full w-64 shrink-0 flex-col justify-between border-r border-neutral">
<div className="flex h-[45px] justify-between border-b border-neutral py-2 pl-4 pr-2">
<div className="flex w-full items-center justify-between font-bold">
<span className="text-sm text-neutral">History</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ export function DevopsCopilotPanel({ onClose, style }: DevopsCopilotPanelProps)
organizationId={organizationId}
/>
)}
<div className="flex h-full w-full flex-col justify-between">
<div className="flex h-full min-w-0 flex-1 flex-col justify-between">
<Header
threadId={threadId}
threads={threads}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export function Header({
</Badge>
</Tooltip>
</div>
<div className="flex items-center gap-1">
<div className="flex shrink-0 items-center gap-1">
<DropdownMenu.Root>
<DropdownMenu.Trigger asChild>
<span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ describe('DevopsCopilotTroubleshootTrigger', () => {
expect(mockSendMessage).toHaveBeenCalledWith('Why did my deployment fail? (execution id: exec-123)')
expect(posthog.capture).toHaveBeenCalledWith('ai-copilot-troubleshoot-triggered', {
source: 'service-deployment-list',
troubleshoot_type: 'deployment',
deployment_id: 'exec-123',
})
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export function DevopsCopilotTroubleshootTrigger({
const openTroubleshoot = () => {
posthog.capture('ai-copilot-troubleshoot-triggered', {
source,
troubleshoot_type: 'deployment',
deployment_id: deploymentId,
})

Expand Down
Loading