diff --git a/site/e2e/tests/groups/addMembers.spec.ts b/site/e2e/tests/groups/addMembers.spec.ts index f9532733d86dd..5967dc80bfb60 100644 --- a/site/e2e/tests/groups/addMembers.spec.ts +++ b/site/e2e/tests/groups/addMembers.spec.ts @@ -20,7 +20,7 @@ test("add members", async ({ page, baseURL }) => { Array.from({ length: numberOfMembers }, () => createUser(orgId)), ); - await page.goto(`${baseURL}/groups/${group.id}`, { + await page.goto(`${baseURL}/groups/${group.name}`, { waitUntil: "domcontentloaded", }); await expect(page).toHaveTitle(`${group.display_name} - Coder`); diff --git a/site/e2e/tests/groups/removeGroup.spec.ts b/site/e2e/tests/groups/removeGroup.spec.ts index 9011ecbb7147a..eeea0afa22eef 100644 --- a/site/e2e/tests/groups/removeGroup.spec.ts +++ b/site/e2e/tests/groups/removeGroup.spec.ts @@ -11,7 +11,7 @@ test("remove group", async ({ page, baseURL }) => { const orgId = await getCurrentOrgId(); const group = await createGroup(orgId); - await page.goto(`${baseURL}/groups/${group.id}`, { + await page.goto(`${baseURL}/groups/${group.name}`, { waitUntil: "domcontentloaded", }); await expect(page).toHaveTitle(`${group.display_name} - Coder`); diff --git a/site/e2e/tests/groups/removeMember.spec.ts b/site/e2e/tests/groups/removeMember.spec.ts index 468d9d4851441..ba2856d578ae5 100644 --- a/site/e2e/tests/groups/removeMember.spec.ts +++ b/site/e2e/tests/groups/removeMember.spec.ts @@ -21,7 +21,7 @@ test("remove member", async ({ page, baseURL }) => { ]); await API.addMember(group.id, member.id); - await page.goto(`${baseURL}/groups/${group.id}`, { + await page.goto(`${baseURL}/groups/${group.name}`, { waitUntil: "domcontentloaded", }); await expect(page).toHaveTitle(`${group.display_name} - Coder`); diff --git a/site/src/api/api.ts b/site/src/api/api.ts index 01b4ccec76b9d..75a476adcf559 100644 --- a/site/src/api/api.ts +++ b/site/src/api/api.ts @@ -1455,8 +1455,10 @@ class ApiMethods { return response.data; }; - getGroup = async (groupId: string): Promise => { - const response = await this.axios.get(`/api/v2/groups/${groupId}`); + getGroup = async (groupName: string): Promise => { + const response = await this.axios.get( + `/api/v2/organizations/default/groups/${groupName}`, + ); return response.data; }; diff --git a/site/src/api/queries/groups.ts b/site/src/api/queries/groups.ts index 5c34758df069f..feeeb2335b16b 100644 --- a/site/src/api/queries/groups.ts +++ b/site/src/api/queries/groups.ts @@ -9,7 +9,7 @@ import type { const GROUPS_QUERY_KEY = ["groups"]; type GroupSortOrder = "asc" | "desc"; -const getGroupQueryKey = (groupId: string) => ["group", groupId]; +const getGroupQueryKey = (groupName: string) => ["group", groupName]; export const groups = (organizationId: string) => { return { @@ -18,10 +18,10 @@ export const groups = (organizationId: string) => { } satisfies UseQueryOptions; }; -export const group = (groupId: string) => { +export const group = (groupName: string) => { return { - queryKey: getGroupQueryKey(groupId), - queryFn: () => API.getGroup(groupId), + queryKey: getGroupQueryKey(groupName), + queryFn: () => API.getGroup(groupName), }; }; diff --git a/site/src/pages/GroupsPage/CreateGroupPage.tsx b/site/src/pages/GroupsPage/CreateGroupPage.tsx index d5fd2c1f73c01..16b75cb7bbb0d 100644 --- a/site/src/pages/GroupsPage/CreateGroupPage.tsx +++ b/site/src/pages/GroupsPage/CreateGroupPage.tsx @@ -24,7 +24,7 @@ export const CreateGroupPage: FC = () => { organizationId, ...data, }); - navigate(`/groups/${newGroup.id}`); + navigate(`/groups/${newGroup.name}`); }} error={createGroupMutation.error} isLoading={createGroupMutation.isLoading} diff --git a/site/src/pages/GroupsPage/GroupPage.tsx b/site/src/pages/GroupsPage/GroupPage.tsx index 01e8dc250b13b..b36f1f9c1cde0 100644 --- a/site/src/pages/GroupsPage/GroupPage.tsx +++ b/site/src/pages/GroupsPage/GroupPage.tsx @@ -23,6 +23,7 @@ import { removeMember, } from "api/queries/groups"; import type { Group, ReducedUser, User } from "api/typesGenerated"; +import { ErrorAlert } from "components/Alert/ErrorAlert"; import { AvatarData } from "components/AvatarData/AvatarData"; import { DeleteDialog } from "components/Dialogs/DeleteDialog/DeleteDialog"; import { EmptyState } from "components/EmptyState/EmptyState"; @@ -53,16 +54,20 @@ import { isEveryoneGroup } from "utils/groups"; import { pageTitle } from "utils/page"; export const GroupPage: FC = () => { - const { groupId } = useParams() as { groupId: string }; + const { groupName } = useParams() as { groupName: string }; const queryClient = useQueryClient(); const navigate = useNavigate(); - const groupQuery = useQuery(group(groupId)); + const groupQuery = useQuery(group(groupName)); const groupData = groupQuery.data; - const { data: permissions } = useQuery(groupPermissions(groupId)); + const { data: permissions } = useQuery( + groupData !== undefined + ? groupPermissions(groupData.id) + : { enabled: false }, + ); const addMemberMutation = useMutation(addMember(queryClient)); const deleteGroupMutation = useMutation(deleteGroup(queryClient)); const [isDeletingGroup, setIsDeletingGroup] = useState(false); - const isLoading = !groupData || !permissions; + const isLoading = groupQuery.isLoading || !groupData || !permissions; const canUpdateGroup = permissions ? permissions.canUpdateGroup : false; const helmet = ( @@ -75,6 +80,10 @@ export const GroupPage: FC = () => { ); + if (groupQuery.error) { + return ; + } + if (isLoading) { return ( <> @@ -83,6 +92,7 @@ export const GroupPage: FC = () => { ); } + const groupId = groupData.id; return ( <> @@ -137,6 +147,7 @@ export const GroupPage: FC = () => { userId: user.id, }); reset(); + await groupQuery.refetch(); } catch (error) { displayError(getErrorMessage(error, "Failed to add member.")); } diff --git a/site/src/pages/GroupsPage/GroupsPageView.tsx b/site/src/pages/GroupsPage/GroupsPageView.tsx index da87bb6e07580..4f167be339eef 100644 --- a/site/src/pages/GroupsPage/GroupsPageView.tsx +++ b/site/src/pages/GroupsPage/GroupsPageView.tsx @@ -96,7 +96,7 @@ export const GroupsPageView: FC = ({ {groups?.map((group) => { - const groupPageLink = `/groups/${group.id}`; + const groupPageLink = `/groups/${group.name}`; return ( { - const { groupId } = useParams() as { groupId: string }; + const { groupName } = useParams() as { groupName: string }; const queryClient = useQueryClient(); - const groupQuery = useQuery(group(groupId)); + const groupQuery = useQuery(group(groupName)); + const { data: groupData, isLoading, error } = useQuery(group(groupName)); const patchGroupMutation = useMutation(patchGroup(queryClient)); const navigate = useNavigate(); const navigateToGroup = () => { - navigate(`/groups/${groupId}`); + navigate(`/groups/${groupName}`); }; + const helmet = ( + + {pageTitle("Settings Group")} + + ); + + if (error) { + return ; + } + + if (isLoading || !groupData) { + return ( + <> + {helmet} + + + ); + } + const groupId = groupData.id; + return ( <> - - {pageTitle("Settings Group")} - + {helmet} { add_users: [], remove_users: [], }); - navigateToGroup(); + navigate(`/groups/${data.name}`, { replace: true }); } catch (error) { displayError(getErrorMessage(error, "Failed to update group")); } diff --git a/site/src/router.tsx b/site/src/router.tsx index e2685c29f69c8..451e8026feafc 100644 --- a/site/src/router.tsx +++ b/site/src/router.tsx @@ -327,8 +327,8 @@ export const router = createBrowserRouter( } /> - } /> - } /> + } /> + } /> } />