1
1
import Collapse from "@material-ui/core/Collapse"
2
+ import Link from "@material-ui/core/Link"
2
3
import { makeStyles } from "@material-ui/core/styles"
3
4
import Table from "@material-ui/core/Table"
4
5
import TableBody from "@material-ui/core/TableBody"
@@ -7,6 +8,7 @@ import TableContainer from "@material-ui/core/TableContainer"
7
8
import TableHead from "@material-ui/core/TableHead"
8
9
import TableRow from "@material-ui/core/TableRow"
9
10
import { AuditLog } from "api/api"
11
+ import { Template , Workspace } from "api/typesGenerated"
10
12
import { CodeExample } from "components/CodeExample/CodeExample"
11
13
import { CloseDropdown , OpenDropdown } from "components/DropdownArrows/DropdownArrows"
12
14
import { Margins } from "components/Margins/Margins"
@@ -17,40 +19,124 @@ import { TableLoader } from "components/TableLoader/TableLoader"
17
19
import { AuditHelpTooltip } from "components/Tooltips"
18
20
import { UserAvatar } from "components/UserAvatar/UserAvatar"
19
21
import { FC , useState } from "react"
22
+ import { Link as RouterLink } from "react-router-dom"
23
+ import { colors } from "theme/colors"
24
+ import { combineClasses } from "util/combineClasses"
20
25
import { createDayString } from "util/createDayString"
21
26
22
- const AuditDiff = ( ) => {
27
+ const getDiffValue = ( value : number | string | boolean ) => {
28
+ if ( typeof value === "string" ) {
29
+ return `"${ value } "`
30
+ }
31
+
32
+ return value . toString ( )
33
+ }
34
+
35
+ const AuditDiff : React . FC < { diff : AuditLog [ "diff" ] } > = ( { diff } ) => {
23
36
const styles = useStyles ( )
37
+ const diffEntries = Object . entries ( diff )
24
38
25
39
return (
26
40
< 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 >
41
+ < div className = { combineClasses ( [ styles . diffColumn , styles . diffOld ] ) } >
42
+ { diffEntries . map ( ( [ attrName , valueDiff ] , index ) => (
43
+ < div key = { attrName } className = { styles . diffRow } >
44
+ < div className = { styles . diffLine } > { index + 1 } </ div >
45
+ < div className = { styles . diffIcon } > -</ div >
46
+ < div className = { styles . diffContent } >
47
+ { attrName } :{ " " }
48
+ < span className = { combineClasses ( [ styles . diffValue , styles . diffValueOld ] ) } >
49
+ { getDiffValue ( valueDiff . old ) }
50
+ </ span >
51
+ </ div >
33
52
</ div >
34
- </ div >
53
+ ) ) }
35
54
</ 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 >
55
+ < div className = { combineClasses ( [ styles . diffColumn , styles . diffNew ] ) } >
56
+ { diffEntries . map ( ( [ attrName , valueDiff ] , index ) => (
57
+ < div key = { attrName } className = { styles . diffRow } >
58
+ < div className = { styles . diffLine } > { index + 1 } </ div >
59
+ < div className = { styles . diffIcon } > +</ div >
60
+ < div className = { styles . diffContent } >
61
+ { attrName } :{ " " }
62
+ < span className = { combineClasses ( [ styles . diffValue , styles . diffValueNew ] ) } >
63
+ { getDiffValue ( valueDiff . new ) }
64
+ </ span >
65
+ </ div >
42
66
</ div >
43
- </ div >
67
+ ) ) }
44
68
</ div >
45
69
</ div >
46
70
)
47
71
}
48
72
73
+ const getResourceLabel = ( resource : AuditLog [ "resource" ] ) : string => {
74
+ if ( "name" in resource ) {
75
+ return resource . name
76
+ }
77
+
78
+ return resource . username
79
+ }
80
+
81
+ const getResourceHref = (
82
+ resource : AuditLog [ "resource" ] ,
83
+ resourceType : AuditLog [ "resource_type" ] ,
84
+ ) : string | undefined => {
85
+ switch ( resourceType ) {
86
+ case "user" :
87
+ return `/users`
88
+ case "template" :
89
+ return `/templates/${ ( resource as Template ) . name } `
90
+ case "workspace" :
91
+ return `/workspaces/@${ ( resource as Workspace ) . owner_name } /${ ( resource as Workspace ) . name } `
92
+ case "organization" :
93
+ return
94
+ }
95
+ }
96
+
97
+ const ResourceLink : React . FC < {
98
+ resource : AuditLog [ "resource" ]
99
+ resourceType : AuditLog [ "resource_type" ]
100
+ } > = ( { resource, resourceType } ) => {
101
+ const href = getResourceHref ( resource , resourceType )
102
+ const label = < strong > { getResourceLabel ( resource ) } </ strong >
103
+
104
+ if ( ! href ) {
105
+ return label
106
+ }
107
+
108
+ return (
109
+ < Link component = { RouterLink } to = { href } >
110
+ { label }
111
+ </ Link >
112
+ )
113
+ }
114
+
115
+ const actionLabelByAction : Record < AuditLog [ "action" ] , string > = {
116
+ create : "created" ,
117
+ write : "updated" ,
118
+ delete : "deleted" ,
119
+ }
120
+
121
+ const resourceLabelByResourceType : Record < AuditLog [ "resource_type" ] , string > = {
122
+ organization : "organization" ,
123
+ template : "template" ,
124
+ template_version : "template version" ,
125
+ user : "user" ,
126
+ workspace : "workspace" ,
127
+ }
128
+
129
+ const readableActionMessage = ( auditLog : AuditLog ) => {
130
+ return `${ actionLabelByAction [ auditLog . action ] } ${
131
+ resourceLabelByResourceType [ auditLog . resource_type ]
132
+ } `
133
+ }
134
+
49
135
const AuditLogRow : React . FC < { auditLog : AuditLog } > = ( { auditLog } ) => {
50
136
const styles = useStyles ( )
51
137
const [ isDiffOpen , setIsDiffOpen ] = useState ( false )
52
138
const diffs = Object . entries ( auditLog . diff )
53
- const shouldDisplayDiff = diffs . length > 1
139
+ const shouldDisplayDiff = diffs . length > 0
54
140
55
141
const toggle = ( ) => {
56
142
if ( shouldDisplayDiff ) {
@@ -84,8 +170,11 @@ const AuditLogRow: React.FC<{ auditLog: AuditLog }> = ({ auditLog }) => {
84
170
< UserAvatar username = { auditLog . user ?. username ?? "" } />
85
171
< div >
86
172
< span className = { styles . auditLogResume } >
87
- < strong > { auditLog . user ?. username } </ strong > { auditLog . action } { " " }
88
- < strong > { auditLog . resource . name } </ strong >
173
+ < strong > { auditLog . user ?. username } </ strong > { readableActionMessage ( auditLog ) } { " " }
174
+ < ResourceLink
175
+ resource = { auditLog . resource }
176
+ resourceType = { auditLog . resource_type }
177
+ />
89
178
</ span >
90
179
< span className = { styles . auditLogTime } > { createDayString ( auditLog . time ) } </ span >
91
180
</ div >
@@ -111,7 +200,7 @@ const AuditLogRow: React.FC<{ auditLog: AuditLog }> = ({ auditLog }) => {
111
200
112
201
{ shouldDisplayDiff && (
113
202
< Collapse in = { isDiffOpen } >
114
- < AuditDiff />
203
+ < AuditDiff diff = { auditLog . diff } />
115
204
</ Collapse >
116
205
) }
117
206
</ TableCell >
@@ -205,12 +294,16 @@ const useStyles = makeStyles((theme) => ({
205
294
borderTop : `1px solid ${ theme . palette . divider } ` ,
206
295
} ,
207
296
297
+ diffColumn : {
298
+ flex : 1 ,
299
+ paddingTop : theme . spacing ( 2 ) ,
300
+ paddingBottom : theme . spacing ( 2.5 ) ,
301
+ lineHeight : "160%" ,
302
+ } ,
303
+
208
304
diffOld : {
209
305
backgroundColor : theme . palette . error . dark ,
210
306
color : theme . palette . error . contrastText ,
211
- flex : 1 ,
212
- paddingTop : theme . spacing ( 1 ) ,
213
- paddingBottom : theme . spacing ( 1 ) ,
214
307
} ,
215
308
216
309
diffRow : {
@@ -220,13 +313,12 @@ const useStyles = makeStyles((theme) => ({
220
313
221
314
diffLine : {
222
315
opacity : 0.5 ,
223
- padding : theme . spacing ( 1 ) ,
316
+
224
317
width : theme . spacing ( 8 ) ,
225
318
textAlign : "right" ,
226
319
} ,
227
320
228
321
diffIcon : {
229
- padding : theme . spacing ( 1 ) ,
230
322
width : theme . spacing ( 4 ) ,
231
323
textAlign : "center" ,
232
324
fontSize : theme . typography . body1 . fontSize ,
@@ -237,8 +329,18 @@ const useStyles = makeStyles((theme) => ({
237
329
diffNew : {
238
330
backgroundColor : theme . palette . success . dark ,
239
331
color : theme . palette . success . contrastText ,
240
- flex : 1 ,
241
- paddingTop : theme . spacing ( 1 ) ,
242
- paddingBottom : theme . spacing ( 1 ) ,
332
+ } ,
333
+
334
+ diffValue : {
335
+ padding : 1 ,
336
+ borderRadius : theme . shape . borderRadius / 2 ,
337
+ } ,
338
+
339
+ diffValueOld : {
340
+ backgroundColor : colors . red [ 12 ] ,
341
+ } ,
342
+
343
+ diffValueNew : {
344
+ backgroundColor : colors . green [ 12 ] ,
243
345
} ,
244
346
} ) )
0 commit comments