From bd80549b174a1757c12e655d797892f3950fd0d5 Mon Sep 17 00:00:00 2001 From: Shreyag02 Date: Tue, 21 Jul 2026 15:09:13 +0530 Subject: [PATCH 1/8] fix(admin/org): hide create action during search and fix navbar height Hide the "New Organization" button (and its separator) while search is active so the listing navbar stays uncluttered, and align the navbar height with the org-details navbar (48px) instead of 56px. --- .../views/organizations/list/list.module.css | 2 +- .../admin/views/organizations/list/navbar.tsx | 24 +++++++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/web/sdk/admin/views/organizations/list/list.module.css b/web/sdk/admin/views/organizations/list/list.module.css index 8306a41b5..945c41533 100644 --- a/web/sdk/admin/views/organizations/list/list.module.css +++ b/web/sdk/admin/views/organizations/list/list.module.css @@ -5,7 +5,7 @@ display: flex; align-items: center; justify-content: space-between; - min-height: var(--rs-space-12); + min-height: var(--rs-space-11); } .table { diff --git a/web/sdk/admin/views/organizations/list/navbar.tsx b/web/sdk/admin/views/organizations/list/navbar.tsx index 400aec865..b451f6869 100644 --- a/web/sdk/admin/views/organizations/list/navbar.tsx +++ b/web/sdk/admin/views/organizations/list/navbar.tsx @@ -64,16 +64,20 @@ export const OrganizationsNavabar = ({ - - + {!showSearch ? ( + <> + + + + ) : null} {showSearch ? ( Date: Tue, 21 Jul 2026 15:14:48 +0530 Subject: [PATCH 2/8] fix(admin/org): strip scope prefix from member role titles Display org member roles as "Owner", "Member", "Admin" instead of "Organization Owner" etc. in the Role column, via a formatRoleTitle helper. --- web/sdk/admin/utils/helper.ts | 7 +++++++ .../admin/views/organizations/details/members/columns.tsx | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/web/sdk/admin/utils/helper.ts b/web/sdk/admin/utils/helper.ts index c8b97df75..90bd9c197 100644 --- a/web/sdk/admin/utils/helper.ts +++ b/web/sdk/admin/utils/helper.ts @@ -41,6 +41,13 @@ export function randomSuffix(length = 4): string { return out; } +// Role titles come prefixed with the scope (e.g. "Organization Owner"). +// For display we only want the bare title: "Owner", "Member", "Admin". +export function formatRoleTitle(title?: string): string { + if (!title) return ''; + return title.replace(/^organization\s+/i, ''); +} + export function convertBillingAddressToString(address?: { line1?: string; line2?: string; diff --git a/web/sdk/admin/views/organizations/details/members/columns.tsx b/web/sdk/admin/views/organizations/details/members/columns.tsx index 366bf2a03..94ef49dd7 100644 --- a/web/sdk/admin/views/organizations/details/members/columns.tsx +++ b/web/sdk/admin/views/organizations/details/members/columns.tsx @@ -22,6 +22,7 @@ import { TimeStamp, timestampToDate, } from "../../../../utils/connect-timestamp"; +import { formatRoleTitle } from "../../../../utils/helper"; const MemberStates = { enabled: "Active", @@ -51,7 +52,7 @@ export const getColumns = ({ const roleMap = roles.reduce( (acc, role) => { const id = role?.id ?? ""; - acc[id] = role.title || ""; + acc[id] = formatRoleTitle(role.title); return acc; }, {} as Record, From 5501a551c9549d5af9134db0f8f5d8b066210a1e Mon Sep 17 00:00:00 2001 From: Shreyag02 Date: Tue, 21 Jul 2026 15:16:27 +0530 Subject: [PATCH 3/8] fix(admin/org): remove underline on the View Invoice link --- .../admin/views/organizations/details/invoices/columns.tsx | 7 ++++++- .../organizations/details/invoices/invoices.module.css | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/web/sdk/admin/views/organizations/details/invoices/columns.tsx b/web/sdk/admin/views/organizations/details/invoices/columns.tsx index c24cf9dda..d4b7ec06a 100644 --- a/web/sdk/admin/views/organizations/details/invoices/columns.tsx +++ b/web/sdk/admin/views/organizations/details/invoices/columns.tsx @@ -86,7 +86,12 @@ export const getColumns = ({ cell: ({ getValue }) => { const value = getValue() as string; return ( - + View Invoice ); diff --git a/web/sdk/admin/views/organizations/details/invoices/invoices.module.css b/web/sdk/admin/views/organizations/details/invoices/invoices.module.css index 3fc52a098..af9b8c2cc 100644 --- a/web/sdk/admin/views/organizations/details/invoices/invoices.module.css +++ b/web/sdk/admin/views/organizations/details/invoices/invoices.module.css @@ -26,3 +26,7 @@ .first-column { padding-left: var(--rs-space-7); } + +.invoice-link { + text-decoration: none; +} From a55df10e0d792404e3c8d44c0608e06039b18465 Mon Sep 17 00:00:00 2001 From: Shreyag02 Date: Tue, 21 Jul 2026 16:09:27 +0530 Subject: [PATCH 4/8] fix(admin/org): disable project add-member for single-member orgs Disable the "Add member" project action when the org has only one member, since there is no one else to search for and add. Also keep the project row highlighted while its action menu is open. --- .../organizations/details/projects/columns.tsx | 15 ++++++++++++++- .../details/projects/projects.module.css | 5 +++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/web/sdk/admin/views/organizations/details/projects/columns.tsx b/web/sdk/admin/views/organizations/details/projects/columns.tsx index fe58440c6..250704709 100644 --- a/web/sdk/admin/views/organizations/details/projects/columns.tsx +++ b/web/sdk/admin/views/organizations/details/projects/columns.tsx @@ -50,6 +50,7 @@ interface AddMemberDropdownProps { eligibleMembers: User[]; isLoading: boolean; setSearchQuery: (query: string) => void; + disabled?: boolean; } function AddMemberDropdown({ @@ -57,6 +58,7 @@ function AddMemberDropdown({ eligibleMembers, isLoading, setSearchQuery, + disabled, }: AddMemberDropdownProps) { const t = useTerminology(); return ( @@ -65,7 +67,7 @@ function AddMemberDropdown({ autocompleteMode="manual" onInputValueChange={setSearchQuery} > - + Add {t.member({ case: "lower" })} @@ -101,12 +103,14 @@ function ProjectActionsContent({ project, handleProjectUpdate, handleRenameOptionOpen, + canAddMember, }: { project: SearchOrganizationProjectsResponse_OrganizationProject; handleProjectUpdate: ( project: SearchOrganizationProjectsResponse_OrganizationProject, ) => void; handleRenameOptionOpen: () => void; + canAddMember: boolean; }) { const t = useTerminology(); const handleRenameOptionClick = (e: React.MouseEvent) => { @@ -135,6 +139,7 @@ function ProjectActionsContent({ eligibleMembers={eligibleMembers} isLoading={isLoading} setSearchQuery={setSearchQuery} + disabled={!canAddMember} /> void; + canAddMember: boolean; }) { const [open, setOpen] = useState(false); @@ -198,6 +205,7 @@ function ProjectActions({ project={project} handleProjectUpdate={handleProjectUpdate} handleRenameOptionOpen={handleRenameOptionOpen} + canAddMember={canAddMember} /> @@ -221,6 +229,10 @@ export const getColumns = ({ SearchOrganizationProjectsResponse_OrganizationProject, unknown >[] => { + // Adding a project member requires searching org members. With a single org + // member there is no one to add, so the action is disabled until more members + // are invited. + const canAddMember = Object.keys(orgMembersMap).length > 1; return [ { accessorKey: "title", @@ -300,6 +312,7 @@ export const getColumns = ({ ); }, diff --git a/web/sdk/admin/views/organizations/details/projects/projects.module.css b/web/sdk/admin/views/organizations/details/projects/projects.module.css index 98114a4f8..813f1e8c0 100644 --- a/web/sdk/admin/views/organizations/details/projects/projects.module.css +++ b/web/sdk/admin/views/organizations/details/projects/projects.module.css @@ -35,6 +35,11 @@ width: var(--rs-space-12); } +/* Keep the row highlighted while its action menu is open. */ +.table-wrapper tr:has([data-test-id="admin-project-actions"][data-popup-open]) { + background: var(--rs-color-background-base-primary-hover); +} + .flex1 { flex: 1; } From 4cbaf1c5cb8ee5f0c3b94b80534dcc5da3591be4 Mon Sep 17 00:00:00 2001 From: Shreyag02 Date: Tue, 21 Jul 2026 16:44:27 +0530 Subject: [PATCH 5/8] fix(admin/org): show zero state for empty detail tabs Distinguish an empty tab (no data at all) from a no-match search result: add a dedicated zero state to the members, projects, invoices, tokens and API tabs via the DataTable zeroState prop, so the "no matches for that keyword" copy only appears when a search or filter is active. Table headers are hidden in both states by the DataTable. --- .../organizations/details/apis/apis.module.css | 8 ++++++++ .../views/organizations/details/apis/index.tsx | 15 +++++++++++++++ .../organizations/details/invoices/index.tsx | 15 +++++++++++++++ .../details/invoices/invoices.module.css | 8 ++++++++ .../organizations/details/members/index.tsx | 15 +++++++++++++++ .../details/members/members.module.css | 8 ++++++++ .../organizations/details/projects/index.tsx | 16 ++++++++++++++++ .../details/projects/projects.module.css | 8 ++++++++ .../views/organizations/details/tokens/index.tsx | 15 +++++++++++++++ .../details/tokens/tokens.module.css | 8 ++++++++ 10 files changed, 116 insertions(+) diff --git a/web/sdk/admin/views/organizations/details/apis/apis.module.css b/web/sdk/admin/views/organizations/details/apis/apis.module.css index ecc31ad20..54401a3e1 100644 --- a/web/sdk/admin/views/organizations/details/apis/apis.module.css +++ b/web/sdk/admin/views/organizations/details/apis/apis.module.css @@ -7,6 +7,14 @@ text-wrap: auto; } +.zero-state-container { + padding: var(--rs-space-10); +} + +.zero-state { + padding-top: var(--rs-space-17); +} + .table { width: 100%; table-layout: fixed; diff --git a/web/sdk/admin/views/organizations/details/apis/index.tsx b/web/sdk/admin/views/organizations/details/apis/index.tsx index 0d2b00738..bffbf467a 100644 --- a/web/sdk/admin/views/organizations/details/apis/index.tsx +++ b/web/sdk/admin/views/organizations/details/apis/index.tsx @@ -36,6 +36,20 @@ const NoCredentials = () => { ); }; +const ZeroState = () => { + return ( +
+ } + heading="API Credentials" + subHeading="Service accounts provide programmatic API access on behalf of this organization." + /> +
+ ); +}; + const ErrorState = () => { return ( : } + zeroState={} classNames={{ root: styles["table-wrapper"], table: styles["table"], diff --git a/web/sdk/admin/views/organizations/details/invoices/index.tsx b/web/sdk/admin/views/organizations/details/invoices/index.tsx index 76eff1d09..24cc11bf2 100644 --- a/web/sdk/admin/views/organizations/details/invoices/index.tsx +++ b/web/sdk/admin/views/organizations/details/invoices/index.tsx @@ -70,6 +70,20 @@ const NoInvoices = () => { ); }; +const ZeroState = () => { + return ( +
+ } + heading="Invoices" + subHeading="Invoices generated for this organization's billing activity will appear here." + /> +
+ ); +}; + const ErrorState = () => { const t = useTerminology(); return ( @@ -180,6 +194,7 @@ export function OrganizationInvoicesView() { : } + zeroState={} classNames={{ table: styles["table"], root: styles["table-wrapper"], diff --git a/web/sdk/admin/views/organizations/details/invoices/invoices.module.css b/web/sdk/admin/views/organizations/details/invoices/invoices.module.css index af9b8c2cc..1ef5c9ce0 100644 --- a/web/sdk/admin/views/organizations/details/invoices/invoices.module.css +++ b/web/sdk/admin/views/organizations/details/invoices/invoices.module.css @@ -7,6 +7,14 @@ text-wrap: auto; } +.zero-state-container { + padding: var(--rs-space-10); +} + +.zero-state { + padding-top: var(--rs-space-17); +} + .table { width: 100%; table-layout: fixed; diff --git a/web/sdk/admin/views/organizations/details/members/index.tsx b/web/sdk/admin/views/organizations/details/members/index.tsx index a706ebb3c..7f80fdadd 100644 --- a/web/sdk/admin/views/organizations/details/members/index.tsx +++ b/web/sdk/admin/views/organizations/details/members/index.tsx @@ -54,6 +54,20 @@ const NoMembers = () => { ); }; +const ZeroState = () => { + return ( +
+ } + heading="Members" + subHeading="Members are users who belong to this organization and can access its resources." + /> +
+ ); +}; + const ErrorState = () => { return ( : } + zeroState={} classNames={{ table: styles["table"], root: styles["table-wrapper"], diff --git a/web/sdk/admin/views/organizations/details/members/members.module.css b/web/sdk/admin/views/organizations/details/members/members.module.css index b74e1e389..a63c07d9b 100644 --- a/web/sdk/admin/views/organizations/details/members/members.module.css +++ b/web/sdk/admin/views/organizations/details/members/members.module.css @@ -15,6 +15,14 @@ text-wrap: auto; } +.zero-state-container { + padding: var(--rs-space-10); +} + +.zero-state { + padding-top: var(--rs-space-17); +} + .table { width: 100%; table-layout: fixed; diff --git a/web/sdk/admin/views/organizations/details/projects/index.tsx b/web/sdk/admin/views/organizations/details/projects/index.tsx index 9cd2a9e86..6600c6f58 100644 --- a/web/sdk/admin/views/organizations/details/projects/index.tsx +++ b/web/sdk/admin/views/organizations/details/projects/index.tsx @@ -51,6 +51,21 @@ const NoProjects = () => { ); }; +const ZeroState = () => { + const t = useTerminology(); + return ( +
+ } + heading={t.project({ plural: true, case: "capital" })} + subHeading={`${t.project({ plural: true, case: "capital" })} group resources and members within this ${t.organization({ case: "lower" })}.`} + /> +
+ ); +}; + const ErrorState = () => { const t = useTerminology(); return ( @@ -192,6 +207,7 @@ export function OrganizationProjectsView() { : } + zeroState={} classNames={{ table: styles["table"], root: styles["table-wrapper"], diff --git a/web/sdk/admin/views/organizations/details/projects/projects.module.css b/web/sdk/admin/views/organizations/details/projects/projects.module.css index 813f1e8c0..4c2f64dea 100644 --- a/web/sdk/admin/views/organizations/details/projects/projects.module.css +++ b/web/sdk/admin/views/organizations/details/projects/projects.module.css @@ -15,6 +15,14 @@ text-wrap: auto; } +.zero-state-container { + padding: var(--rs-space-10); +} + +.zero-state { + padding-top: var(--rs-space-17); +} + .table { width: 100%; table-layout: fixed; diff --git a/web/sdk/admin/views/organizations/details/tokens/index.tsx b/web/sdk/admin/views/organizations/details/tokens/index.tsx index 31f953bcd..a7ca7c424 100644 --- a/web/sdk/admin/views/organizations/details/tokens/index.tsx +++ b/web/sdk/admin/views/organizations/details/tokens/index.tsx @@ -45,6 +45,20 @@ const NoTokens = () => { ); }; +const ZeroState = () => { + return ( +
+ } + heading="Tokens" + subHeading="Token transactions for this organization's consumable balance will appear here." + /> +
+ ); +}; + const ErrorState = () => { const t = useTerminology(); return ( @@ -150,6 +164,7 @@ export function OrganizationTokensView() { : } + zeroState={} classNames={{ table: styles["table"], root: styles["table-wrapper"], diff --git a/web/sdk/admin/views/organizations/details/tokens/tokens.module.css b/web/sdk/admin/views/organizations/details/tokens/tokens.module.css index 11cd46935..0bfa4a70e 100644 --- a/web/sdk/admin/views/organizations/details/tokens/tokens.module.css +++ b/web/sdk/admin/views/organizations/details/tokens/tokens.module.css @@ -7,6 +7,14 @@ text-wrap: auto; } +.zero-state-container { + padding: var(--rs-space-10); +} + +.zero-state { + padding-top: var(--rs-space-17); +} + .table { width: 100%; table-layout: fixed; From e7ca2bb8fc99b2a69b275457d695bae84c29a921 Mon Sep 17 00:00:00 2001 From: Shreyag02 Date: Thu, 23 Jul 2026 15:33:53 +0530 Subject: [PATCH 6/8] fix(admin/org): pin listing navbar to a fixed height Use a fixed height instead of min-height so the bar no longer resizes when the New Organization button (taller than the search field) is toggled in and out during search. --- web/sdk/admin/views/organizations/list/list.module.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/sdk/admin/views/organizations/list/list.module.css b/web/sdk/admin/views/organizations/list/list.module.css index 945c41533..086bc7d25 100644 --- a/web/sdk/admin/views/organizations/list/list.module.css +++ b/web/sdk/admin/views/organizations/list/list.module.css @@ -5,7 +5,7 @@ display: flex; align-items: center; justify-content: space-between; - min-height: var(--rs-space-11); + height: var(--rs-space-11); } .table { @@ -83,4 +83,4 @@ .select-content { max-height: 400px; -} +} \ No newline at end of file From dc9d6ea3c9521bbee52c2ad6925706776918760a Mon Sep 17 00:00:00 2001 From: Shreyag02 Date: Thu, 23 Jul 2026 17:11:03 +0530 Subject: [PATCH 7/8] fix(admin/org): reveal row actions on hover in detail listings Show the three-dot action menu only on row hover, keyboard focus, or while its menu is open, fading the trigger rather than the cell so table row dividers stay intact. Wrap the project and project-member action triggers in IconButton for a pointer cursor and hit area, and widen the project-member popup action column to match the members list. --- .../details/members/members.module.css | 11 +++++++++++ .../organizations/details/projects/columns.tsx | 10 +++++++--- .../details/projects/members/columns.tsx | 12 +++++++++++- .../details/projects/members/members.module.css | 13 ++++++++++++- .../details/projects/projects.module.css | 11 +++++++++++ 5 files changed, 52 insertions(+), 5 deletions(-) diff --git a/web/sdk/admin/views/organizations/details/members/members.module.css b/web/sdk/admin/views/organizations/details/members/members.module.css index a63c07d9b..b68df4bfe 100644 --- a/web/sdk/admin/views/organizations/details/members/members.module.css +++ b/web/sdk/admin/views/organizations/details/members/members.module.css @@ -42,3 +42,14 @@ .table-action-column { width: var(--rs-space-12); } + +.table-action-column > * { + opacity: 0; + transition: opacity 120ms ease-in-out; +} + +.table-wrapper tr:hover .table-action-column > *, +.table-action-column:focus-within > *, +.table-action-column:has([data-popup-open]) > * { + opacity: 1; +} diff --git a/web/sdk/admin/views/organizations/details/projects/columns.tsx b/web/sdk/admin/views/organizations/details/projects/columns.tsx index 451234679..27d24895c 100644 --- a/web/sdk/admin/views/organizations/details/projects/columns.tsx +++ b/web/sdk/admin/views/organizations/details/projects/columns.tsx @@ -5,6 +5,7 @@ import { Flex, Text, Menu, + IconButton, } from "@raystack/apsara"; import type { DataTableColumnDef } from "@raystack/apsara"; import type { @@ -161,7 +162,7 @@ function ProjectActions({ const [isRenameDialogOpen, setIsRenameDialogOpen] = useState(false); - const preventClickBubbling = (e: React.MouseEvent) => { + const preventClickBubbling = (e: React.MouseEvent) => { e.stopPropagation(); }; @@ -189,10 +190,13 @@ function ProjectActions({ + > + + } /> diff --git a/web/sdk/admin/views/organizations/details/projects/members/columns.tsx b/web/sdk/admin/views/organizations/details/projects/members/columns.tsx index e653145ae..ffff18bff 100644 --- a/web/sdk/admin/views/organizations/details/projects/members/columns.tsx +++ b/web/sdk/admin/views/organizations/details/projects/members/columns.tsx @@ -10,6 +10,7 @@ import { getAvatarColor, Text, AlertDialog, + IconButton, } from "@raystack/apsara"; import type { DataTableColumnDef } from "@raystack/apsara"; import { DotsHorizontalIcon, UpdateIcon } from "@radix-ui/react-icons"; @@ -98,7 +99,16 @@ export const getColumns = ({ ); return ( - } /> + + + + } + /> * { + opacity: 0; + transition: opacity 120ms ease-in-out; +} + +.table-wrapper tr:hover .table-action-column>*, +.table-action-column:focus-within>*, +.table-action-column:has([data-popup-open])>* { + opacity: 1; } .table-action-dropdown { diff --git a/web/sdk/admin/views/organizations/details/projects/projects.module.css b/web/sdk/admin/views/organizations/details/projects/projects.module.css index 4c2f64dea..c9415bbf1 100644 --- a/web/sdk/admin/views/organizations/details/projects/projects.module.css +++ b/web/sdk/admin/views/organizations/details/projects/projects.module.css @@ -43,6 +43,17 @@ width: var(--rs-space-12); } +.table-action-column > * { + opacity: 0; + transition: opacity 120ms ease-in-out; +} + +.table-wrapper tr:hover .table-action-column > *, +.table-action-column:focus-within > *, +.table-action-column:has([data-popup-open]) > * { + opacity: 1; +} + /* Keep the row highlighted while its action menu is open. */ .table-wrapper tr:has([data-test-id="admin-project-actions"][data-popup-open]) { background: var(--rs-color-background-base-primary-hover); From 62690f372fbdb88533a5d0e2566680b2c9679bd9 Mon Sep 17 00:00:00 2001 From: Shreyag02 Date: Fri, 24 Jul 2026 00:04:27 +0530 Subject: [PATCH 8/8] fix(admin/org): polish project members popup Disable the popup Add member action for single-member orgs since there is no one to search for, and highlight a member row while its action menu is open. Drop the duplicate manual close button in the members and PAT dialogs now that Dialog.Content renders one, and direct initial dialog focus to the content body so it never lands on the close button when the search field is disabled. --- .../details/pat/components/pat-details-dialog.tsx | 1 - .../organizations/details/projects/index.tsx | 3 +++ .../projects/members/add-members-dropdown.tsx | 9 +++++++-- .../details/projects/members/index.tsx | 15 ++++++++++++--- .../details/projects/members/members.module.css | 9 +++++++++ 5 files changed, 31 insertions(+), 6 deletions(-) diff --git a/web/sdk/admin/views/organizations/details/pat/components/pat-details-dialog.tsx b/web/sdk/admin/views/organizations/details/pat/components/pat-details-dialog.tsx index c4d66f0bf..8739d5447 100644 --- a/web/sdk/admin/views/organizations/details/pat/components/pat-details-dialog.tsx +++ b/web/sdk/admin/views/organizations/details/pat/components/pat-details-dialog.tsx @@ -99,7 +99,6 @@ export function PatDetailsDialog({ {pat?.title || ""} - diff --git a/web/sdk/admin/views/organizations/details/projects/index.tsx b/web/sdk/admin/views/organizations/details/projects/index.tsx index 6600c6f58..a8847c3bb 100644 --- a/web/sdk/admin/views/organizations/details/projects/index.tsx +++ b/web/sdk/admin/views/organizations/details/projects/index.tsx @@ -183,12 +183,15 @@ export function OrganizationProjectsView() { const columns = getColumns({ orgMembersMap, handleProjectUpdate, t }); + const canAddMember = Object.keys(orgMembersMap).length > 1; + return ( <> {memberDialogConfig.open && memberDialogConfig.projectId ? ( ) : null} diff --git a/web/sdk/admin/views/organizations/details/projects/members/add-members-dropdown.tsx b/web/sdk/admin/views/organizations/details/projects/members/add-members-dropdown.tsx index 457dd690c..184d5c3c3 100644 --- a/web/sdk/admin/views/organizations/details/projects/members/add-members-dropdown.tsx +++ b/web/sdk/admin/views/organizations/details/projects/members/add-members-dropdown.tsx @@ -2,7 +2,6 @@ import { Avatar, Button, Menu, - Flex, getAvatarColor, Text, } from "@raystack/apsara"; @@ -14,6 +13,7 @@ import { useAddProjectMembers } from "../use-add-project-members"; interface AddMembersDropdownProps { projectId: string; refetchMembers: () => Promise; + disabled?: boolean; } function Loader() { @@ -31,6 +31,7 @@ function Loader() { export function AddMembersDropdown({ projectId, refetchMembers, + disabled, }: AddMembersDropdownProps) { const { eligibleMembers, isLoading, addMember, setSearchQuery } = useAddProjectMembers({ @@ -52,7 +53,11 @@ export function AddMembersDropdown({ autocompleteMode="manual" > Add member} + render={ + + } /> (); export const ProjectMembersDialog = ({ projectId, onClose, + canAddMember, }: { projectId: string; onClose: () => void; + canAddMember: boolean; }) => { + const initialFocusRef = useRef(null); + const [tableQuery, setTableQuery] = useDebouncedState<{ query: DataTableQuery; rqlRequest: RQLRequest; @@ -199,14 +203,16 @@ export const ProjectMembersDialog = ({ /> ) : null} - + initialFocusRef.current} + > {isProjectLoading ? ( ) : ( {project?.title ?? ""} )} -