diff --git a/frontend/src/hooks/api/organizationIdentity/index.tsx b/frontend/src/hooks/api/organizationIdentity/index.tsx new file mode 100644 index 000000000..9da529579 --- /dev/null +++ b/frontend/src/hooks/api/organizationIdentity/index.tsx @@ -0,0 +1,15 @@ +export { + useCreateOrganizationIdentity, + useDeleteOrganizationIdentity, + useUpdateOrganizationIdentity +} from "./mutations"; +export { organizationIdentityQuery } from "./queries"; +export type { + TCreateOrganizationIdentityDTO, + TDeleteOrganizationIdentityDTO, + TGetOrganizationIdentityByIdDTO, + TListOrganizationIdentitiesDTO, + TMetadata, + TOrganizationIdentity, + TUpdateOrganizationIdentityDTO +} from "./types"; diff --git a/frontend/src/hooks/api/organizationIdentity/mutations.tsx b/frontend/src/hooks/api/organizationIdentity/mutations.tsx new file mode 100644 index 000000000..510f440fb --- /dev/null +++ b/frontend/src/hooks/api/organizationIdentity/mutations.tsx @@ -0,0 +1,58 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; + +import { apiRequest } from "@app/config/request"; + +import { organizationIdentityQuery } from "./queries"; +import { + TCreateOrganizationIdentityDTO, + TDeleteOrganizationIdentityDTO, + TOrganizationIdentity, + TUpdateOrganizationIdentityDTO +} from "./types"; + +export const useCreateOrganizationIdentity = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: async (dto: TCreateOrganizationIdentityDTO) => { + const { data } = await apiRequest.post<{ identity: TOrganizationIdentity }>( + "/api/v1/organization/identities", + dto + ); + return data; + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: organizationIdentityQuery.allKey() }); + } + }); +}; + +export const useUpdateOrganizationIdentity = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: async ({ identityId, ...updates }: TUpdateOrganizationIdentityDTO) => { + const { data } = await apiRequest.patch<{ identity: TOrganizationIdentity }>( + `/api/v1/organization/identities/${identityId}`, + updates + ); + return data; + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: organizationIdentityQuery.allKey() }); + } + }); +}; + +export const useDeleteOrganizationIdentity = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: async ({ identityId }: TDeleteOrganizationIdentityDTO) => { + const { data } = await apiRequest.delete<{ identity: TOrganizationIdentity }>( + `/api/v1/organization/identities/${identityId}` + ); + return data; + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: organizationIdentityQuery.allKey() }); + } + }); +}; diff --git a/frontend/src/hooks/api/organizationIdentity/queries.tsx b/frontend/src/hooks/api/organizationIdentity/queries.tsx new file mode 100644 index 000000000..17bfc5816 --- /dev/null +++ b/frontend/src/hooks/api/organizationIdentity/queries.tsx @@ -0,0 +1,44 @@ +import { queryOptions } from "@tanstack/react-query"; + +import { apiRequest } from "@app/config/request"; + +import { + TGetOrganizationIdentityByIdDTO, + TListOrganizationIdentitiesDTO, + TOrganizationIdentity +} from "./types"; + +export const organizationIdentityQuery = { + allKey: () => ["organization-identities"] as const, + getByIdKey: (params: TGetOrganizationIdentityByIdDTO) => + [...organizationIdentityQuery.allKey(), "by-id", params] as const, + listKey: (params?: TListOrganizationIdentitiesDTO) => + [...organizationIdentityQuery.allKey(), "list", params] as const, + getById: (params: TGetOrganizationIdentityByIdDTO) => + queryOptions({ + queryKey: organizationIdentityQuery.getByIdKey(params), + queryFn: async () => { + const { data } = await apiRequest.get<{ identity: TOrganizationIdentity }>( + `/api/v1/organization/identities/${params.identityId}` + ); + return data.identity; + } + }), + list: (params: TListOrganizationIdentitiesDTO = {}) => + queryOptions({ + queryKey: organizationIdentityQuery.listKey(params), + queryFn: async () => { + const { data } = await apiRequest.get<{ + identities: TOrganizationIdentity[]; + totalCount: number; + }>("/api/v1/organization/identities", { + params: { + offset: params.offset, + limit: params.limit, + search: params.search + } + }); + return data; + } + }) +}; diff --git a/frontend/src/hooks/api/organizationIdentity/types.ts b/frontend/src/hooks/api/organizationIdentity/types.ts new file mode 100644 index 000000000..7ae60feb7 --- /dev/null +++ b/frontend/src/hooks/api/organizationIdentity/types.ts @@ -0,0 +1,43 @@ +export type TMetadata = { + key: string; + value: string; +}; + +export type TOrganizationIdentity = { + id: string; + name: string; + orgId: string; + projectId: string | null; + createdAt: string; + updatedAt: string; + hasDeleteProtection: boolean; + authMethods?: string[]; + metadata?: TMetadata[]; +}; + +export type TCreateOrganizationIdentityDTO = { + name: string; + hasDeleteProtection?: boolean; + metadata?: TMetadata[]; +}; + +export type TUpdateOrganizationIdentityDTO = { + identityId: string; + name?: string; + hasDeleteProtection?: boolean; + metadata?: TMetadata[]; +}; + +export type TGetOrganizationIdentityByIdDTO = { + identityId: string; +}; + +export type TListOrganizationIdentitiesDTO = { + offset?: number; + limit?: number; + search?: string; +}; + +export type TDeleteOrganizationIdentityDTO = { + identityId: string; +}; diff --git a/frontend/src/hooks/api/projectIdentity/index.tsx b/frontend/src/hooks/api/projectIdentity/index.tsx new file mode 100644 index 000000000..e4810ccd0 --- /dev/null +++ b/frontend/src/hooks/api/projectIdentity/index.tsx @@ -0,0 +1,15 @@ +export { + useCreateProjectIdentity, + useDeleteProjectIdentity, + useUpdateProjectIdentity +} from "./mutations"; +export { projectIdentityQuery } from "./queries"; +export type { + TCreateProjectIdentityDTO, + TDeleteProjectIdentityDTO, + TGetProjectIdentityByIdDTO, + TListProjectIdentitiesDTO, + TProjectIdentity, + TProjectIdentityMetadata, + TUpdateProjectIdentityDTO +} from "./types"; diff --git a/frontend/src/hooks/api/projectIdentity/mutations.tsx b/frontend/src/hooks/api/projectIdentity/mutations.tsx new file mode 100644 index 000000000..9df4d9256 --- /dev/null +++ b/frontend/src/hooks/api/projectIdentity/mutations.tsx @@ -0,0 +1,58 @@ +import { useMutation, useQueryClient } from "@tanstack/react-query"; + +import { apiRequest } from "@app/config/request"; + +import { projectIdentityQuery } from "./queries"; +import { + TCreateProjectIdentityDTO, + TDeleteProjectIdentityDTO, + TProjectIdentity, + TUpdateProjectIdentityDTO +} from "./types"; + +export const useCreateProjectIdentity = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: async ({ projectId, ...dto }: TCreateProjectIdentityDTO) => { + const { data } = await apiRequest.post<{ identity: TProjectIdentity }>( + `/api/v1/projects/${projectId}/identities`, + dto + ); + return data; + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: projectIdentityQuery.allKey() }); + } + }); +}; + +export const useUpdateProjectIdentity = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: async ({ projectId, identityId, ...updates }: TUpdateProjectIdentityDTO) => { + const { data } = await apiRequest.patch<{ identity: TProjectIdentity }>( + `/api/v1/projects/${projectId}/identities/${identityId}`, + updates + ); + return data; + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: projectIdentityQuery.allKey() }); + } + }); +}; + +export const useDeleteProjectIdentity = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: async ({ projectId, identityId }: TDeleteProjectIdentityDTO) => { + const { data } = await apiRequest.delete<{ identity: TProjectIdentity }>( + `/api/v1/projects/${projectId}/identities/${identityId}` + ); + return data; + }, + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: projectIdentityQuery.allKey() }); + } + }); +}; diff --git a/frontend/src/hooks/api/projectIdentity/queries.tsx b/frontend/src/hooks/api/projectIdentity/queries.tsx new file mode 100644 index 000000000..16fafbc55 --- /dev/null +++ b/frontend/src/hooks/api/projectIdentity/queries.tsx @@ -0,0 +1,44 @@ +import { queryOptions } from "@tanstack/react-query"; + +import { apiRequest } from "@app/config/request"; + +import { + TGetProjectIdentityByIdDTO, + TListProjectIdentitiesDTO, + TProjectIdentity +} from "./types"; + +export const projectIdentityQuery = { + allKey: () => ["project-identities"] as const, + getByIdKey: (params: TGetProjectIdentityByIdDTO) => + [...projectIdentityQuery.allKey(), "by-id", params] as const, + listKey: (params: TListProjectIdentitiesDTO) => + [...projectIdentityQuery.allKey(), "list", params] as const, + getById: (params: TGetProjectIdentityByIdDTO) => + queryOptions({ + queryKey: projectIdentityQuery.getByIdKey(params), + queryFn: async () => { + const { data } = await apiRequest.get<{ identity: TProjectIdentity }>( + `/api/v1/projects/${params.projectId}/identities/${params.identityId}` + ); + return data.identity; + } + }), + list: (params: TListProjectIdentitiesDTO) => + queryOptions({ + queryKey: projectIdentityQuery.listKey(params), + queryFn: async () => { + const { data } = await apiRequest.get<{ + identities: TProjectIdentity[]; + totalCount: number; + }>(`/api/v1/projects/${params.projectId}/identities`, { + params: { + offset: params.offset, + limit: params.limit, + search: params.search + } + }); + return data; + } + }) +}; diff --git a/frontend/src/hooks/api/projectIdentity/types.ts b/frontend/src/hooks/api/projectIdentity/types.ts new file mode 100644 index 000000000..278b85e8a --- /dev/null +++ b/frontend/src/hooks/api/projectIdentity/types.ts @@ -0,0 +1,54 @@ +export type TProjectIdentityMetadata = { + key: string; + value: string; + id: string; +}; + +export type TProjectIdentity = { + id: string; + name: string; + orgId: string; + projectId: string | null; + createdAt: string; + updatedAt: string; + hasDeleteProtection: boolean; + metadata?: TProjectIdentityMetadata[]; +}; + +export type TCreateProjectIdentityDTO = { + projectId: string; + name: string; + hasDeleteProtection?: boolean; + metadata?: Array<{ + key: string; + value: string; + }>; +}; + +export type TUpdateProjectIdentityDTO = { + projectId: string; + identityId: string; + name?: string; + hasDeleteProtection?: boolean; + metadata?: Array<{ + key: string; + value: string; + }>; +}; + +export type TGetProjectIdentityByIdDTO = { + projectId: string; + identityId: string; +}; + +export type TListProjectIdentitiesDTO = { + projectId: string; + offset?: number; + limit?: number; + search?: string; +}; + +export type TDeleteProjectIdentityDTO = { + projectId: string; + identityId: string; +};