Skip to content

Commit

Permalink
feat(escalation_policies): Add FE hooks for Rotation Schedule and Esc…
Browse files Browse the repository at this point in the history
…alation policy endpoints (#76393)

Adds FE hooks for the following endpoints: 

* GET `organization/<org>/escalation-policies/`
* PUT `organization/<org>/escalation-policies/`
* GET `organization/<org>/escalation-policies/<policy_id>`
* DELETE `organization/<org>/escalation-policies/<policy_id>`
* GET `organization/<org>/rotation-schedules/`
* PUT `organization/<org>/rotation-schedules/`
* GET `organization/<org>/rotation-schedules/<policy_id>`
* DELETE `organization/<org>/rotation-schedules/<policy_id>`
  • Loading branch information
MichaelSun48 committed Aug 20, 2024
1 parent 8d911e0 commit 69ecc4c
Show file tree
Hide file tree
Showing 8 changed files with 431 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import {
getApiQueryData,
setApiQueryData,
useMutation,
type UseMutationOptions,
useQueryClient,
} from 'sentry/utils/queryClient';
import type RequestError from 'sentry/utils/requestError/requestError';
import useApi from 'sentry/utils/useApi';
import {
type EscalationPolicy,
makeFetchEscalationPoliciesKey,
} from 'sentry/views/escalationPolicies/queries/useFetchEscalationPolicies';

type DeleteEscalationPolicyParams = {
escalationPolicyId: string;
orgSlug: string;
};

type DeleteEscalationPolicyResponse = unknown;

type DeleteEscalationPolicyContext = {
previousEscalationPolicies?: EscalationPolicy[];
};

export const useDeleteEscalationPolicy = (
options: Omit<
UseMutationOptions<
DeleteEscalationPolicyResponse,
RequestError,
DeleteEscalationPolicyParams,
DeleteEscalationPolicyContext
>,
'mutationFn'
> = {}
) => {
const api = useApi();
const queryClient = useQueryClient();

return useMutation<
DeleteEscalationPolicyResponse,
RequestError,
DeleteEscalationPolicyParams,
DeleteEscalationPolicyContext
>({
...options,
mutationFn: ({orgSlug, escalationPolicyId}: DeleteEscalationPolicyParams) =>
api.requestPromise(
`/organizations/${orgSlug}/escalation-policies/${escalationPolicyId}/`,
{
method: 'DELETE',
}
),
onMutate: async variables => {
// Delete escalation policy from FE cache
await queryClient.cancelQueries(
makeFetchEscalationPoliciesKey({orgSlug: variables.orgSlug})
);

const previousEscalationPolicies = getApiQueryData<EscalationPolicy[]>(
queryClient,
makeFetchEscalationPoliciesKey({orgSlug: variables.orgSlug})
);

setApiQueryData(
queryClient,
makeFetchEscalationPoliciesKey({orgSlug: variables.orgSlug}),
oldData => {
if (!Array.isArray(oldData)) {
return oldData;
}

return oldData.filter(
escalationPolicy => escalationPolicy.id !== variables.escalationPolicyId
);
}
);
options.onMutate?.(variables);

return {previousEscalationPolicies};
},
onError: (error, variables, context) => {
options.onError?.(error, variables, context);
},
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {
getApiQueryData,
setApiQueryData,
useMutation,
type UseMutationOptions,
useQueryClient,
} from 'sentry/utils/queryClient';
import type RequestError from 'sentry/utils/requestError/requestError';
import useApi from 'sentry/utils/useApi';
import {
makeFetchRotationSchedulesKey,
type RotationSchedule,
} from 'sentry/views/escalationPolicies/queries/useFetchRotationSchedules';

type DeleteRotationScheduleParams = {
orgSlug: string;
rotationScheduleId: string;
};

type DeleteRotationScheduleResponse = unknown;

type DeleteRotationScheduleContext = {
previousRotationSchedules?: RotationSchedule[];
};

export const useDeleteRotationSchedule = (
options: Omit<
UseMutationOptions<
DeleteRotationScheduleResponse,
RequestError,
DeleteRotationScheduleParams,
DeleteRotationScheduleContext
>,
'mutationFn'
> = {}
) => {
const api = useApi();
const queryClient = useQueryClient();

return useMutation<
DeleteRotationScheduleResponse,
RequestError,
DeleteRotationScheduleParams,
DeleteRotationScheduleContext
>({
...options,
mutationFn: ({orgSlug, rotationScheduleId}: DeleteRotationScheduleParams) =>
api.requestPromise(
`/organizations/${orgSlug}/rotation-schedules/${rotationScheduleId}/`,
{
method: 'DELETE',
}
),
onMutate: async variables => {
// Delete rotation schedule from FE cache
await queryClient.cancelQueries(
makeFetchRotationSchedulesKey({orgSlug: variables.orgSlug})
);

const previousRotationSchedules = getApiQueryData<RotationSchedule[]>(
queryClient,
makeFetchRotationSchedulesKey({orgSlug: variables.orgSlug})
);

setApiQueryData(
queryClient,
makeFetchRotationSchedulesKey({orgSlug: variables.orgSlug}),
previousRotationSchedules?.filter(
rotationSchedule => rotationSchedule.id !== variables.rotationScheduleId
)
);

return {previousRotationSchedules};
},
onError: (error, variables, context) => {
options.onError?.(error, variables, context);
},
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import {
setApiQueryData,
useMutation,
type UseMutationOptions,
useQueryClient,
} from 'sentry/utils/queryClient';
import type RequestError from 'sentry/utils/requestError/requestError';
import useApi from 'sentry/utils/useApi';
import {
type EscalationPolicy,
makeFetchEscalationPoliciesKey,
} from 'sentry/views/escalationPolicies/queries/useFetchEscalationPolicies';

interface UpdateEscalationPolicyPayload extends Omit<EscalationPolicy, 'id'> {
// If EscalationPolicy id is not provided, a new EscalationPolicy will be created.
id?: string;
}

interface UpdateEscalationPolicyParams {
escalationPolicy: UpdateEscalationPolicyPayload;
orgSlug: string;
}

export const useUpdateEscalationPolicy = (
options: Omit<
UseMutationOptions<EscalationPolicy, RequestError, UpdateEscalationPolicyParams>,
'mutationFn'
> = {}
) => {
const api = useApi();
const queryClient = useQueryClient();

return useMutation<EscalationPolicy, RequestError, UpdateEscalationPolicyParams>({
...options,
mutationFn: ({orgSlug, escalationPolicy}: UpdateEscalationPolicyParams) =>
api.requestPromise(`/organizations/${orgSlug}/escalation-policies/`, {
method: 'PUT',
data: escalationPolicy,
}),
onSuccess: (escalationPolicy, parameters, context) => {
setApiQueryData<EscalationPolicy>(
queryClient,
makeFetchEscalationPoliciesKey({orgSlug: parameters.orgSlug}),
escalationPolicy // Update the cache with the new escalationPolicy
);
options.onSuccess?.(escalationPolicy, parameters, context);
},
onError: (error, variables, context) => {
options.onError?.(error, variables, context);
},
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import {
setApiQueryData,
useMutation,
type UseMutationOptions,
useQueryClient,
} from 'sentry/utils/queryClient';
import type RequestError from 'sentry/utils/requestError/requestError';
import useApi from 'sentry/utils/useApi';
import {
makeFetchRotationSchedulesKey,
type RotationSchedule,
} from 'sentry/views/escalationPolicies/queries/useFetchRotationSchedules';

interface UpdateRotationSchedulePayload extends Omit<RotationSchedule, 'id'> {
id?: string;
}

interface UpdateRotationScheduleParams {
orgSlug: string;
rotationSchedule: UpdateRotationSchedulePayload;
}

export const useUpdateRotationSchedule = (
options: Omit<
UseMutationOptions<RotationSchedule, RequestError, UpdateRotationScheduleParams>,
'mutationFn'
> = {}
) => {
const api = useApi();
const queryClient = useQueryClient();

return useMutation<RotationSchedule, RequestError, UpdateRotationScheduleParams>({
...options,
mutationFn: ({orgSlug, rotationSchedule}: UpdateRotationScheduleParams) =>
api.requestPromise(`/organizations/${orgSlug}/rotation-schedules/`, {
method: 'PUT',
data: rotationSchedule,
}),
onSuccess: (rotationSchedule, parameters, context) => {
setApiQueryData<RotationSchedule>(
queryClient,
makeFetchRotationSchedulesKey({orgSlug: parameters.orgSlug}),
rotationSchedule // Update the cache with the new rotationSchedule
);
options.onSuccess?.(rotationSchedule, parameters, context);
},
onError: (error, variables, context) => {
options.onError?.(error, variables, context);
},
});
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import {
type ApiQueryKey,
useApiQuery,
type UseApiQueryOptions,
} from 'sentry/utils/queryClient';

export interface EscalationPolicy {
description: string;
id: string;
name: string;
organization: string;
repeatNTimes: number;
userId: string;
team?: string;
}

interface FetchEscalationPoliciesParams {
orgSlug: string;
}

interface FetchEscalationPoliciesResponse {
escalationPolicies: EscalationPolicy[];
}

export const makeFetchEscalationPoliciesKey = ({
orgSlug,
}: FetchEscalationPoliciesParams): ApiQueryKey => [
`/organizations/${orgSlug}/escalation-policies/`,
{
query: {},
},
];

export const useFetchEscalationPolicies = (
params: FetchEscalationPoliciesParams,
options: Partial<UseApiQueryOptions<FetchEscalationPoliciesResponse>> = {}
) => {
return useApiQuery<FetchEscalationPoliciesResponse>(
makeFetchEscalationPoliciesKey(params),
{
staleTime: 0,
...options,
}
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {
type ApiQueryKey,
useApiQuery,
type UseApiQueryOptions,
} from 'sentry/utils/queryClient';
import type {EscalationPolicy} from 'sentry/views/escalationPolicies/queries/useFetchEscalationPolicies';

interface FetchEscalationPolicyDetailsParams {
escalationPolicyId: string;
orgSlug: string;
}

interface FetchEscalationPolicyDetailsResponse {
escalationPolicy: EscalationPolicy;
}

export const makeFetchEscalationPoliciesKey = ({
orgSlug,
escalationPolicyId,
}: FetchEscalationPolicyDetailsParams): ApiQueryKey => [
`/organizations/${orgSlug}/escalation-policies/${escalationPolicyId}`,
{
query: {},
},
];

export const useFetchEscalationPolicies = (
params: FetchEscalationPolicyDetailsParams,
options: Partial<UseApiQueryOptions<FetchEscalationPolicyDetailsResponse>> = {}
) => {
return useApiQuery<FetchEscalationPolicyDetailsResponse>(
makeFetchEscalationPoliciesKey(params),
{
staleTime: 0,
...options,
}
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {
type ApiQueryKey,
useApiQuery,
type UseApiQueryOptions,
} from 'sentry/utils/queryClient';
import type {RotationSchedule} from 'sentry/views/escalationPolicies/queries/useFetchRotationSchedules';

interface FetchRotationScheduleDetailsParams {
orgSlug: string;
rotationScheduleId: string;
}

interface FetchRotationScheduleDetailsResponse {
rotationSchedule: RotationSchedule;
}

export const makeFetchRotationScheduleDetailsKey = ({
orgSlug,
rotationScheduleId,
}: FetchRotationScheduleDetailsParams): ApiQueryKey => [
`/organizations/${orgSlug}/rotation-schedules/${rotationScheduleId}`,
{
query: {},
},
];

export const useFetchRotationScheduleDetails = (
params: FetchRotationScheduleDetailsParams,
options: Partial<UseApiQueryOptions<FetchRotationScheduleDetailsResponse>> = {}
) => {
return useApiQuery<FetchRotationScheduleDetailsResponse>(
makeFetchRotationScheduleDetailsKey(params),
{
staleTime: 0,
...options,
}
);
};
Loading

0 comments on commit 69ecc4c

Please sign in to comment.