diff --git a/ui-v2/src/api/deployments/deployments.test.ts b/ui-v2/src/api/deployments/deployments.test.ts index 77fdc6e275149..2a52bb02479f6 100644 --- a/ui-v2/src/api/deployments/deployments.test.ts +++ b/ui-v2/src/api/deployments/deployments.test.ts @@ -12,6 +12,7 @@ import { buildPaginateDeploymentsQuery, queryKeyFactory, useDeleteDeployment, + useDeleteDeploymentSchedule, useUpdateDeploymentSchedule, } from "./index"; @@ -265,4 +266,63 @@ describe("deployments api", () => { ).toEqual([MOCK_UPDATED_SCHEDULE]); }); }); + + describe("useDeleteDeploymentSchedule", () => { + const MOCK_DEPLOYMENT_ID = "deployment-id"; + const MOCK_SCHEDULE_ID = "schedule-id"; + const MOCK_SCHEDULE = { + id: MOCK_SCHEDULE_ID, + created: "2024-01-01T00:00:00.000Z", + updated: "2024-01-01T00:00:00.000Z", + deployment_id: "deployment-id", + schedule: { + interval: 3600.0, + anchor_date: "2024-01-01T00:00:00.000Z", + timezone: "UTC", + }, + active: false, + max_scheduled_runs: null, + }; + const MOCK_DEPLYOMENT = createFakeDeployment({ + id: MOCK_DEPLOYMENT_ID, + schedules: [MOCK_SCHEDULE], + }); + const MOCK_UPDATED_DEPLOYMENT = { + ...MOCK_DEPLYOMENT, + schedules: [], + }; + + it("invalidates cache and fetches updated value", async () => { + const queryClient = new QueryClient(); + // Original cached value + queryClient.setQueryData(queryKeyFactory.all(), [MOCK_DEPLYOMENT]); + + // Updated fetch and cached value + mockFetchDeploymentsAPI([MOCK_UPDATED_DEPLOYMENT]); + + const { result: useListDeploymentsResult } = renderHook( + () => useQuery(buildPaginateDeploymentsQuery()), + { wrapper: createWrapper({ queryClient }) }, + ); + + const { result: useDeleteDeploymentScheduleResult } = renderHook( + useDeleteDeploymentSchedule, + { wrapper: createWrapper({ queryClient }) }, + ); + + act(() => + useDeleteDeploymentScheduleResult.current.deleteDeploymentSchedule({ + deployment_id: MOCK_DEPLOYMENT_ID, + schedule_id: MOCK_SCHEDULE_ID, + }), + ); + + await waitFor(() => + expect(useDeleteDeploymentScheduleResult.current.isSuccess).toBe(true), + ); + expect( + useListDeploymentsResult.current.data?.results[0].schedules, + ).toHaveLength(0); + }); + }); }); diff --git a/ui-v2/src/api/deployments/index.ts b/ui-v2/src/api/deployments/index.ts index da1c75c15cb0e..82d8af641056b 100644 --- a/ui-v2/src/api/deployments/index.ts +++ b/ui-v2/src/api/deployments/index.ts @@ -243,7 +243,7 @@ type UpdateDeploymentSchedule = { } & components["schemas"]["DeploymentScheduleUpdate"]; /** - * Hook for update a deployment's schedule + * Hook for updating a deployment's schedule * * @returns Mutation object for updating a deployment's schedule with loading/error states and trigger function * @@ -251,8 +251,7 @@ type UpdateDeploymentSchedule = { * ```ts * const { updateDeploymentSchedule } = useUpdateDeploymentSchedule(); * - * // Delete a deployment by id - * deleteDeployment({deployment_id, schedule_id, ...body}, { + * updateDeploymentSchedule({deployment_id, schedule_id, ...body}, { * onSuccess: () => { * // Handle successful update * console.log('Deployment schedule updated successfully'); @@ -278,10 +277,48 @@ export const useUpdateDeploymentSchedule = () => { params: { path: { schedule_id, id: deployment_id } }, }), onSettled: () => - queryClient.invalidateQueries({ - queryKey: queryKeyFactory.all(), - }), + queryClient.invalidateQueries({ queryKey: queryKeyFactory.all() }), }); return { updateDeploymentSchedule, ...rest }; }; + +type DeleteDeploymentSchedule = { + deployment_id: string; + schedule_id: string; +}; +/** + * Hook for deleting a deployment's schedule + * + * @returns Mutation object for deleting a deployment's schedule with loading/error states and trigger function + * + * @example + * ```ts + * const { deleteDeploymentSchedule } = useDeleteDeploymentSchedule(); + * + * deleteDeploymentSchedule({deployment_id, schedule_id, ...body}, { + * onSuccess: () => { + * // Handle successful update + * console.log('Deployment schedule deleted successfully'); + * }, + * onError: (error) => { + * // Handle error + * console.error('Failed to delete deployment schedule:', error); + * } + * }); + * ``` + */ +export const useDeleteDeploymentSchedule = () => { + const queryClient = useQueryClient(); + + const { mutate: deleteDeploymentSchedule, ...rest } = useMutation({ + mutationFn: ({ deployment_id, schedule_id }: DeleteDeploymentSchedule) => + getQueryService().DELETE("/deployments/{id}/schedules/{schedule_id}", { + params: { path: { schedule_id, id: deployment_id } }, + }), + onSettled: () => + queryClient.invalidateQueries({ queryKey: queryKeyFactory.lists() }), + }); + + return { deleteDeploymentSchedule, ...rest }; +}; diff --git a/ui-v2/tests/utils/handlers.ts b/ui-v2/tests/utils/handlers.ts index e2bba49baa7bd..16c21f1e7fd05 100644 --- a/ui-v2/tests/utils/handlers.ts +++ b/ui-v2/tests/utils/handlers.ts @@ -43,6 +43,10 @@ const deploymentsHandlers = [ http.patch(buildApiUrl("/deployments/:id/schedules/:schedule_id"), () => { return HttpResponse.json({ status: 204 }); }), + + http.delete(buildApiUrl("/deployments/:id/schedules/:schedule_id"), () => { + return HttpResponse.json({ status: 204 }); + }), ]; const flowHandlers = [