fix: add groups to deployment settings (#16185)

fixes #16182 

<img width="1177" alt="Screenshot 2025-01-17 at 23 20 04"
src="https://github.com/user-attachments/assets/e0eec4bb-6b50-45e9-a27b-d3a89552562a"
/>
<img width="1163" alt="Screenshot 2025-01-17 at 23 20 12"
src="https://github.com/user-attachments/assets/d8a7129c-0240-4ef5-9f21-84cda5631366"
/>
<img width="1161" alt="Screenshot 2025-01-17 at 23 20 22"
src="https://github.com/user-attachments/assets/0ec78f3d-ec96-46a6-8def-aad4700712ac"
/>
This commit is contained in:
Jaayden Halko
2025-01-17 19:46:28 -05:00
committed by GitHub
parent 5cc7c439f3
commit fbc2a73bef
9 changed files with 34 additions and 59 deletions
+5 -3
View File
@@ -293,13 +293,15 @@ export const createTemplate = async (
* random name.
*/
export const createGroup = async (page: Page): Promise<string> => {
await page.goto("/groups/create", { waitUntil: "domcontentloaded" });
await expectUrl(page).toHavePathName("/groups/create");
await page.goto("/deployment/groups/create", {
waitUntil: "domcontentloaded",
});
await expectUrl(page).toHavePathName("/deployment/groups/create");
const name = randomName();
await page.getByLabel("Name", { exact: true }).fill(name);
await page.getByRole("button", { name: /save/i }).click();
await expectUrl(page).toHavePathName(`/groups/${name}`);
await expectUrl(page).toHavePathName(`/deployment/groups/${name}`);
return name;
};
@@ -99,6 +99,9 @@ const DeploymentSettingsNavigation: FC<DeploymentSettingsNavigationProps> = ({
{permissions.viewAllUsers && (
<SidebarNavItem href="/deployment/users">Users</SidebarNavItem>
)}
{permissions.viewAnyGroup && (
<SidebarNavItem href="/deployment/groups">Groups</SidebarNavItem>
)}
{permissions.viewNotificationTemplate && (
<SidebarNavItem href="/deployment/notifications">
<div className="flex flex-row items-center gap-2">
@@ -19,7 +19,7 @@ export const CreateGroupPage: FC = () => {
<CreateGroupPageView
onSubmit={async (data) => {
const newGroup = await createGroupMutation.mutateAsync(data);
navigate(`/groups/${newGroup.name}`);
navigate(`/deployment/groups/${newGroup.name}`);
}}
error={createGroupMutation.error}
isLoading={createGroupMutation.isLoading}
@@ -50,7 +50,7 @@ export const CreateGroupPageView: FC<CreateGroupPageViewProps> = ({
initialTouched,
});
const getFieldHelpers = getFormHelpers<CreateGroupRequest>(form, error);
const onCancel = () => navigate("/groups");
const onCancel = () => navigate("/deployment/groups");
return (
<Margins>
+1 -1
View File
@@ -211,7 +211,7 @@ export const GroupPage: FC = () => {
try {
await deleteGroupMutation.mutateAsync(groupId);
displaySuccess("Group deleted successfully.");
navigate("/groups");
navigate("/deployment/groups");
} catch (error) {
displayError(getErrorMessage(error, "Failed to delete group."));
}
+2 -2
View File
@@ -80,7 +80,7 @@ export const GroupsPageView: FC<GroupsPageViewProps> = ({
canCreateGroup && (
<Button
component={RouterLink}
to="/groups/create"
to="/deployment/groups/create"
startIcon={<AddOutlined />}
variant="contained"
>
@@ -95,7 +95,7 @@ export const GroupsPageView: FC<GroupsPageViewProps> = ({
<Cond>
{groups?.map((group) => {
const groupPageLink = `/groups/${group.name}`;
const groupPageLink = `/deployment/groups/${group.name}`;
return (
<TableRow
@@ -18,7 +18,7 @@ export const SettingsGroupPage: FC = () => {
const navigate = useNavigate();
const navigateToGroup = () => {
navigate(`/groups/${groupName}`);
navigate(`/deployment/groups/${groupName}`);
};
const helmet = (
@@ -56,7 +56,7 @@ export const SettingsGroupPage: FC = () => {
add_users: [],
remove_users: [],
});
navigate(`/groups/${data.name}`, { replace: true });
navigate(`/deployment/groups/${data.name}`, { replace: true });
} catch (error) {
displayError(getErrorMessage(error, "Failed to update group"));
}
+5 -46
View File
@@ -1,80 +1,39 @@
import GroupAdd from "@mui/icons-material/GroupAddOutlined";
import PersonAdd from "@mui/icons-material/PersonAddOutlined";
import Button from "@mui/material/Button";
import { Loader } from "components/Loader/Loader";
import { Margins } from "components/Margins/Margins";
import { PageHeader, PageHeaderTitle } from "components/PageHeader/PageHeader";
import { TAB_PADDING_Y, TabLink, Tabs, TabsList } from "components/Tabs/Tabs";
import { useAuthenticated } from "contexts/auth/RequireAuth";
import { useDashboard } from "modules/dashboard/useDashboard";
import { useFeatureVisibility } from "modules/dashboard/useFeatureVisibility";
import { linkToUsers } from "modules/navigation";
import { type FC, Suspense } from "react";
import {
Outlet,
Link as RouterLink,
useLocation,
useNavigate,
} from "react-router-dom";
import { Outlet, Link as RouterLink } from "react-router-dom";
export const UsersLayout: FC = () => {
const { permissions } = useAuthenticated();
const { showOrganizations } = useDashboard();
const navigate = useNavigate();
const feats = useFeatureVisibility();
const location = useLocation();
const activeTab = location.pathname.endsWith("groups") ? "groups" : "users";
return (
<>
<Margins>
<PageHeader
actions={
<>
{permissions.createUser && (
<Button
onClick={() => {
navigate("/users/create");
}}
startIcon={<PersonAdd />}
>
Create user
</Button>
)}
<div>
{permissions.createGroup && feats.template_rbac && (
<Button
component={RouterLink}
startIcon={<GroupAdd />}
to="/groups/create"
to="/deployment/groups/create"
>
Create group
</Button>
)}
</>
</div>
}
>
<PageHeaderTitle>Users</PageHeaderTitle>
<PageHeaderTitle>Groups</PageHeaderTitle>
</PageHeader>
</Margins>
{!showOrganizations && (
<Tabs
css={{ marginBottom: 40, marginTop: -TAB_PADDING_Y }}
active={activeTab}
>
<Margins>
<TabsList>
<TabLink to={linkToUsers} value="users">
Users
</TabLink>
<TabLink to="/groups" value="groups">
Groups
</TabLink>
</TabsList>
</Margins>
</Tabs>
)}
<Margins>
<Suspense fallback={<Loader />}>
<Outlet />
+14 -3
View File
@@ -353,7 +353,7 @@ const templateRouter = () => {
);
};
const groupsRouter = () => {
const organizationGroupsRouter = () => {
return (
<Route path="groups">
<Route index element={<OrganizationGroupsPage />} />
@@ -433,7 +433,7 @@ export const router = createBrowserRouter(
<Route path=":organization" element={<OrganizationSidebarLayout />}>
<Route index element={<OrganizationMembersPage />} />
{groupsRouter()}
{organizationGroupsRouter()}
<Route path="roles">
<Route index element={<OrganizationCustomRolesPage />} />
<Route path="create" element={<CreateEditRolePage />} />
@@ -488,7 +488,18 @@ export const router = createBrowserRouter(
<Route path="users" element={<UsersPage />} />
<Route path="users/create" element={<CreateUserPage />} />
{groupsRouter()}
<Route path="groups">
<Route element={<UsersLayout />}>
<Route index element={<GroupsPage />} />
</Route>
<Route path="create" element={<CreateGroupPage />} />
<Route path=":groupName" element={<GroupPage />} />
<Route
path=":groupName/settings"
element={<SettingsGroupPage />}
/>
</Route>
</Route>
<Route path="/settings" element={<UserSettingsLayout />}>