feat: route groups by name instead of id (#13692)

* feat: route groups by name instead of id

* fix: update group navigation when name changes

* fix: update isLoading and error checking

* fix: fix format

* fix: update isLoading and error

* fix: cleanup
This commit is contained in:
Jaayden Halko
2024-07-01 15:48:14 -04:00
committed by GitHub
parent 41e1383640
commit f26f123391
10 changed files with 58 additions and 24 deletions
+1 -1
View File
@@ -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`);
+1 -1
View File
@@ -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`);
+1 -1
View File
@@ -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`);
+4 -2
View File
@@ -1455,8 +1455,10 @@ class ApiMethods {
return response.data;
};
getGroup = async (groupId: string): Promise<TypesGen.Group> => {
const response = await this.axios.get(`/api/v2/groups/${groupId}`);
getGroup = async (groupName: string): Promise<TypesGen.Group> => {
const response = await this.axios.get(
`/api/v2/organizations/default/groups/${groupName}`,
);
return response.data;
};
+4 -4
View File
@@ -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<Group[]>;
};
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),
};
};
@@ -24,7 +24,7 @@ export const CreateGroupPage: FC = () => {
organizationId,
...data,
});
navigate(`/groups/${newGroup.id}`);
navigate(`/groups/${newGroup.name}`);
}}
error={createGroupMutation.error}
isLoading={createGroupMutation.isLoading}
+15 -4
View File
@@ -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 = () => {
</Helmet>
);
if (groupQuery.error) {
return <ErrorAlert error={groupQuery.error} />;
}
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."));
}
+1 -1
View File
@@ -96,7 +96,7 @@ export const GroupsPageView: FC<GroupsPageViewProps> = ({
<Cond>
{groups?.map((group) => {
const groupPageLink = `/groups/${group.id}`;
const groupPageLink = `/groups/${group.name}`;
return (
<TableRow
@@ -4,26 +4,47 @@ import { useMutation, useQuery, useQueryClient } from "react-query";
import { useNavigate, useParams } from "react-router-dom";
import { getErrorMessage } from "api/errors";
import { group, patchGroup } from "api/queries/groups";
import { ErrorAlert } from "components/Alert/ErrorAlert";
import { displayError } from "components/GlobalSnackbar/utils";
import { Loader } from "components/Loader/Loader";
import { pageTitle } from "utils/page";
import SettingsGroupPageView from "./SettingsGroupPageView";
export const SettingsGroupPage: FC = () => {
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 = (
<Helmet>
<title>{pageTitle("Settings Group")}</title>
</Helmet>
);
if (error) {
return <ErrorAlert error={error} />;
}
if (isLoading || !groupData) {
return (
<>
{helmet}
<Loader />
</>
);
}
const groupId = groupData.id;
return (
<>
<Helmet>
<title>{pageTitle("Settings Group")}</title>
</Helmet>
{helmet}
<SettingsGroupPageView
onCancel={navigateToGroup}
@@ -35,7 +56,7 @@ export const SettingsGroupPage: FC = () => {
add_users: [],
remove_users: [],
});
navigateToGroup();
navigate(`/groups/${data.name}`, { replace: true });
} catch (error) {
displayError(getErrorMessage(error, "Failed to update group"));
}
+2 -2
View File
@@ -330,8 +330,8 @@ export const router = createBrowserRouter(
</Route>
<Route path="create" element={<CreateGroupPage />} />
<Route path=":groupId" element={<GroupPage />} />
<Route path=":groupId/settings" element={<SettingsGroupPage />} />
<Route path=":groupName" element={<GroupPage />} />
<Route path=":groupName/settings" element={<SettingsGroupPage />} />
</Route>
<Route path="/audit" element={<AuditPage />} />