From 4a01a21f5d916f45c800ec5e627ae90a793d4f51 Mon Sep 17 00:00:00 2001 From: Rohan Chakraborty Date: Tue, 19 May 2026 14:18:43 +0530 Subject: [PATCH 1/3] fix: sdk action menu behaviour --- web/sdk/react/assets/user-minus.svg | 3 +++ web/sdk/react/hooks/useOrganizationTeams.ts | 8 +++++--- .../members/components/member-columns.tsx | 6 +++--- .../views-new/members/members-view.module.css | 4 ++++ .../react/views-new/members/members-view.tsx | 19 ++++++++++++++++--- .../components/member-columns.module.css | 7 +++++++ .../projects/components/member-columns.tsx | 11 ++++++----- .../components/project-columns.module.css | 7 +++++++ .../projects/components/project-columns.tsx | 9 +++++---- .../projects/project-details-view.module.css | 4 ++++ .../projects/project-details-view.tsx | 3 ++- .../components/service-account-columns.tsx | 6 +++--- .../components/member-columns.module.css | 7 +++++++ .../teams/components/member-columns.tsx | 11 ++++++----- .../teams/components/team-columns.module.css | 7 +++++++ .../teams/components/team-columns.tsx | 9 +++++---- .../teams/team-details-view.module.css | 4 ++++ .../views-new/teams/team-details-view.tsx | 6 ++++-- web/sdk/react/views-new/teams/teams-view.tsx | 11 ++++++++--- 19 files changed, 106 insertions(+), 36 deletions(-) create mode 100644 web/sdk/react/assets/user-minus.svg create mode 100644 web/sdk/react/views-new/projects/components/member-columns.module.css create mode 100644 web/sdk/react/views-new/projects/components/project-columns.module.css create mode 100644 web/sdk/react/views-new/teams/components/member-columns.module.css create mode 100644 web/sdk/react/views-new/teams/components/team-columns.module.css diff --git a/web/sdk/react/assets/user-minus.svg b/web/sdk/react/assets/user-minus.svg new file mode 100644 index 000000000..f22dd6321 --- /dev/null +++ b/web/sdk/react/assets/user-minus.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/web/sdk/react/hooks/useOrganizationTeams.ts b/web/sdk/react/hooks/useOrganizationTeams.ts index ae6e04097..c444996fc 100644 --- a/web/sdk/react/hooks/useOrganizationTeams.ts +++ b/web/sdk/react/hooks/useOrganizationTeams.ts @@ -16,6 +16,7 @@ export const useOrganizationTeams = ({ withMemberCount = false }: useOrganizationTeamsProps): { isFetching: boolean; + isFetched: boolean; teams: Group[]; userAccessOnTeam: Record; refetch: () => void; @@ -27,14 +28,14 @@ export const useOrganizationTeams = ({ const { activeOrganization: organization } = useFrontier(); // Organization teams query - const { data: orgTeamsData, isLoading: isOrgTeamsLoading, error: orgTeamsError, refetch: refetchOrgTeams } = useQuery( + const { data: orgTeamsData, isLoading: isOrgTeamsLoading, isFetched: isOrgTeamsFetched, error: orgTeamsError, refetch: refetchOrgTeams } = useQuery( FrontierServiceQueries.listOrganizationGroups, create(ListOrganizationGroupsRequestSchema, { orgId: organization?.id || '', withMemberCount }), { enabled: !!organization?.id && showOrgTeams } ); - // User teams query - const { data: userTeamsData, isLoading: isUserTeamsLoading, error: userTeamsError, refetch: refetchUserTeams } = useQuery( + // User teams query + const { data: userTeamsData, isLoading: isUserTeamsLoading, isFetched: isUserTeamsFetched, error: userTeamsError, refetch: refetchUserTeams } = useQuery( FrontierServiceQueries.listCurrentUserGroups, create(ListCurrentUserGroupsRequestSchema, { orgId: organization?.id || '', withPermissions, withMemberCount }), { enabled: !!organization?.id && !showOrgTeams } @@ -75,6 +76,7 @@ export const useOrganizationTeams = ({ return { isFetching: isTeamsLoading, + isFetched: isUserTeamsFetched || isOrgTeamsFetched, teams: teams, userAccessOnTeam, refetch, diff --git a/web/sdk/react/views-new/members/components/member-columns.tsx b/web/sdk/react/views-new/members/components/member-columns.tsx index 6a1265128..fcc45a5e6 100644 --- a/web/sdk/react/views-new/members/components/member-columns.tsx +++ b/web/sdk/react/views-new/members/components/member-columns.tsx @@ -1,6 +1,6 @@ 'use client'; -import { DotsVerticalIcon } from '@radix-ui/react-icons'; +import { DotsHorizontalIcon } from '@radix-ui/react-icons'; import { Flex, Text, @@ -141,13 +141,13 @@ export const getColumns = ({ }} render={ } > - + ); diff --git a/web/sdk/react/views-new/members/members-view.module.css b/web/sdk/react/views-new/members/members-view.module.css index 78da80ac9..5e32e17cb 100644 --- a/web/sdk/react/views-new/members/members-view.module.css +++ b/web/sdk/react/views-new/members/members-view.module.css @@ -12,6 +12,10 @@ table-layout: fixed; } +.tableRow > td { + padding: var(--rs-space-3); +} + .menuContent { min-width: 180px; } diff --git a/web/sdk/react/views-new/members/members-view.tsx b/web/sdk/react/views-new/members/members-view.tsx index a5fc80f96..74157b69f 100644 --- a/web/sdk/react/views-new/members/members-view.tsx +++ b/web/sdk/react/views-new/members/members-view.tsx @@ -1,7 +1,7 @@ 'use client'; import { useMemo, useState } from 'react'; -import { ExclamationTriangleIcon, TrashIcon, UpdateIcon } from '@radix-ui/react-icons'; +import { ExclamationTriangleIcon, UpdateIcon } from '@radix-ui/react-icons'; import { Button, Tooltip, @@ -11,8 +11,10 @@ import { EmptyState, DataTable, Dialog, + Image, Menu } from '@raystack/apsara-v1'; +import deleteIcon from '../../assets/delete.svg'; import { useFrontier } from '../../contexts/FrontierContext'; import { useOrganizationMembers } from '../../hooks/useOrganizationMembers'; import { usePermissions } from '../../hooks/usePermissions'; @@ -189,7 +191,8 @@ export function MembersView({ showTeamField = true }: MembersViewProps) { } classNames={{ root: styles.tableRoot, - table: styles.table + table: styles.table, + row: styles.tableRow }} /> @@ -218,7 +221,14 @@ export function MembersView({ showTeamField = true }: MembersViewProps) { ))} {payload?.canRemove && ( } + leadingIcon={ + Remove + } onClick={() => removeMemberDialogHandle.openWithPayload({ memberId: payload.memberId, @@ -226,6 +236,9 @@ export function MembersView({ showTeamField = true }: MembersViewProps) { }) } data-test-id="remove-member-dropdown-item" + style={{ + color: 'var(--rs-color-foreground-danger-primary)' + }} > Remove diff --git a/web/sdk/react/views-new/projects/components/member-columns.module.css b/web/sdk/react/views-new/projects/components/member-columns.module.css new file mode 100644 index 000000000..72da9c120 --- /dev/null +++ b/web/sdk/react/views-new/projects/components/member-columns.module.css @@ -0,0 +1,7 @@ +.actionsCell { + visibility: hidden; +} + +tr:hover .actionsCell { + visibility: visible; +} diff --git a/web/sdk/react/views-new/projects/components/member-columns.tsx b/web/sdk/react/views-new/projects/components/member-columns.tsx index 738c04276..3e0af7b90 100644 --- a/web/sdk/react/views-new/projects/components/member-columns.tsx +++ b/web/sdk/react/views-new/projects/components/member-columns.tsx @@ -1,6 +1,6 @@ 'use client'; -import { DotsVerticalIcon, TrashIcon, UpdateIcon } from '@radix-ui/react-icons'; +import { DotsHorizontalIcon } from '@radix-ui/react-icons'; import { Flex, Text, @@ -13,6 +13,7 @@ import { import type { User, Group, Role } from '@raystack/proton/frontier'; import { getInitials } from '~/utils'; import teamIcon from '~/react/assets/users.svg'; +import styles from './member-columns.module.css'; export type MemberRow = (Group & { isTeam: true }) | (User & { isTeam?: false }); @@ -52,7 +53,7 @@ export function getColumns({ const label = member.isTeam ? member.title : member.title; const subLabel = member.isTeam ? member.name : member.email; return ( - + !currentRoleIds.has(r.id)); return ( - + } > - + ); diff --git a/web/sdk/react/views-new/projects/components/project-columns.module.css b/web/sdk/react/views-new/projects/components/project-columns.module.css new file mode 100644 index 000000000..72da9c120 --- /dev/null +++ b/web/sdk/react/views-new/projects/components/project-columns.module.css @@ -0,0 +1,7 @@ +.actionsCell { + visibility: hidden; +} + +tr:hover .actionsCell { + visibility: visible; +} diff --git a/web/sdk/react/views-new/projects/components/project-columns.tsx b/web/sdk/react/views-new/projects/components/project-columns.tsx index 9b514be3b..4f2785fba 100644 --- a/web/sdk/react/views-new/projects/components/project-columns.tsx +++ b/web/sdk/react/views-new/projects/components/project-columns.tsx @@ -1,6 +1,6 @@ 'use client'; -import { DotsVerticalIcon, Pencil1Icon, TrashIcon } from '@radix-ui/react-icons'; +import { DotsHorizontalIcon } from '@radix-ui/react-icons'; import { Flex, Text, @@ -10,6 +10,7 @@ import { } from '@raystack/apsara-v1'; import type { Project } from '@raystack/proton/frontier'; import { MembersCell } from './members-cell'; +import styles from './project-columns.module.css'; export interface ProjectMenuPayload { projectId: string; @@ -84,7 +85,7 @@ export const getColumns = ({ if (!canUpdate && !canDelete) return null; return ( - + } > - + ); diff --git a/web/sdk/react/views-new/projects/project-details-view.module.css b/web/sdk/react/views-new/projects/project-details-view.module.css index 2674282bc..a9a2e35eb 100644 --- a/web/sdk/react/views-new/projects/project-details-view.module.css +++ b/web/sdk/react/views-new/projects/project-details-view.module.css @@ -12,6 +12,10 @@ table-layout: fixed; } +.tableRow > td { + padding: var(--rs-space-3); +} + .menuContent { min-width: 160px; } diff --git a/web/sdk/react/views-new/projects/project-details-view.tsx b/web/sdk/react/views-new/projects/project-details-view.tsx index f06cacf6a..b0e77dbf3 100644 --- a/web/sdk/react/views-new/projects/project-details-view.tsx +++ b/web/sdk/react/views-new/projects/project-details-view.tsx @@ -414,7 +414,8 @@ export function ProjectDetailsView({ } classNames={{ root: styles.tableRoot, - table: styles.table + table: styles.table, + row: styles.tableRow }} /> diff --git a/web/sdk/react/views-new/service-accounts/components/service-account-columns.tsx b/web/sdk/react/views-new/service-accounts/components/service-account-columns.tsx index b889465d1..a1e50b86d 100644 --- a/web/sdk/react/views-new/service-accounts/components/service-account-columns.tsx +++ b/web/sdk/react/views-new/service-accounts/components/service-account-columns.tsx @@ -1,6 +1,6 @@ 'use client'; -import { DotsVerticalIcon } from '@radix-ui/react-icons'; +import { DotsHorizontalIcon } from '@radix-ui/react-icons'; import { Flex, Text, @@ -81,14 +81,14 @@ export const getColumns = ({ }} render={ } > - + ); diff --git a/web/sdk/react/views-new/teams/components/member-columns.module.css b/web/sdk/react/views-new/teams/components/member-columns.module.css new file mode 100644 index 000000000..72da9c120 --- /dev/null +++ b/web/sdk/react/views-new/teams/components/member-columns.module.css @@ -0,0 +1,7 @@ +.actionsCell { + visibility: hidden; +} + +tr:hover .actionsCell { + visibility: visible; +} diff --git a/web/sdk/react/views-new/teams/components/member-columns.tsx b/web/sdk/react/views-new/teams/components/member-columns.tsx index 38f12cd49..b1a0afddd 100644 --- a/web/sdk/react/views-new/teams/components/member-columns.tsx +++ b/web/sdk/react/views-new/teams/components/member-columns.tsx @@ -1,6 +1,6 @@ 'use client'; -import { DotsVerticalIcon } from '@radix-ui/react-icons'; +import { DotsHorizontalIcon } from '@radix-ui/react-icons'; import { Flex, Text, @@ -12,6 +12,7 @@ import { } from '@raystack/apsara-v1'; import type { User, Role } from '@raystack/proton/frontier'; import { getInitials } from '~/utils'; +import styles from './member-columns.module.css'; export interface MemberMenuPayload { memberId: string; @@ -42,7 +43,7 @@ export function getColumns({ const fallback = getInitials(member.title || member.email); const color = getAvatarColor(member.id || ''); return ( - + !currentRoleIds.has(r.id)); return ( - + } > - + ); diff --git a/web/sdk/react/views-new/teams/components/team-columns.module.css b/web/sdk/react/views-new/teams/components/team-columns.module.css new file mode 100644 index 000000000..72da9c120 --- /dev/null +++ b/web/sdk/react/views-new/teams/components/team-columns.module.css @@ -0,0 +1,7 @@ +.actionsCell { + visibility: hidden; +} + +tr:hover .actionsCell { + visibility: visible; +} diff --git a/web/sdk/react/views-new/teams/components/team-columns.tsx b/web/sdk/react/views-new/teams/components/team-columns.tsx index 5e7be2508..94abc9003 100644 --- a/web/sdk/react/views-new/teams/components/team-columns.tsx +++ b/web/sdk/react/views-new/teams/components/team-columns.tsx @@ -1,6 +1,6 @@ 'use client'; -import { DotsVerticalIcon } from '@radix-ui/react-icons'; +import { DotsHorizontalIcon } from '@radix-ui/react-icons'; import { Flex, Text, @@ -9,6 +9,7 @@ import { DataTableColumnDef } from '@raystack/apsara-v1'; import type { Group } from '@raystack/proton/frontier'; +import styles from './team-columns.module.css'; export interface TeamMenuPayload { teamId: string; @@ -64,7 +65,7 @@ export function getColumns({ if (!canUpdate && !canDelete) return null; return ( - + } > - + ); diff --git a/web/sdk/react/views-new/teams/team-details-view.module.css b/web/sdk/react/views-new/teams/team-details-view.module.css index 8cd2868e7..c835a24ac 100644 --- a/web/sdk/react/views-new/teams/team-details-view.module.css +++ b/web/sdk/react/views-new/teams/team-details-view.module.css @@ -6,6 +6,10 @@ table-layout: fixed; } +.tableRow > td { + padding: var(--rs-space-3); +} + .menuContent { min-width: 160px; } diff --git a/web/sdk/react/views-new/teams/team-details-view.tsx b/web/sdk/react/views-new/teams/team-details-view.tsx index 984a3e38f..4b477a9ba 100644 --- a/web/sdk/react/views-new/teams/team-details-view.tsx +++ b/web/sdk/react/views-new/teams/team-details-view.tsx @@ -20,6 +20,7 @@ import { Image } from '@raystack/apsara-v1'; import deleteIcon from '../../assets/delete.svg'; +import userMinusIcon from '../../assets/user-minus.svg'; import { toastManager } from '@raystack/apsara-v1'; import { useQuery, useMutation } from '@connectrpc/connect-query'; import { @@ -340,7 +341,8 @@ export function TeamDetailsView({ } classNames={{ root: styles.tableRoot, - table: styles.table + table: styles.table, + row: styles.tableRow }} /> @@ -367,7 +369,7 @@ export function TeamDetailsView({ @@ -151,7 +154,7 @@ export function TeamsView({ - {isLoading ? ( + {showInitialSkeleton ? ( ) : ( <> @@ -159,11 +162,13 @@ export function TeamsView({ placeholder="Search by title" size="large" width={360} + disabled={isLoading} /> {canListOrgGroups && ( + + + + + {projectsFilterOptions.map(opt => ( + + {opt.label} + + ))} + + + )} + )} - {isLoading ? ( + {showInitialSkeleton ? ( ) : ( diff --git a/web/sdk/react/views-new/service-accounts/service-accounts-view.tsx b/web/sdk/react/views-new/service-accounts/service-accounts-view.tsx index 99f7f0b63..df6907951 100644 --- a/web/sdk/react/views-new/service-accounts/service-accounts-view.tsx +++ b/web/sdk/react/views-new/service-accounts/service-accounts-view.tsx @@ -16,6 +16,7 @@ import { } from '@raystack/apsara-v1'; import deleteIcon from '~/react/assets/delete.svg'; import keyIcon from '~/react/assets/key.svg'; +import exclamationTriangleIcon from '~/react/assets/exclamation-triangle.svg'; import { useQuery } from '@connectrpc/connect-query'; import { create } from '@bufbuild/protobuf'; import { @@ -146,19 +147,36 @@ export function ServiceAccountsView({ {hasNoAccess ? ( } + variant="empty2" + icon={ + + } heading="Restricted Access" subHeading="Admin access required, please reach out to your admin incase you want to generate a key." /> ) : hasNoServiceAccounts ? ( } + variant="empty2" + icon={ + + } heading="No Service Account Found" subHeading={`Create a new account to use the APIs of ${t.appName()} platform`} primaryAction={ + ) : null + } + /> + {canCreateGroup && ( + + )} + + ); + } + return (