diff --git a/site/e2e/tests/auditLogs.spec.ts b/site/e2e/tests/auditLogs.spec.ts index 8afb2e714c695..31d3208c636fa 100644 --- a/site/e2e/tests/auditLogs.spec.ts +++ b/site/e2e/tests/auditLogs.spec.ts @@ -35,7 +35,6 @@ test("logins are logged", async ({ page }) => { await page.goto("/audit"); const username = users.auditor.username; - const user = currentUser(page); const loginMessage = `${username} logged in`; // Make sure those things we did all actually show up await resetSearch(page, username); diff --git a/site/src/pages/GroupsPage/GroupsPage.tsx b/site/src/pages/GroupsPage/GroupsPage.tsx index a99ec44334530..d5ef810f9ff9d 100644 --- a/site/src/pages/GroupsPage/GroupsPage.tsx +++ b/site/src/pages/GroupsPage/GroupsPage.tsx @@ -2,7 +2,6 @@ import GroupAdd from "@mui/icons-material/GroupAddOutlined"; import { getErrorMessage } from "api/errors"; import { groupsByOrganization } from "api/queries/groups"; import { organizationsPermissions } from "api/queries/organizations"; -import { ErrorAlert } from "components/Alert/ErrorAlert"; import { Button } from "components/Button/Button"; import { EmptyState } from "components/EmptyState/EmptyState"; import { displayError } from "components/GlobalSnackbar/utils"; @@ -10,6 +9,7 @@ import { Loader } from "components/Loader/Loader"; import { SettingsHeader } from "components/SettingsHeader/SettingsHeader"; import { Stack } from "components/Stack/Stack"; import { useFeatureVisibility } from "modules/dashboard/useFeatureVisibility"; +import { RequirePermission } from "modules/permissions/RequirePermission"; import { type FC, useEffect } from "react"; import { Helmet } from "react-helmet-async"; import { useQuery } from "react-query"; @@ -54,16 +54,26 @@ export const GroupsPage: FC = () => { return ; } + const helmet = ( + + {pageTitle("Groups")} + + ); + const permissions = permissionsQuery.data?.[organization.id]; - if (!permissions) { - return ; + + if (!permissions?.viewGroups) { + return ( + <> + {helmet} + + + ); } return ( <> - - {pageTitle("Groups")} - + {helmet} { const { organization: organizationName } = useParams() as { organization: string; }; - const { organizationPermissions } = useOrganizationSettings(); + const { organization, organizationPermissions } = useOrganizationSettings(); const [roleToDelete, setRoleToDelete] = useState(); @@ -49,65 +49,67 @@ export const CustomRolesPage: FC = () => { } }, [organizationRolesQuery.error]); - if (!organizationPermissions) { - return ; + if (!organization) { + return ; } return ( - + <> - {pageTitle("Custom Roles")} + + {pageTitle( + "Custom Roles", + organization.display_name || organization.name, + )} + - - - - + + + - + - setRoleToDelete(undefined)} - onConfirm={async () => { - try { - if (roleToDelete) { - await deleteRoleMutation.mutateAsync(roleToDelete.name); + setRoleToDelete(undefined)} + onConfirm={async () => { + try { + if (roleToDelete) { + await deleteRoleMutation.mutateAsync(roleToDelete.name); + } + setRoleToDelete(undefined); + await organizationRolesQuery.refetch(); + displaySuccess("Custom role deleted successfully!"); + } catch (error) { + displayError( + getErrorMessage(error, "Failed to delete custom role"), + ); } - setRoleToDelete(undefined); - await organizationRolesQuery.refetch(); - displaySuccess("Custom role deleted successfully!"); - } catch (error) { - displayError( - getErrorMessage(error, "Failed to delete custom role"), - ); - } - }} - /> - + }} + /> + + ); }; diff --git a/site/src/pages/OrganizationSettingsPage/IdpSyncPage/IdpSyncPage.tsx b/site/src/pages/OrganizationSettingsPage/IdpSyncPage/IdpSyncPage.tsx index 91d138ed26a5a..613572348a1c3 100644 --- a/site/src/pages/OrganizationSettingsPage/IdpSyncPage/IdpSyncPage.tsx +++ b/site/src/pages/OrganizationSettingsPage/IdpSyncPage/IdpSyncPage.tsx @@ -16,6 +16,7 @@ import { Link } from "components/Link/Link"; import { Paywall } from "components/Paywall/Paywall"; import { useFeatureVisibility } from "modules/dashboard/useFeatureVisibility"; import { useOrganizationSettings } from "modules/management/OrganizationSettingsLayout"; +import { RequirePermission } from "modules/permissions/RequirePermission"; import { type FC, useEffect, useState } from "react"; import { Helmet } from "react-helmet-async"; import { useMutation, useQueries, useQuery, useQueryClient } from "react-query"; @@ -31,8 +32,7 @@ export const IdpSyncPage: FC = () => { const { organization: organizationName } = useParams() as { organization: string; }; - const { organizations } = useOrganizationSettings(); - const organization = organizations?.find((o) => o.name === organizationName); + const { organization, organizationPermissions } = useOrganizationSettings(); const [groupField, setGroupField] = useState(""); const [roleField, setRoleField] = useState(""); @@ -80,6 +80,23 @@ export const IdpSyncPage: FC = () => { return ; } + const helmet = ( + + + {pageTitle("IdP Sync", organization.display_name || organization.name)} + + + ); + + if (!organizationPermissions?.viewIdpSyncSettings) { + return ( + <> + {helmet} + + + ); + } + const patchGroupSyncSettingsMutation = useMutation( patchGroupSyncSettings(organizationName, queryClient), ); @@ -103,9 +120,7 @@ export const IdpSyncPage: FC = () => { return ( <> - - {pageTitle("IdP Sync")} - + {helmet}
diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationMembersPage.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationMembersPage.tsx index 7ae0eb72bec91..ffa7b08b83742 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationMembersPage.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationMembersPage.tsx @@ -15,6 +15,7 @@ import { displayError, displaySuccess } from "components/GlobalSnackbar/utils"; import { Stack } from "components/Stack/Stack"; import { useAuthenticated } from "contexts/auth/RequireAuth"; import { useOrganizationSettings } from "modules/management/OrganizationSettingsLayout"; +import { RequirePermission } from "modules/permissions/RequirePermission"; import { type FC, useState } from "react"; import { Helmet } from "react-helmet-async"; import { useMutation, useQuery, useQueryClient } from "react-query"; @@ -54,7 +55,7 @@ const OrganizationMembersPage: FC = () => { const [memberToDelete, setMemberToDelete] = useState(); - if (!organization || !organizationPermissions) { + if (!organization) { return ; } @@ -66,6 +67,15 @@ const OrganizationMembersPage: FC = () => { ); + if (!organizationPermissions) { + return ( + <> + {helmet} + + + ); + } + return ( <> {helmet} diff --git a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionersPage.tsx b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionersPage.tsx index 5a4965c039e1f..fc736975c07f5 100644 --- a/site/src/pages/OrganizationSettingsPage/OrganizationProvisionersPage.tsx +++ b/site/src/pages/OrganizationSettingsPage/OrganizationProvisionersPage.tsx @@ -4,6 +4,7 @@ import { EmptyState } from "components/EmptyState/EmptyState"; import { useEmbeddedMetadata } from "hooks/useEmbeddedMetadata"; import { useDashboard } from "modules/dashboard/useDashboard"; import { useOrganizationSettings } from "modules/management/OrganizationSettingsLayout"; +import { RequirePermission } from "modules/permissions/RequirePermission"; import type { FC } from "react"; import { Helmet } from "react-helmet-async"; import { useQuery } from "react-query"; @@ -15,7 +16,7 @@ const OrganizationProvisionersPage: FC = () => { const { organization: organizationName } = useParams() as { organization: string; }; - const { organization } = useOrganizationSettings(); + const { organization, organizationPermissions } = useOrganizationSettings(); const { entitlements } = useDashboard(); const { metadata } = useEmbeddedMetadata(); const buildInfoQuery = useQuery(buildInfo(metadata["build-info"])); @@ -25,16 +26,29 @@ const OrganizationProvisionersPage: FC = () => { return ; } + const helmet = ( + + + {pageTitle( + "Provisioners", + organization.display_name || organization.name, + )} + + + ); + + if (!organizationPermissions?.viewProvisioners) { + return ( + <> + {helmet} + + + ); + } + return ( <> - - - {pageTitle( - "Provisioners", - organization.display_name || organization.name, - )} - - + {helmet} { @@ -24,36 +27,58 @@ const OrganizationSettingsPage: FC = () => { deleteOrganization(queryClient), ); - if (!organization || !organizationPermissions?.editSettings) { + if (!organization) { return ; } + const helmet = ( + + + {pageTitle("Settings", organization.display_name || organization.name)} + + + ); + + if (!organizationPermissions?.editSettings) { + return ( + <> + {helmet} + + + ); + } + const error = updateOrganizationMutation.error ?? deleteOrganizationMutation.error; return ( - { - const updatedOrganization = - await updateOrganizationMutation.mutateAsync({ - organizationId: organization.id, - req: values, - }); - navigate(`/organizations/${updatedOrganization.name}/settings`); - displaySuccess("Organization settings updated."); - }} - onDeleteOrganization={async () => { - try { - await deleteOrganizationMutation.mutateAsync(organization.id); - displaySuccess("Organization deleted"); - navigate("/organizations"); - } catch (error) { - displayError(getErrorMessage(error, "Failed to delete organization")); - } - }} - /> + <> + {helmet} + { + const updatedOrganization = + await updateOrganizationMutation.mutateAsync({ + organizationId: organization.id, + req: values, + }); + navigate(`/organizations/${updatedOrganization.name}/settings`); + displaySuccess("Organization settings updated."); + }} + onDeleteOrganization={async () => { + try { + await deleteOrganizationMutation.mutateAsync(organization.id); + displaySuccess("Organization deleted"); + navigate("/organizations"); + } catch (error) { + displayError( + getErrorMessage(error, "Failed to delete organization"), + ); + } + }} + /> + ); }; diff --git a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionersPage.tsx b/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionersPage.tsx index 051f916c3ad99..ced95a95e02c0 100644 --- a/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionersPage.tsx +++ b/site/src/pages/OrganizationSettingsPage/ProvisionersPage/ProvisionersPage.tsx @@ -2,6 +2,7 @@ import { EmptyState } from "components/EmptyState/EmptyState"; import { TabLink, Tabs, TabsList } from "components/Tabs/Tabs"; import { useSearchParamsKey } from "hooks/useSearchParamsKey"; import { useOrganizationSettings } from "modules/management/OrganizationSettingsLayout"; +import { RequirePermission } from "modules/permissions/RequirePermission"; import type { FC } from "react"; import { Helmet } from "react-helmet-async"; import { pageTitle } from "utils/page"; @@ -16,26 +17,32 @@ const ProvisionersPage: FC = () => { }); if (!organization || !organizationPermissions?.viewProvisionerJobs) { + return ; + } + + const helmet = ( + + + {pageTitle( + "Provisioners", + organization.display_name || organization.name, + )} + + + ); + + if (!organizationPermissions?.viewProvisioners) { return ( <> - - {pageTitle("Provisioners")} - - + {helmet} + ); } return ( <> - - - {pageTitle( - "Provisioners", - organization.display_name || organization.name, - )} - - + {helmet}
diff --git a/site/src/pages/TemplatePage/TemplatePageHeader.tsx b/site/src/pages/TemplatePage/TemplatePageHeader.tsx index b04a2c6d103f5..7bb1d9e54a4c2 100644 --- a/site/src/pages/TemplatePage/TemplatePageHeader.tsx +++ b/site/src/pages/TemplatePage/TemplatePageHeader.tsx @@ -168,7 +168,6 @@ export const TemplatePageHeader: FC = ({ onDeleteTemplate, }) => { const getLink = useLinks(); - const hasIcon = template.icon && template.icon !== ""; const templateLink = getLink( linkToTemplate(template.organization_name, template.name), ); diff --git a/site/src/pages/UserSettingsPage/ExternalAuthPage/ExternalAuthPageView.tsx b/site/src/pages/UserSettingsPage/ExternalAuthPage/ExternalAuthPageView.tsx index 5cb1e4fddeac0..845918a7b75ed 100644 --- a/site/src/pages/UserSettingsPage/ExternalAuthPage/ExternalAuthPageView.tsx +++ b/site/src/pages/UserSettingsPage/ExternalAuthPage/ExternalAuthPageView.tsx @@ -110,25 +110,6 @@ interface ExternalAuthRowProps { onValidateExternalAuth: () => void; } -const StyledBadge = styled(Badge)(({ theme }) => ({ - "& .MuiBadge-badge": { - // Make a circular background for the icon. Background provides contrast, with a thin - // border to separate it from the avatar image. - backgroundColor: `${theme.palette.background.paper}`, - borderStyle: "solid", - borderColor: `${theme.palette.secondary.main}`, - borderWidth: "thin", - - // Override the default minimum sizes, as they are larger than what we want. - minHeight: "0px", - minWidth: "0px", - // Override the default "height", which is usually set to some constant value. - height: "auto", - // Padding adds some room for the icon to live in. - padding: "0.1em", - }, -})); - const ExternalAuthRow: FC = ({ app, unlinked, diff --git a/site/src/pages/UserSettingsPage/Sidebar.tsx b/site/src/pages/UserSettingsPage/Sidebar.tsx index 5cc8c54dcbda9..69d51ae3bb227 100644 --- a/site/src/pages/UserSettingsPage/Sidebar.tsx +++ b/site/src/pages/UserSettingsPage/Sidebar.tsx @@ -22,7 +22,7 @@ interface SidebarProps { } export const Sidebar: FC = ({ user }) => { - const { entitlements, experiments } = useDashboard(); + const { entitlements } = useDashboard(); const showSchedulePage = entitlements.features.advanced_template_scheduling.enabled; diff --git a/site/src/pages/UsersPage/UsersPage.tsx b/site/src/pages/UsersPage/UsersPage.tsx index 9d2aaadefc96d..c8677e3a44f47 100644 --- a/site/src/pages/UsersPage/UsersPage.tsx +++ b/site/src/pages/UsersPage/UsersPage.tsx @@ -23,7 +23,7 @@ import { useDashboard } from "modules/dashboard/useDashboard"; import { type FC, useState } from "react"; import { Helmet } from "react-helmet-async"; import { useMutation, useQuery, useQueryClient } from "react-query"; -import { useLocation, useNavigate, useSearchParams } from "react-router-dom"; +import { useNavigate, useSearchParams } from "react-router-dom"; import { pageTitle } from "utils/page"; import { generateRandomString } from "utils/random"; import { ResetPasswordDialog } from "./ResetPasswordDialog"; @@ -39,7 +39,6 @@ type UserPageProps = { const UsersPage: FC = ({ defaultNewPassword }) => { const queryClient = useQueryClient(); const navigate = useNavigate(); - const location = useLocation(); const searchParamsResult = useSearchParams(); const { entitlements } = useDashboard(); const [searchParams] = searchParamsResult; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy