Skip to content

fix: only show editable orgs on deployment page #14193

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Tuples-b-gone
  • Loading branch information
code-asher committed Aug 8, 2024
commit b86684d26b199f000c8d3eae168fce5e7cb688cd
19 changes: 13 additions & 6 deletions site/src/pages/ManagementSettingsPage/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@ import type { FC } from "react";
import { useQuery } from "react-query";
import { useLocation, useParams } from "react-router-dom";
import { organizationsPermissions } from "api/queries/organizations";
import type { AuthorizationResponse, Organization } from "api/typesGenerated";
import { useAuthenticated } from "contexts/auth/RequireAuth";
import {
canEditOrganization,
useOrganizationSettings,
} from "./ManagementSettingsLayout";
import { SidebarView } from "./SidebarView";
import { type OrganizationWithPermissions, SidebarView } from "./SidebarView";

/**
* A combined deployment settings and organization menu.
Expand All @@ -34,11 +33,19 @@ export const Sidebar: FC = () => {
// can manage in some way.
const editableOrgs = organizations
?.map((org) => {
const permissions = orgPermissionsQuery.data?.[org.id];
return [org, permissions] as [Organization, AuthorizationResponse];
return {
...org,
permissions: orgPermissionsQuery.data?.[org.id],
};
})
.filter(([_, permissions]) => {
return canEditOrganization(permissions);
// TypeScript is not able to infer whether permissions are defined from the
// canEditOrganization call, so although redundant this helps figure it out.
.filter(
(org): org is OrganizationWithPermissions =>
org.permissions !== undefined,
)
.filter((org) => {
return canEditOrganization(org.permissions);
});

return (
Expand Down
72 changes: 36 additions & 36 deletions site/src/pages/ManagementSettingsPage/SidebarView.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,24 @@ const meta: Meta<typeof SidebarView> = {
activeSettings: true,
activeOrganizationName: undefined,
organizations: [
[
MockOrganization,
{
{
...MockOrganization,
permissions: {
editOrganization: true,
editMembers: true,
editGroups: true,
auditOrganization: true,
},
],
[
MockOrganization2,
{
},
{
...MockOrganization2,
permissions: {
editOrganization: true,
editMembers: true,
editGroups: true,
auditOrganization: true,
},
],
},
],
permissions: MockPermissions,
},
Expand Down Expand Up @@ -114,15 +114,15 @@ export const SelectedOrgAdmin: Story = {
args: {
activeOrganizationName: MockOrganization.name,
organizations: [
[
MockOrganization,
{
{
...MockOrganization,
permissions: {
editOrganization: true,
editMembers: true,
editGroups: true,
auditOrganization: true,
},
],
},
],
},
};
Expand All @@ -135,15 +135,15 @@ export const SelectedOrgAuditor: Story = {
createOrganization: false,
},
organizations: [
[
MockOrganization,
{
{
...MockOrganization,
permissions: {
editOrganization: false,
editMembers: false,
editGroups: false,
auditOrganization: true,
},
],
},
],
},
};
Expand All @@ -156,40 +156,40 @@ export const SelectedOrgUserAdmin: Story = {
createOrganization: false,
},
organizations: [
[
MockOrganization,
{
{
...MockOrganization,
permissions: {
editOrganization: false,
editMembers: true,
editGroups: true,
auditOrganization: false,
},
],
},
],
},
};

export const MultiOrgAdminAndUserAdmin: Story = {
args: {
organizations: [
[
MockOrganization,
{
{
...MockOrganization,
permissions: {
editOrganization: false,
editMembers: false,
editGroups: false,
auditOrganization: true,
},
],
[
MockOrganization2,
{
},
{
...MockOrganization2,
permissions: {
editOrganization: false,
editMembers: true,
editGroups: true,
auditOrganization: false,
},
],
},
],
},
};
Expand All @@ -198,24 +198,24 @@ export const SelectedMultiOrgAdminAndUserAdmin: Story = {
args: {
activeOrganizationName: MockOrganization2.name,
organizations: [
[
MockOrganization,
{
{
...MockOrganization,
permissions: {
editOrganization: false,
editMembers: false,
editGroups: false,
auditOrganization: true,
},
],
[
MockOrganization2,
{
},
{
...MockOrganization2,
permissions: {
editOrganization: false,
editMembers: true,
editGroups: true,
auditOrganization: false,
},
],
},
],
},
};
23 changes: 12 additions & 11 deletions site/src/pages/ManagementSettingsPage/SidebarView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@ import { UserAvatar } from "components/UserAvatar/UserAvatar";
import { type ClassName, useClassName } from "hooks/useClassName";
import { linkToAuditing, linkToUsers, withFilter } from "modules/navigation";

export interface OrganizationWithPermissions extends Organization {
permissions: AuthorizationResponse;
}

interface SidebarProps {
/** True if a settings page is being viewed. */
activeSettings: boolean;
/** The active org name, if any. Overrides activeSettings. */
activeOrganizationName: string | undefined;
/** Organizations and their permissions or undefined if still fetching. */
organizations: [Organization, AuthorizationResponse][] | undefined;
organizations: OrganizationWithPermissions[] | undefined;
/** Site-wide permissions. */
permissions: AuthorizationResponse;
}
Expand Down Expand Up @@ -137,7 +141,7 @@ interface OrganizationsSettingsNavigationProps {
/** The active org name if an org is being viewed. */
activeOrganizationName: string | undefined;
/** Organizations and their permissions or undefined if still fetching. */
organizations: [Organization, AuthorizationResponse][] | undefined;
organizations: OrganizationWithPermissions[] | undefined;
/** Site-wide permissions. */
permissions: AuthorizationResponse;
}
Expand Down Expand Up @@ -177,11 +181,10 @@ const OrganizationsSettingsNavigation: FC<
New organization
</SidebarNavItem>
)}
{props.organizations.map(([org, permissions]) => (
{props.organizations.map((org) => (
<OrganizationSettingsNavigation
key={org.id}
organization={org}
permissions={permissions}
active={org.name === props.activeOrganizationName}
/>
))}
Expand All @@ -193,9 +196,7 @@ interface OrganizationSettingsNavigationProps {
/** Whether this organization is currently selected. */
active: boolean;
/** The organization to display in the navigation. */
organization: Organization;
/** The permissions for this organization. */
permissions: AuthorizationResponse;
organization: OrganizationWithPermissions;
}

/**
Expand Down Expand Up @@ -226,22 +227,22 @@ const OrganizationSettingsNavigation: FC<
</SidebarNavItem>
{props.active && (
<Stack spacing={0.5} css={{ marginBottom: 8, marginTop: 8 }}>
{props.permissions.editOrganization && (
{props.organization.permissions.editOrganization && (
<SidebarNavSubItem
end
href={urlForSubpage(props.organization.name)}
>
Organization settings
</SidebarNavSubItem>
)}
{props.permissions.editMembers && (
{props.organization.permissions.editMembers && (
<SidebarNavSubItem
href={urlForSubpage(props.organization.name, "members")}
>
Members
</SidebarNavSubItem>
)}
{props.permissions.editGroups && (
{props.organization.permissions.editGroups && (
<SidebarNavSubItem
href={urlForSubpage(props.organization.name, "groups")}
>
Expand All @@ -251,7 +252,7 @@ const OrganizationSettingsNavigation: FC<
{/* For now redirect to the site-wide audit page with the organization
pre-filled into the filter. Based on user feedback we might want
to serve a copy of the audit page or even delete this link. */}
{props.permissions.auditOrganization && (
{props.organization.permissions.auditOrganization && (
<SidebarNavSubItem
href={`/deployment${withFilter(
linkToAuditing,
Expand Down