diff --git a/keep-ui/app/(keep)/alerts/alert-assign-ticket-modal.tsx b/keep-ui/app/(keep)/alerts/alert-assign-ticket-modal.tsx index 8b71690b83..0a2bda5343 100644 --- a/keep-ui/app/(keep)/alerts/alert-assign-ticket-modal.tsx +++ b/keep-ui/app/(keep)/alerts/alert-assign-ticket-modal.tsx @@ -1,12 +1,13 @@ import React, { useState } from "react"; import Select, { components } from "react-select"; -import { Button, TextInput, Text } from "@tremor/react"; +import { Button, TextInput, Text, Icon } from "@tremor/react"; import { PlusIcon } from "@heroicons/react/20/solid"; import { useForm, Controller, SubmitHandler } from "react-hook-form"; import { Providers } from "../providers/providers"; import { AlertDto } from "./models"; import Modal from "@/components/ui/Modal"; import { useApi } from "@/shared/lib/hooks/useApi"; +import { QuestionMarkCircleIcon } from "@heroicons/react/24/outline"; interface AlertAssignTicketModalProps { handleClose: () => void; @@ -41,12 +42,18 @@ const AlertAssignTicketModal = ({ const { handleSubmit, control, + reset, formState: { errors, isSubmitting }, } = useForm(); // if this modal should not be open, do nothing if (!alert) return null; + const handleModalClose = () => { + reset(); + handleClose(); + }; + const onSubmit: SubmitHandler = async (data) => { try { // build the formData @@ -60,7 +67,7 @@ const AlertAssignTicketModal = ({ }; const response = await api.post(`/alerts/enrich`, requestData); alert.ticket_url = data.ticket_url; - handleClose(); + handleModalClose(); } catch (error) { // Handle unexpected error console.error("An unexpected error occurred"); @@ -147,7 +154,7 @@ const AlertAssignTicketModal = ({ return ( @@ -155,9 +162,16 @@ const AlertAssignTicketModal = ({ {ticketingProviders.length > 0 ? (
- +
+ + +
Assign Ticket
); diff --git a/keep-ui/app/(keep)/alerts/models.tsx b/keep-ui/app/(keep)/alerts/models.tsx index 0b95617815..a7bbfb5d56 100644 --- a/keep-ui/app/(keep)/alerts/models.tsx +++ b/keep-ui/app/(keep)/alerts/models.tsx @@ -106,6 +106,7 @@ export interface AlertToWorkflowExecution { | "error" | "providers_not_configured"; workflow_started: Date; + event_id: string; } export const AlertKnownKeys = [ diff --git a/keep-ui/package-lock.json b/keep-ui/package-lock.json index 0f8c9a397d..88b3516a53 100644 --- a/keep-ui/package-lock.json +++ b/keep-ui/package-lock.json @@ -62,7 +62,7 @@ "postcss-nested": "^6.0.1", "postcss-selector-parser": "^6.0.12", "postcss-value-parser": "^4.2.0", - "posthog-js": "^1.194.2", + "posthog-js": "^1.200.1", "posthog-node": "^3.1.1", "pusher-js": "^8.3.0", "react": "^18.3.1", @@ -16832,9 +16832,9 @@ } }, "node_modules/posthog-js": { - "version": "1.194.2", - "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.194.2.tgz", - "integrity": "sha512-UVFVvx6iJMEjHo+N/HmPDK4zjkVY8m+G13jTQmvHMtByfyn/fH6JhOz/ph+gtmvXPI03130y1qrwwgPIZ3ty8A==", + "version": "1.200.1", + "resolved": "https://registry.npmjs.org/posthog-js/-/posthog-js-1.200.1.tgz", + "integrity": "sha512-Ktm2Fa6La67imiZXNwXvFnhkoFae3KhGvjI2TUnElxWF3Sr5mvi5/IMT2fLc5pns89cKsCr+n52Q5E6OxpqBxw==", "dependencies": { "core-js": "^3.38.1", "fflate": "^0.4.8", diff --git a/keep-ui/package.json b/keep-ui/package.json index f4c052f2f8..7e2e17d737 100644 --- a/keep-ui/package.json +++ b/keep-ui/package.json @@ -63,7 +63,7 @@ "postcss-nested": "^6.0.1", "postcss-selector-parser": "^6.0.12", "postcss-value-parser": "^4.2.0", - "posthog-js": "^1.194.2", + "posthog-js": "^1.200.1", "posthog-node": "^3.1.1", "pusher-js": "^8.3.0", "react": "^18.3.1", diff --git a/keep/api/api.py b/keep/api/api.py index fb2b3845b2..c87d84a8fe 100644 --- a/keep/api/api.py +++ b/keep/api/api.py @@ -95,13 +95,12 @@ def no_redirect_request(self, method, url, **kwargs): async def check_pending_tasks(background_tasks: set): while True: events_in_queue = len(background_tasks) - if events_in_queue > 0: - logger.info( - f"{events_in_queue} background tasks pending", - extra={ - "pending_tasks": events_in_queue, - }, - ) + logger.info( + f"{events_in_queue} background tasks pending", + extra={ + "pending_tasks": events_in_queue, + }, + ) await asyncio.sleep(1) @@ -195,6 +194,7 @@ async def lifespan(app: FastAPI): background_tasks = set() # if debug tasks are enabled, create a task to check for pending tasks if KEEP_DEBUG_TASKS: + logger.info("Starting background task to check for pending tasks") asyncio.create_task(check_pending_tasks(background_tasks)) # Startup diff --git a/keep/api/models/workflow.py b/keep/api/models/workflow.py index 49e0a2b8eb..3d534662ec 100644 --- a/keep/api/models/workflow.py +++ b/keep/api/models/workflow.py @@ -101,6 +101,7 @@ class WorkflowToAlertExecutionDTO(BaseModel): alert_fingerprint: str workflow_status: str workflow_started: datetime + event_id: str | None class WorkflowExecutionDTO(BaseModel): diff --git a/keep/api/routes/workflows.py b/keep/api/routes/workflows.py index 77771a32bd..b313650fe2 100644 --- a/keep/api/routes/workflows.py +++ b/keep/api/routes/workflows.py @@ -342,6 +342,33 @@ async def create_workflow( ) +@router.get("/executions", description="Get workflow executions by alert fingerprint") +def get_workflow_executions_by_alert_fingerprint( + authenticated_entity: AuthenticatedEntity = Depends( + IdentityManagerFactory.get_auth_verifier(["read:workflows"]) + ), + session: Session = Depends(get_session), +) -> list[WorkflowToAlertExecutionDTO]: + with tracer.start_as_current_span("get_workflow_executions_by_alert_fingerprint"): + latest_workflow_to_alert_executions = ( + get_last_workflow_workflow_to_alert_executions( + session=session, tenant_id=authenticated_entity.tenant_id + ) + ) + + return [ + WorkflowToAlertExecutionDTO( + workflow_id=workflow_execution.workflow_execution.workflow_id, + workflow_execution_id=workflow_execution.workflow_execution_id, + alert_fingerprint=workflow_execution.alert_fingerprint, + workflow_status=workflow_execution.workflow_execution.status, + workflow_started=workflow_execution.workflow_execution.started, + event_id=workflow_execution.event_id, + ) + for workflow_execution in latest_workflow_to_alert_executions + ] + + @router.post( "/json", description="Create or update a workflow", @@ -540,32 +567,6 @@ def get_workflow_by_id( raise HTTPException(status_code=500, detail="Error fetching workflow meta data") -@router.get("/executions", description="Get workflow executions by alert fingerprint") -def get_workflow_executions_by_alert_fingerprint( - authenticated_entity: AuthenticatedEntity = Depends( - IdentityManagerFactory.get_auth_verifier(["read:workflows"]) - ), - session: Session = Depends(get_session), -) -> list[WorkflowToAlertExecutionDTO]: - with tracer.start_as_current_span("get_workflow_executions_by_alert_fingerprint"): - latest_workflow_to_alert_executions = ( - get_last_workflow_workflow_to_alert_executions( - session=session, tenant_id=authenticated_entity.tenant_id - ) - ) - - return [ - WorkflowToAlertExecutionDTO( - workflow_id=workflow_execution.workflow_execution.workflow_id, - workflow_execution_id=workflow_execution.workflow_execution_id, - alert_fingerprint=workflow_execution.alert_fingerprint, - workflow_status=workflow_execution.workflow_execution.status, - workflow_started=workflow_execution.workflow_execution.started, - ) - for workflow_execution in latest_workflow_to_alert_executions - ] - - @router.get("/{workflow_id}/runs", description="Get workflow executions by ID") def get_workflow_runs_by_id( workflow_id: str,