Skip to content

Commit 785f67b

Browse files
committed
Add basic diff
1 parent 38955a8 commit 785f67b

File tree

4 files changed

+191
-37
lines changed

4 files changed

+191
-37
lines changed

site/src/components/Stack/Stack.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ import { combineClasses } from "../../util/combineClasses"
66

77
type Direction = "column" | "row"
88

9-
export interface StackProps {
9+
export type StackProps = {
1010
className?: string
1111
direction?: Direction
1212
spacing?: number
1313
alignItems?: CSSProperties["alignItems"]
1414
justifyContent?: CSSProperties["justifyContent"]
15-
}
15+
} & React.HTMLProps<HTMLDivElement>
1616

1717
type StyleProps = Omit<StackProps, "className">
1818

@@ -37,6 +37,7 @@ export const Stack: FC<StackProps & { children: ReactNode | ReactNode[] }> = ({
3737
spacing = 2,
3838
alignItems,
3939
justifyContent,
40+
...divProps
4041
}) => {
4142
const styles = useStyles({
4243
spacing,
@@ -45,5 +46,9 @@ export const Stack: FC<StackProps & { children: ReactNode | ReactNode[] }> = ({
4546
justifyContent,
4647
})
4748

48-
return <div className={combineClasses([styles.stack, className])}>{children}</div>
49+
return (
50+
<div {...divProps} className={combineClasses([styles.stack, className])}>
51+
{children}
52+
</div>
53+
)
4954
}

site/src/pages/AuditPage/AuditPageView.stories.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ComponentMeta, Story } from "@storybook/react"
2-
import { MockAuditLog } from "testHelpers/entities"
2+
import { MockAuditLog, MockAuditLogWithDiff } from "testHelpers/entities"
33
import { AuditPageView } from "./AuditPageView"
44

55
export default {
@@ -11,7 +11,7 @@ const Template: Story = (args) => <AuditPageView {...args} />
1111

1212
export const AuditPage = Template.bind({})
1313
AuditPage.args = {
14-
auditLogs: [MockAuditLog, MockAuditLog],
14+
auditLogs: [MockAuditLog, MockAuditLog, MockAuditLogWithDiff],
1515
}
1616

1717
export const AuditPageSmallViewport = Template.bind({})

site/src/pages/AuditPage/AuditPageView.tsx

Lines changed: 149 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import Collapse from "@material-ui/core/Collapse"
12
import { makeStyles } from "@material-ui/core/styles"
23
import Table from "@material-ui/core/Table"
34
import TableBody from "@material-ui/core/TableBody"
@@ -7,16 +8,102 @@ import TableHead from "@material-ui/core/TableHead"
78
import TableRow from "@material-ui/core/TableRow"
89
import { AuditLog } from "api/api"
910
import { CodeExample } from "components/CodeExample/CodeExample"
11+
import { CloseDropdown, OpenDropdown } from "components/DropdownArrows/DropdownArrows"
1012
import { Margins } from "components/Margins/Margins"
1113
import { PageHeader, PageHeaderSubtitle, PageHeaderTitle } from "components/PageHeader/PageHeader"
1214
import { Pill } from "components/Pill/Pill"
1315
import { Stack } from "components/Stack/Stack"
1416
import { TableLoader } from "components/TableLoader/TableLoader"
1517
import { AuditHelpTooltip } from "components/Tooltips"
1618
import { UserAvatar } from "components/UserAvatar/UserAvatar"
17-
import { FC } from "react"
19+
import { FC, useState } from "react"
1820
import { createDayString } from "util/createDayString"
1921

22+
const AuditDiff = () => {
23+
const styles = useStyles()
24+
25+
return (
26+
<div className={styles.diff}>
27+
<div className={styles.diffOld}>
28+
<div className={styles.diffRow}>
29+
<div className={styles.diffLine}>1</div>
30+
<div className={styles.diffIcon}>-</div>
31+
<div className={styles.diffContent}>
32+
workspace_name: <span>alice-workspace</span>
33+
</div>
34+
</div>
35+
</div>
36+
<div className={styles.diffNew}>
37+
<div className={styles.diffRow}>
38+
<div className={styles.diffLine}>1</div>
39+
<div className={styles.diffIcon}>+</div>
40+
<div className={styles.diffContent}>
41+
workspace_name: <span>bruno-workspace</span>
42+
</div>
43+
</div>
44+
</div>
45+
</div>
46+
)
47+
}
48+
49+
const AuditLogRow: React.FC<{ auditLog: AuditLog }> = ({ auditLog }) => {
50+
const styles = useStyles()
51+
const [isDiffOpen, setIsDiffOpen] = useState(false)
52+
53+
return (
54+
<>
55+
<Stack
56+
direction="row"
57+
alignItems="center"
58+
className={styles.auditLogRow}
59+
tabIndex={0}
60+
onClick={() => setIsDiffOpen((v) => !v)}
61+
onKeyDown={(event) => {
62+
if (event.key === "Enter") {
63+
setIsDiffOpen((v) => !v)
64+
}
65+
}}
66+
>
67+
<Stack
68+
direction="row"
69+
alignItems="center"
70+
justifyContent="space-between"
71+
className={styles.auditLogRowInfo}
72+
>
73+
<Stack direction="row" alignItems="center">
74+
<UserAvatar username={auditLog.user?.username ?? ""} />
75+
<div>
76+
<span className={styles.auditLogResume}>
77+
<strong>{auditLog.user?.username}</strong> {auditLog.action}{" "}
78+
<strong>{auditLog.resource.name}</strong>
79+
</span>
80+
<span className={styles.auditLogTime}>{createDayString(auditLog.time)}</span>
81+
</div>
82+
</Stack>
83+
84+
<Stack direction="column" alignItems="flex-end" spacing={1}>
85+
<Pill type="success" text={auditLog.status_code.toString()} />
86+
<Stack direction="row" alignItems="center" className={styles.auditLogExtraInfo}>
87+
<div>
88+
<strong>IP</strong> {auditLog.ip}
89+
</div>
90+
<div>
91+
<strong>Agent</strong> {auditLog.user_agent}
92+
</div>
93+
</Stack>
94+
</Stack>
95+
</Stack>
96+
97+
{isDiffOpen ? <CloseDropdown /> : <OpenDropdown />}
98+
</Stack>
99+
100+
<Collapse in={isDiffOpen}>
101+
<AuditDiff />
102+
</Collapse>
103+
</>
104+
)
105+
}
106+
20107
export const Language = {
21108
title: "Audit",
22109
subtitle: "View events in your audit log.",
@@ -51,37 +138,10 @@ export const AuditPageView: FC<{ auditLogs?: AuditLog[] }> = ({ auditLogs }) =>
51138
</TableHead>
52139
<TableBody>
53140
{auditLogs ? (
54-
auditLogs.map((log) => (
55-
<TableRow key={log.id}>
56-
<TableCell>
57-
<Stack direction="row" alignItems="center" justifyContent="space-between">
58-
<Stack direction="row" alignItems="center">
59-
<UserAvatar username={log.user?.username ?? ""} />
60-
<div>
61-
<span className={styles.auditLogResume}>
62-
<strong>{log.user?.username}</strong> {log.action}{" "}
63-
<strong>{log.resource.name}</strong>
64-
</span>
65-
<span className={styles.auditLogTime}>{createDayString(log.time)}</span>
66-
</div>
67-
</Stack>
68-
69-
<Stack direction="column" alignItems="flex-end" spacing={1}>
70-
<Pill type="success" text={log.status_code.toString()} />
71-
<Stack
72-
direction="row"
73-
alignItems="center"
74-
className={styles.auditLogExtraInfo}
75-
>
76-
<div>
77-
<strong>IP</strong> {log.ip}
78-
</div>
79-
<div>
80-
<strong>Agent</strong> {log.user_agent}
81-
</div>
82-
</Stack>
83-
</Stack>
84-
</Stack>
141+
auditLogs.map((auditLog) => (
142+
<TableRow key={auditLog.id} hover>
143+
<TableCell className={styles.auditLogCell}>
144+
<AuditLogRow auditLog={auditLog} />
85145
</TableCell>
86146
</TableRow>
87147
))
@@ -96,6 +156,19 @@ export const AuditPageView: FC<{ auditLogs?: AuditLog[] }> = ({ auditLogs }) =>
96156
}
97157

98158
const useStyles = makeStyles((theme) => ({
159+
auditLogCell: {
160+
padding: "0 !important",
161+
},
162+
163+
auditLogRow: {
164+
padding: theme.spacing(2, 4),
165+
cursor: "pointer",
166+
},
167+
168+
auditLogRowInfo: {
169+
flex: 1,
170+
},
171+
99172
auditLogResume: {
100173
...theme.typography.body1,
101174
fontFamily: "inherit",
@@ -114,4 +187,48 @@ const useStyles = makeStyles((theme) => ({
114187
fontFamily: "inherit",
115188
color: theme.palette.text.secondary,
116189
},
190+
191+
diff: {
192+
display: "flex",
193+
alignItems: "flex-start",
194+
fontSize: theme.typography.body2.fontSize,
195+
borderTop: `1px solid ${theme.palette.divider}`,
196+
},
197+
198+
diffOld: {
199+
backgroundColor: theme.palette.error.dark,
200+
color: theme.palette.error.contrastText,
201+
flex: 1,
202+
paddingTop: theme.spacing(1),
203+
paddingBottom: theme.spacing(1),
204+
},
205+
206+
diffRow: {
207+
display: "flex",
208+
alignItems: "baseline",
209+
},
210+
211+
diffLine: {
212+
opacity: 0.5,
213+
padding: theme.spacing(1),
214+
width: theme.spacing(8),
215+
textAlign: "right",
216+
},
217+
218+
diffIcon: {
219+
padding: theme.spacing(1),
220+
width: theme.spacing(4),
221+
textAlign: "center",
222+
fontSize: theme.typography.body1.fontSize,
223+
},
224+
225+
diffContent: {},
226+
227+
diffNew: {
228+
backgroundColor: theme.palette.success.dark,
229+
color: theme.palette.success.contrastText,
230+
flex: 1,
231+
paddingTop: theme.spacing(1),
232+
paddingBottom: theme.spacing(1),
233+
},
117234
}))

site/src/testHelpers/entities.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -703,3 +703,35 @@ export const MockAuditLog = {
703703
user: MockUser,
704704
resource: MockOrganization,
705705
}
706+
707+
export const MockAuditLogWithDiff = {
708+
id: "fbd2116a-8961-4954-87ae-e4575bd29ce0",
709+
request_id: "53bded77-7b9d-4e82-8771-991a34d759f9",
710+
time: "2022-05-19T16:45:57.122Z",
711+
organization_id: "fc0774ce-cc9e-48d4-80ae-88f7a4d4a8b0",
712+
ip: "127.0.0.1",
713+
user_agent: "browser",
714+
resource_type: "organization",
715+
resource_id: "ef8d1cf4-82de-4fd9-8980-047dad6d06b5",
716+
resource_target: "Bruno's Org",
717+
action: "write",
718+
diff: {
719+
workspace_name: {
720+
old: "alice-workspace",
721+
new: "aharvey",
722+
},
723+
workspace_auto_off: {
724+
old: true,
725+
new: false,
726+
},
727+
template_version_id: {
728+
old: "fbd2116a-8961-4954-87ae-e4575bd29ce0",
729+
new: "53bded77-7b9d-4e82-8771-991a34d759f9",
730+
},
731+
},
732+
status_code: 200,
733+
additional_fields: {},
734+
description: "Colin Adler updated the organization Bruno's Org",
735+
user: MockUser,
736+
resource: MockOrganization,
737+
}

0 commit comments

Comments
 (0)