From 1e3cc715449a8f2ea5bb9a0e115a82e5ee1ba4b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daphn=C3=A9=20Popin?= Date: Tue, 16 Jul 2024 14:44:35 +0200 Subject: [PATCH] Builders have access to admin list on Connections page (#6240) * Builders have access to admin list on Connections page * Do not reuse MembersList, we want a simpler design * clean --- front/lib/swr.ts | 15 ++++ front/package-lock.json | 8 +- front/package.json | 2 +- front/pages/api/w/[wId]/members/index.ts | 28 ++++--- .../w/[wId]/builder/data-sources/managed.tsx | 73 ++++++++++++++++++- 5 files changed, 107 insertions(+), 19 deletions(-) diff --git a/front/lib/swr.ts b/front/lib/swr.ts index c2e628e4eb492..f5cfd81c4d275 100644 --- a/front/lib/swr.ts +++ b/front/lib/swr.ts @@ -317,6 +317,21 @@ export function useMembers(owner: WorkspaceType) { }; } +export function useAdmins(owner: WorkspaceType) { + const membersFetcher: Fetcher = fetcher; + const { data, error, mutate } = useSWRWithDefaults( + `/api/w/${owner.sId}/members?role=admin`, + membersFetcher + ); + + return { + admins: useMemo(() => (data ? data.members : []), [data]), + isAdminsLoading: !error && !data, + iAdminsError: error, + mutateMembers: mutate, + }; +} + export function useWorkspaceInvitations(owner: WorkspaceType) { const workspaceInvitationsFetcher: Fetcher = fetcher; diff --git a/front/package-lock.json b/front/package-lock.json index 37516fa29d9d5..b7774a41a2e17 100644 --- a/front/package-lock.json +++ b/front/package-lock.json @@ -9,7 +9,7 @@ "@amplitude/analytics-browser": "^2.5.2", "@amplitude/analytics-node": "^1.3.5", "@auth0/nextjs-auth0": "^3.5.0", - "@dust-tt/sparkle": "^0.2.190", + "@dust-tt/sparkle": "^0.2.191", "@dust-tt/types": "file:../types", "@emoji-mart/data": "^1.1.2", "@emoji-mart/react": "^1.1.1", @@ -10734,9 +10734,9 @@ "license": "Apache-2.0" }, "node_modules/@dust-tt/sparkle": { - "version": "0.2.190", - "resolved": "https://registry.npmjs.org/@dust-tt/sparkle/-/sparkle-0.2.190.tgz", - "integrity": "sha512-ErmlgHpflKFujCnzscMi1WRoHImVAPNR8rEdSCXoecpaDlOO4fYcthEj3EvYPq74enxkG3vdMOQt2asRfrFdQg==", + "version": "0.2.191", + "resolved": "https://registry.npmjs.org/@dust-tt/sparkle/-/sparkle-0.2.191.tgz", + "integrity": "sha512-3KMfAidH2/gyEUu5tRqzGUchdhEq/lek/yehVb3iq4T3FkSoFNRqjEZf1jjpNtXMcysILBJRkSzvzR6BfNCRzQ==", "dependencies": { "@emoji-mart/data": "^1.1.2", "@emoji-mart/react": "^1.1.1", diff --git a/front/package.json b/front/package.json index b195cd11d1531..e83a8119cfa89 100644 --- a/front/package.json +++ b/front/package.json @@ -21,7 +21,7 @@ "@amplitude/analytics-browser": "^2.5.2", "@amplitude/analytics-node": "^1.3.5", "@auth0/nextjs-auth0": "^3.5.0", - "@dust-tt/sparkle": "^0.2.190", + "@dust-tt/sparkle": "^0.2.191", "@dust-tt/types": "file:../types", "@emoji-mart/data": "^1.1.2", "@emoji-mart/react": "^1.1.1", diff --git a/front/pages/api/w/[wId]/members/index.ts b/front/pages/api/w/[wId]/members/index.ts index d28df93fae8df..d68826dda6eea 100644 --- a/front/pages/api/w/[wId]/members/index.ts +++ b/front/pages/api/w/[wId]/members/index.ts @@ -18,19 +18,25 @@ async function handler( res: NextApiResponse>, auth: Authenticator ): Promise { - if (!auth.isAdmin()) { - return apiError(req, res, { - status_code: 403, - api_error: { - type: "workspace_auth_error", - message: - "Only users that are `admins` for the current workspace can see memberships or modify it.", - }, - }); - } - switch (req.method) { case "GET": + if (auth.isBuilder() && req.query.role && req.query.role === "admin") { + const members = await getMembers(auth, { roles: ["admin"] }); + res.status(200).json({ members }); + return; + } + + if (!auth.isAdmin()) { + return apiError(req, res, { + status_code: 403, + api_error: { + type: "workspace_auth_error", + message: + "Only users that are `admins` for the current workspace can see memberships or modify it.", + }, + }); + } + const members = await getMembers(auth); res.status(200).json({ members }); diff --git a/front/pages/w/[wId]/builder/data-sources/managed.tsx b/front/pages/w/[wId]/builder/data-sources/managed.tsx index 37895b69af2e3..6344284e4379f 100644 --- a/front/pages/w/[wId]/builder/data-sources/managed.tsx +++ b/front/pages/w/[wId]/builder/data-sources/managed.tsx @@ -1,4 +1,5 @@ import { + Avatar, BookOpenIcon, Button, Chip, @@ -6,6 +7,7 @@ import { Cog6ToothIcon, ContentMessage, ContextItem, + Hoverable, InformationCircleIcon, Modal, Page, @@ -36,6 +38,7 @@ import { buildConnectionId } from "@app/lib/connector_connection_id"; import { CONNECTOR_CONFIGURATIONS } from "@app/lib/connector_providers"; import { githubAuth } from "@app/lib/github_auth"; import { withDefaultUserAuthRequirements } from "@app/lib/iam/session"; +import { useAdmins } from "@app/lib/swr"; import { timeAgoFrom } from "@app/lib/utils"; import logger from "@app/logger/logger"; import type { PostManagedDataSourceRequestBody } from "@app/pages/api/w/[wId]/data_sources/managed"; @@ -404,6 +407,9 @@ export default function DataSourcesView({ const [showConfirmConnection, setShowConfirmConnection] = useState(null); + const [showAdminsModal, setShowAdminsModal] = useState(false); + const { admins, isAdminsLoading } = useAdmins(owner); + const handleEnableManagedDataSource = async ( provider: ConnectorProvider, suffix: string | null @@ -520,6 +526,60 @@ export default function DataSourcesView({ current: "data_sources_managed", })} > + {!isAdmin && ( + setShowAdminsModal(false)} + hasChanged={false} + variant="side-sm" + > +
+ + {isAdminsLoading ? ( +
+
+ +
+
+
Loading...
+
+
+
+ ) : ( +
+ {admins.map((admin) => { + return ( +
+
+ +
+
+
+ {admin.fullName} +
+
+ {admin.email} +
+
+
+ ); + })} +
+ )} +
+
+ )} {showConfirmConnection && ( - {owner.role !== "admin" && ( - - Only Admins can activate and manage Connections. + {!isAdmin && ( + + Workspace administrators control access to connections for + all members.{" "} + setShowAdminsModal(true)} + > + View the list of administrators here. + )}