feat(instance-management): organizations overview and control

This commit is contained in:
Daniel Hougaard
2025-05-30 19:28:05 +04:00
parent 78c4a591a9
commit 29561d37e9
11 changed files with 681 additions and 26 deletions
+2 -16
View File
@@ -1,16 +1,2 @@
export {
useAdminDeleteUser,
useAdminGrantServerAdminAccess,
useAdminRemoveIdentitySuperAdminAccess,
useCreateAdminUser,
useInvalidateCache,
useRemoveUserServerAdminAccess,
useUpdateServerConfig,
useUpdateServerEncryptionStrategy
} from "./mutation";
export {
useAdminGetUsers,
useGetAdminIntegrationsConfig,
useGetServerConfig,
useGetServerRootKmsEncryptionDetails
} from "./queries";
export * from "./mutation";
export * from "./queries";
+35
View File
@@ -63,6 +63,41 @@ export const useAdminDeleteUser = () => {
queryClient.invalidateQueries({
queryKey: [adminStandaloneKeys.getUsers]
});
queryClient.invalidateQueries({ queryKey: adminStandaloneKeys.getOrganizations });
}
});
};
export const useAdminDeleteOrganizationMembership = () => {
const queryClient = useQueryClient();
return useMutation<object, object, { organizationId: string; membershipId: string }>({
mutationFn: async ({ organizationId, membershipId }) => {
await apiRequest.delete(
`/api/v1/admin/organization-management/organizations/${organizationId}/memberships/${membershipId}`
);
return {};
},
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: [adminStandaloneKeys.getOrganizations]
});
}
});
};
export const useAdminDeleteOrganization = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: async (organizationId: string) => {
await apiRequest.delete(
`/api/v1/admin/organization-management/organizations/${organizationId}`
);
},
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: [adminStandaloneKeys.getOrganizations]
});
}
});
};
+27
View File
@@ -6,8 +6,10 @@ import { Identity } from "@app/hooks/api/identities/types";
import { User } from "../types";
import {
AdminGetIdentitiesFilters,
AdminGetOrganizationsFilters,
AdminGetUsersFilters,
AdminIntegrationsConfig,
OrganizationWithProjects,
TGetInvalidatingCacheStatus,
TGetServerRootKmsEncryptionDetails,
TServerConfig
@@ -15,12 +17,15 @@ import {
export const adminStandaloneKeys = {
getUsers: "get-users",
getOrganizations: "get-organizations",
getIdentities: "get-identities"
};
export const adminQueryKeys = {
serverConfig: () => ["server-config"] as const,
getUsers: (filters: AdminGetUsersFilters) => [adminStandaloneKeys.getUsers, { filters }] as const,
getOrganizations: (filters: AdminGetOrganizationsFilters) =>
[adminStandaloneKeys.getOrganizations, { filters }] as const,
getIdentities: (filters: AdminGetIdentitiesFilters) =>
[adminStandaloneKeys.getIdentities, { filters }] as const,
getAdminSlackConfig: () => ["admin-slack-config"] as const,
@@ -34,6 +39,28 @@ export const fetchServerConfig = async () => {
return data.config;
};
export const useAdminGetOrganizations = (filters: AdminGetOrganizationsFilters) => {
return useInfiniteQuery({
initialPageParam: 0,
queryKey: adminQueryKeys.getOrganizations(filters),
queryFn: async ({ pageParam }) => {
const { data } = await apiRequest.get<{ organizations: OrganizationWithProjects[] }>(
"/api/v1/admin/organization-management/organizations",
{
params: {
...filters,
offset: pageParam
}
}
);
return data.organizations;
},
getNextPageParam: (lastPage, pages) =>
lastPage.length !== 0 ? pages.length * filters.limit : undefined
});
};
export const useGetServerConfig = ({
options = {}
}: {
+28
View File
@@ -1,3 +1,5 @@
import { Organization } from "../types";
export enum LoginMethod {
EMAIL = "email",
GOOGLE = "google",
@@ -8,6 +10,27 @@ export enum LoginMethod {
OIDC = "oidc"
}
export type OrganizationWithProjects = Organization & {
members: {
user: {
id: string;
email: string | null;
username: string;
firstName: string | null;
lastName: string | null;
};
membershipId: string;
role: string;
roleId: string | null;
}[];
projects: {
name: string;
id: string;
slug: string;
createdAt: string;
}[];
};
export type TServerConfig = {
initialized: boolean;
allowSignUp: boolean;
@@ -51,6 +74,11 @@ export type TCreateAdminUserDTO = {
salt: string;
};
export type AdminGetOrganizationsFilters = {
limit: number;
searchTerm: string;
};
export type AdminGetUsersFilters = {
limit: number;
searchTerm: string;