Skip to content

Commit abb4d05

Browse files
authored
feat: migrate remaining admin UI components to ConnectRPC (#1285)
1 parent 5452f92 commit abb4d05

File tree

25 files changed

+463
-9300
lines changed

25 files changed

+463
-9300
lines changed

ui/src/api/frontier.ts

Lines changed: 0 additions & 8845 deletions
This file was deleted.

ui/src/api/index.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

ui/src/components/assign-role.tsx

Lines changed: 47 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,26 @@ import {
1010
import { useCallback } from "react";
1111
import type {
1212
SearchOrganizationUsersResponse_OrganizationUser,
13+
Role,
14+
Policy,
1315
} from "@raystack/proton/frontier";
14-
import type { V1Beta1Role } from "~/api/frontier";
15-
import { api } from "~/api";
16+
import {
17+
FrontierService,
18+
FrontierServiceQueries,
19+
ListPoliciesRequestSchema,
20+
DeletePolicyRequestSchema,
21+
CreatePolicyRequestSchema,
22+
} from "@raystack/proton/frontier";
23+
import { create } from "@bufbuild/protobuf";
24+
import { useMutation, useTransport } from "@connectrpc/connect-query";
25+
import { createClient } from "@connectrpc/connect";
1626
import { useForm } from "react-hook-form";
1727
import { zodResolver } from "@hookform/resolvers/zod";
1828
import { z } from "zod";
1929

2030
interface AssignRoleProps {
2131
organizationId: string;
22-
roles: V1Beta1Role[];
32+
roles: Role[];
2333
user?: SearchOrganizationUsersResponse_OrganizationUser;
2434
onRoleUpdate: () => void;
2535
onClose: () => void;
@@ -40,6 +50,8 @@ export const AssignRole = ({
4050
onRoleUpdate,
4151
onClose,
4252
}: AssignRoleProps) => {
53+
const transport = useTransport();
54+
4355
const {
4456
handleSubmit,
4557
watch,
@@ -52,6 +64,14 @@ export const AssignRole = ({
5264
resolver: zodResolver(formSchema),
5365
});
5466

67+
const { mutateAsync: deletePolicy } = useMutation(
68+
FrontierServiceQueries.deletePolicy,
69+
);
70+
71+
const { mutateAsync: createPolicy } = useMutation(
72+
FrontierServiceQueries.createPolicy,
73+
);
74+
5575
const roleIds = watch("roleIds");
5676

5777
function onCheckedChange(value: boolean | string, roleId?: string) {
@@ -77,18 +97,23 @@ export const AssignRole = ({
7797

7898
const onSubmit = async (data: FormData) => {
7999
try {
80-
const policiesResp = await api?.frontierServiceListPolicies({
81-
org_id: organizationId,
82-
user_id: user?.id,
83-
});
84-
const policies = policiesResp?.data?.policies || [];
100+
const client = createClient(FrontierService, transport);
101+
const policiesResp = await client.listPolicies(
102+
create(ListPoliciesRequestSchema, {
103+
orgId: organizationId,
104+
userId: user?.id,
105+
}),
106+
);
107+
const policies = policiesResp.policies || [];
85108

86109
const removedRolesPolicies = policies.filter(
87-
(policy) => !(policy.role_id && data.roleIds.has(policy.role_id)),
110+
(policy: Policy) => !(policy.roleId && data.roleIds.has(policy.roleId)),
88111
);
89112
await Promise.all(
90-
removedRolesPolicies.map((policy) =>
91-
api?.frontierServiceDeletePolicy(policy.id as string),
113+
removedRolesPolicies.map((policy: Policy) =>
114+
deletePolicy(
115+
create(DeletePolicyRequestSchema, { id: policy.id || "" }),
116+
),
92117
),
93118
);
94119

@@ -97,12 +122,16 @@ export const AssignRole = ({
97122

98123
const assignedRolesArr = Array.from(data.roleIds);
99124
await Promise.all(
100-
assignedRolesArr.map((role_id) =>
101-
api?.frontierServiceCreatePolicy({
102-
role_id,
103-
resource: resource,
104-
principal: principal,
105-
}),
125+
assignedRolesArr.map((roleId) =>
126+
createPolicy(
127+
create(CreatePolicyRequestSchema, {
128+
body: {
129+
roleId,
130+
resource,
131+
principal,
132+
},
133+
}),
134+
),
106135
),
107136
);
108137

@@ -112,6 +141,7 @@ export const AssignRole = ({
112141

113142
toast.success("Role assigned successfully");
114143
} catch (error) {
144+
toast.error("Failed to assign role");
115145
console.error(error);
116146
}
117147
};
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { V1Beta1Role } from "@raystack/frontier";
1+
import type { Role } from "@raystack/proton/frontier";
22

33
export type RoleDetailsTypes = {
4-
role: V1Beta1Role;
4+
role: Role;
55
};

ui/src/containers/users.create/index.tsx

Lines changed: 0 additions & 103 deletions
This file was deleted.

ui/src/hooks/useRQL.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import React, { useCallback, useState } from "react";
22
import type { DataTableQuery } from "@raystack/apsara";
33
import type {
4-
V1Beta1RQLQueryPaginationResponse,
5-
V1Beta1RQLQueryGroupResponse,
6-
} from "~/api/frontier";
4+
RQLQueryGroupResponse,
5+
RQLQueryPaginationResponse
6+
} from "@raystack/proton/frontier"
77
import { useDebounceCallback } from "usehooks-ts";
88

99
export interface GroupCountMap {
@@ -17,7 +17,7 @@ interface UseRQLResponse<T> {
1717
query: DataTableQuery;
1818
setQuery: (query: DataTableQuery) => void;
1919
fetchData: (apiQuery?: DataTableQuery) => Promise<void>;
20-
group?: V1Beta1RQLQueryGroupResponse;
20+
group?: RQLQueryGroupResponse;
2121
hasMore: boolean;
2222
onTableQueryChange: (query: DataTableQuery) => void;
2323
groupCountMap: GroupCountMap;
@@ -78,13 +78,13 @@ export const useRQL = <T extends unknown>({
7878

7979
const pagination = response[
8080
"pagination"
81-
] as V1Beta1RQLQueryPaginationResponse;
81+
] as RQLQueryPaginationResponse;
8282
if (pagination) {
8383
setNextOffset(pagination?.offset || 0);
8484
}
8585
setHasMore(items.length !== 0 && items.length === limit);
8686

87-
const group = response.group as V1Beta1RQLQueryGroupResponse;
87+
const group = response.group as RQLQueryGroupResponse;
8888
// Handle group counts
8989
if (group?.data && group.name) {
9090
const groupCount = group.data.reduce(

ui/src/pages/audit-logs/list/navbar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { useQueryClient } from "@tanstack/react-query";
99
import { AUDIT_LOG_QUERY_KEY } from "../util";
1010
import { RQLExportRequest } from "@raystack/proton/frontier";
1111

12-
const adminClient = clients.admin({ useBinary: false });
12+
const adminClient = clients.admin({ useBinary: true });
1313

1414
interface NavbarProps {
1515
searchQuery?: string;

ui/src/pages/organizations/details/members/remove-member.tsx

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
import { useState } from "react";
21
import type { SearchOrganizationUsersResponse_OrganizationUser } from "@raystack/proton/frontier";
3-
2+
import {
3+
FrontierServiceQueries,
4+
RemoveOrganizationUserRequestSchema,
5+
} from "@raystack/proton/frontier";
6+
import { create } from "@bufbuild/protobuf";
7+
import { useMutation } from "@connectrpc/connect-query";
48
import { Button, Dialog, Flex, Text, toast } from "@raystack/apsara";
5-
import { api } from "~/api";
6-
import { AxiosError } from "axios";
9+
import { ConnectError } from "@connectrpc/connect";
710

811
interface RemoveMemberProps {
912
organizationId: string;
@@ -18,29 +21,30 @@ export const RemoveMember = ({
1821
onRemove,
1922
onClose,
2023
}: RemoveMemberProps) => {
21-
const [isSubmitting, setIsSubmitting] = useState(false);
24+
const { mutateAsync: removeOrganizationUser, isPending } = useMutation(
25+
FrontierServiceQueries.removeOrganizationUser,
26+
);
2227

2328
async function onSubmit() {
2429
try {
2530
if (!user) return;
26-
setIsSubmitting(true);
27-
await api?.frontierServiceRemoveOrganizationUser(
28-
organizationId,
29-
user?.id || "",
31+
await removeOrganizationUser(
32+
create(RemoveOrganizationUserRequestSchema, {
33+
id: organizationId,
34+
userId: user?.id || "",
35+
}),
3036
);
3137
if (onRemove) {
3238
onRemove(user);
3339
}
3440
toast.success("Member removed successfully");
3541
} catch (error) {
3642
const message =
37-
error instanceof AxiosError
38-
? error.response?.data?.message
43+
error instanceof ConnectError
44+
? error.message
3945
: "Unknown error";
4046
toast.error(`Failed to remove member: ${message}`);
4147
console.error(error);
42-
} finally {
43-
setIsSubmitting(false);
4448
}
4549
}
4650

@@ -78,7 +82,7 @@ export const RemoveMember = ({
7882
type="submit"
7983
data-test-id="remove-member-submit-button"
8084
color="danger"
81-
loading={isSubmitting}
85+
loading={isPending}
8286
loaderText="Removing..."
8387
onClick={onSubmit}
8488
>

ui/src/pages/organizations/details/projects/columns.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { RenameProjectDialog } from "./rename-project";
2424
import { useState } from "react";
2525
import type React from "react";
2626
import Skeleton from "react-loading-skeleton";
27-
import { useAddProjectMembers } from "./useAddProjectMembers";
27+
import { useAddProjectMembers } from "./use-add-project-members";
2828

2929
const DropdownLoader = () => {
3030
return (

ui/src/pages/organizations/details/projects/index.tsx

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ export function OrganizationProjectssPage() {
106106
isFetchingNextPage,
107107
fetchNextPage,
108108
hasNextPage,
109+
refetch: refetchOrgProjects,
109110
isError,
110111
} = useInfiniteQuery(
111112
AdminServiceQueries.searchOrganizationProjects,
@@ -139,15 +140,8 @@ export function OrganizationProjectssPage() {
139140
function handleProjectUpdate(
140141
project: SearchOrganizationProjectsResponse_OrganizationProject,
141142
) {
142-
// Invalidate and refetch the query instead of manually updating
143-
queryClient.invalidateQueries({
144-
queryKey: createConnectQueryKey({
145-
schema: AdminServiceQueries.searchOrganizationProjects,
146-
transport,
147-
input: {},
148-
cardinality: "infinite",
149-
}),
150-
});
143+
// Refetch the query instead of manually updating
144+
refetchOrgProjects();
151145
}
152146

153147
useEffect(() => {
@@ -168,6 +162,7 @@ export function OrganizationProjectssPage() {
168162
}
169163

170164
function handleMemberDialogClose() {
165+
refetchOrgProjects();
171166
setMemberDialogConfig({
172167
projectId: "",
173168
open: false,

0 commit comments

Comments
 (0)