Skip to content

Commit 9a47ea1

Browse files
authored
chore: move back to single audit log page (#14212)
* chore: remove per-org audit links For now at least, we will have the one audit page at /audit which lets you filter by organization. This also removes the need to do per-org audit permission checks. * Filter audit org dropdown by auditable orgs Previously all orgs you can list would appear, but you might not be able to audit all of them.
1 parent 6019d0b commit 9a47ea1

File tree

8 files changed

+55
-90
lines changed

8 files changed

+55
-90
lines changed

site/src/api/queries/organizations.ts

+6-13
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,9 @@ export const organizationPermissions = (organizationId: string | undefined) => {
135135
queryKey: ["organization", organizationId, "permissions"],
136136
queryFn: () =>
137137
// Only request what we use on individual org settings, members, and group
138-
// pages, which at the moment is whether you can edit the members or roles
139-
// on the members page and whether you can see the create group button on
140-
// the groups page. The edit organization check for the settings page is
138+
// pages, which at the moment is whether you can edit the members on the
139+
// members page, create roles on the roles page, and create groups on the
140+
// groups page. The edit organization check for the settings page is
141141
// covered by the multi-org query at the moment, and the edit group check
142142
// on the group page is done on the group itself, not the org, so neither
143143
// show up here.
@@ -185,9 +185,9 @@ export const organizationsPermissions = (
185185
queryKey: ["organizations", organizationIds.sort(), "permissions"],
186186
queryFn: async () => {
187187
// Only request what we need for the sidebar, which is one edit permission
188-
// per sub-link (audit, settings, groups, roles, and members pages) that
189-
// tells us whether to show that page, since we only show them if you can
190-
// edit (and not, at the moment if you can only view).
188+
// per sub-link (settings, groups, roles, and members pages) that tells us
189+
// whether to show that page, since we only show them if you can edit (and
190+
// not, at the moment if you can only view).
191191
const checks = (organizationId: string) => ({
192192
editMembers: {
193193
object: {
@@ -210,13 +210,6 @@ export const organizationsPermissions = (
210210
},
211211
action: "update",
212212
},
213-
auditOrganization: {
214-
object: {
215-
resource_type: "audit_log",
216-
organization_id: organizationId,
217-
},
218-
action: "read",
219-
},
220213
assignOrgRole: {
221214
object: {
222215
resource_type: "assign_org_role",

site/src/components/Filter/filter.tsx

+5-8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import Divider from "@mui/material/Divider";
66
import Menu from "@mui/material/Menu";
77
import MenuItem from "@mui/material/MenuItem";
88
import Skeleton, { type SkeletonProps } from "@mui/material/Skeleton";
9+
import type { Breakpoint } from "@mui/system/createTheme";
910
import { type FC, type ReactNode, useEffect, useRef, useState } from "react";
1011
import type { useSearchParams } from "react-router-dom";
1112
import {
@@ -142,8 +143,7 @@ type FilterProps = {
142143
error?: unknown;
143144
options?: ReactNode;
144145
presets: PresetFilter[];
145-
/** Set to true if there is not much horizontal space. */
146-
compact?: boolean;
146+
breakpoint?: Breakpoint;
147147
};
148148

149149
export const Filter: FC<FilterProps> = ({
@@ -156,7 +156,7 @@ export const Filter: FC<FilterProps> = ({
156156
learnMoreLabel2,
157157
learnMoreLink2,
158158
presets,
159-
compact,
159+
breakpoint = "md",
160160
}) => {
161161
const theme = useTheme();
162162
// Storing local copy of the filter query so that it can be updated more
@@ -187,12 +187,9 @@ export const Filter: FC<FilterProps> = ({
187187
display: "flex",
188188
gap: 8,
189189
marginBottom: 16,
190-
// For now compact just means immediately wrapping, but maybe we should
191-
// have a collapsible section or consolidate into one menu or something.
192-
// TODO: Remove separate compact mode once multi-org is stable.
193-
flexWrap: compact ? "wrap" : "nowrap",
190+
flexWrap: "nowrap",
194191

195-
[theme.breakpoints.down("md")]: {
192+
[theme.breakpoints.down(breakpoint)]: {
196193
flexWrap: "wrap",
197194
},
198195
}}

site/src/modules/dashboard/Navbar/DeploymentDropdown.tsx

+1-5
Original file line numberDiff line numberDiff line change
@@ -124,11 +124,7 @@ const DeploymentDropdownContent: FC<DeploymentDropdownProps> = ({
124124
{canViewAuditLog && (
125125
<MenuItem
126126
component={NavLink}
127-
to={
128-
canViewOrganizations
129-
? `/deployment${linkToAuditing}`
130-
: linkToAuditing
131-
}
127+
to={linkToAuditing}
132128
css={styles.menuItem}
133129
onClick={onPopoverClose}
134130
>

site/src/pages/AuditPage/AuditFilter.tsx

+36-19
Original file line numberDiff line numberDiff line change
@@ -51,23 +51,23 @@ interface AuditFilterProps {
5151
}
5252

5353
export const AuditFilter: FC<AuditFilterProps> = ({ filter, error, menus }) => {
54+
// Use a smaller width if including the organization filter.
55+
const width = menus.organization && 175;
5456
return (
5557
<Filter
5658
learnMoreLink={docs("/admin/audit-logs#filtering-logs")}
5759
presets={PRESET_FILTERS}
5860
isLoading={menus.user.isInitializing}
5961
filter={filter}
6062
error={error}
61-
// There is not much space with the sidebar and four filters, so in this
62-
// case we will use the compact mode.
63-
compact={Boolean(menus.organization)}
63+
breakpoint={menus.organization && "lg"}
6464
options={
6565
<>
66-
<ResourceTypeMenu menu={menus.resourceType} />
67-
<ActionMenu menu={menus.action} />
68-
<UserMenu menu={menus.user} />
66+
<ResourceTypeMenu width={width} menu={menus.resourceType} />
67+
<ActionMenu width={width} menu={menus.action} />
68+
<UserMenu width={width} menu={menus.user} />
6969
{menus.organization && (
70-
<OrganizationsMenu menu={menus.organization} />
70+
<OrganizationsMenu width={width} menu={menus.organization} />
7171
)}
7272
</>
7373
}
@@ -211,19 +211,36 @@ export const useOrganizationsFilterMenu = ({
211211
return null;
212212
},
213213
getOptions: async () => {
214-
const organizationsRes = await API.getOrganizations();
215-
return organizationsRes.map<SelectFilterOption>((organization) => ({
216-
label: organization.display_name || organization.name,
217-
value: organization.name,
218-
startIcon: (
219-
<UserAvatar
220-
key={organization.id}
221-
size="xs"
222-
username={organization.display_name || organization.name}
223-
avatarURL={organization.icon}
224-
/>
214+
// Only show the organizations for which you can view audit logs.
215+
const organizations = await API.getOrganizations();
216+
const permissions = await API.checkAuthorization({
217+
checks: Object.fromEntries(
218+
organizations.map((organization) => [
219+
organization.id,
220+
{
221+
object: {
222+
resource_type: "audit_log",
223+
organization_id: organization.id,
224+
},
225+
action: "read",
226+
},
227+
]),
225228
),
226-
}));
229+
});
230+
return organizations
231+
.filter((organization) => permissions[organization.id])
232+
.map<SelectFilterOption>((organization) => ({
233+
label: organization.display_name || organization.name,
234+
value: organization.name,
235+
startIcon: (
236+
<UserAvatar
237+
key={organization.id}
238+
size="xs"
239+
username={organization.display_name || organization.name}
240+
avatarURL={organization.icon}
241+
/>
242+
),
243+
}));
227244
},
228245
});
229246
};

site/src/pages/AuditPage/AuditPage.tsx

+4-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { FC } from "react";
22
import { Helmet } from "react-helmet-async";
3-
import { useSearchParams, Navigate, useLocation } from "react-router-dom";
3+
import { useSearchParams } from "react-router-dom";
44
import { paginatedAudits } from "api/queries/audits";
55
import { useFilter } from "components/Filter/filter";
66
import { useUserFilterMenu } from "components/Filter/UserFilter";
@@ -19,7 +19,6 @@ import { AuditPageView } from "./AuditPageView";
1919
const AuditPage: FC = () => {
2020
const feats = useFeatureVisibility();
2121
const { experiments } = useDashboard();
22-
const location = useLocation();
2322

2423
/**
2524
* There is an implicit link between auditsQuery and filter via the
@@ -71,14 +70,9 @@ const AuditPage: FC = () => {
7170
}),
7271
});
7372

74-
// TODO: Once multi-org is stable, we should place this redirect into the
75-
// router directly, if we still need to maintain it (for users who are
76-
// typing the old URL manually or have it bookmarked).
77-
const canViewOrganizations =
78-
feats.multiple_organizations && experiments.includes("multi-organization");
79-
if (canViewOrganizations && location.pathname !== "/deployment/audit") {
80-
return <Navigate to={`/deployment/audit${location.search}`} replace />;
81-
}
73+
// With the multi-organization experiment enabled, show extra organization
74+
// info and the organization filter dropdon.
75+
const canViewOrganizations = experiments.includes("multi-organization");
8276

8377
return (
8478
<>

site/src/pages/AuditPage/AuditPageView.tsx

+2-14
Original file line numberDiff line numberDiff line change
@@ -57,20 +57,8 @@ export const AuditPageView: FC<AuditPageViewProps> = ({
5757
const isEmpty = !isLoading && auditLogs?.length === 0;
5858

5959
return (
60-
<Margins
61-
css={{
62-
// When acting as a deployment settings page, there is already padding.
63-
// TODO: When multi-org is stable we should move this to the deployment
64-
// settings dir, use the standard header, and remove these margins.
65-
padding: showOrgDetails ? 0 : undefined,
66-
}}
67-
>
68-
<PageHeader
69-
css={{
70-
// When acting as a deployment settings page, there is already padding.
71-
paddingTop: showOrgDetails ? 0 : undefined,
72-
}}
73-
>
60+
<Margins>
61+
<PageHeader>
7462
<PageHeaderTitle>
7563
<Stack direction="row" spacing={1} alignItems="center">
7664
<span>{Language.title}</span>

site/src/pages/ManagementSettingsPage/SidebarView.tsx

+1-19
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { Stack } from "components/Stack/Stack";
1111
import { UserAvatar } from "components/UserAvatar/UserAvatar";
1212
import { type ClassName, useClassName } from "hooks/useClassName";
1313
import { useDashboard } from "modules/dashboard/useDashboard";
14-
import { linkToAuditing, linkToUsers, withFilter } from "modules/navigation";
14+
import { linkToUsers } from "modules/navigation";
1515

1616
export interface OrganizationWithPermissions extends Organization {
1717
permissions: AuthorizationResponse;
@@ -133,11 +133,6 @@ const DeploymentSettingsNavigation: FC<DeploymentSettingsNavigationProps> = ({
133133
Users
134134
</SidebarNavSubItem>
135135
)}
136-
{permissions.viewAnyAuditLog && (
137-
<SidebarNavSubItem href={linkToAuditing.slice(1)}>
138-
Auditing
139-
</SidebarNavSubItem>
140-
)}
141136
</Stack>
142137
)}
143138
</div>
@@ -264,19 +259,6 @@ const OrganizationSettingsNavigation: FC<
264259
Roles
265260
</SidebarNavSubItem>
266261
)}
267-
{/* For now redirect to the site-wide audit page with the organization
268-
pre-filled into the filter. Based on user feedback we might want
269-
to serve a copy of the audit page or even delete this link. */}
270-
{organization.permissions.auditOrganization && (
271-
<SidebarNavSubItem
272-
href={`/deployment${withFilter(
273-
linkToAuditing,
274-
`organization:${organization.name}`,
275-
)}`}
276-
>
277-
Auditing
278-
</SidebarNavSubItem>
279-
)}
280262
</Stack>
281263
)}
282264
</>

site/src/router.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,6 @@ export const router = createBrowserRouter(
389389
<Route path="create" element={<CreateEditRolePage />} />
390390
<Route path=":roleName" element={<CreateEditRolePage />} />
391391
</Route>
392-
<Route path="auditing" element={<></>} />
393392
</Route>
394393
</Route>
395394

@@ -423,7 +422,6 @@ export const router = createBrowserRouter(
423422
<Route path="users" element={<UsersPage />} />
424423
<Route path="users/create" element={<CreateUserPage />} />
425424
{groupsRouter()}
426-
<Route path="audit" element={<AuditPage />} />
427425
</Route>
428426

429427
<Route path="/settings" element={<UserSettingsLayout />}>

0 commit comments

Comments
 (0)