Skip to content

Commit c6f5d96

Browse files
committed
take out json stuff and row expansion
1 parent b19f5d1 commit c6f5d96

File tree

2 files changed

+42
-154
lines changed

2 files changed

+42
-154
lines changed

app/pages/SiloAuditLogsPage.tsx renamed to app/pages/system/AuditLog.tsx

Lines changed: 41 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { useInfiniteQuery, useIsFetching } from '@tanstack/react-query'
1010
import { useVirtualizer } from '@tanstack/react-virtual'
1111
import cn from 'classnames'
1212
import { differenceInMilliseconds } from 'date-fns'
13-
import { memo, useCallback, useMemo, useRef, useState } from 'react'
13+
import { useMemo, useRef } from 'react'
1414

1515
import { api } from '@oxide/api'
1616
import { Logs16Icon, Logs24Icon } from '@oxide/design-system/icons/react'
@@ -25,93 +25,12 @@ import { Spinner } from '~/ui/lib/Spinner'
2525
import { toSyslogDateString, toSyslogTimeString } from '~/util/date'
2626
import { docLinks } from '~/util/links'
2727

28-
// silly faux highlighting
29-
// avoids unnecessary import of a library and all that overhead
30-
const HighlightJSON = memo(({ jsonString }: { jsonString: string }) => {
31-
const Indent = ({ depth }: { depth: number }) => (
32-
<span className="inline-block" style={{ width: `${depth * 4 + 1}ch` }} />
33-
)
34-
35-
const Primitive = ({ value }: { value: null | boolean | number | string }) => (
36-
<span className="text-[var(--base-blue-600)]">
37-
{value === null ? 'null' : typeof value === 'string' ? `"${value}"` : String(value)}
38-
</span>
39-
)
40-
41-
const renderValue = (
42-
value: null | boolean | number | string | object,
43-
depth = 0
44-
): React.ReactNode => {
45-
if (
46-
value === null ||
47-
typeof value === 'boolean' ||
48-
typeof value === 'number' ||
49-
typeof value === 'string'
50-
) {
51-
return <Primitive value={value} />
52-
}
53-
54-
if (Array.isArray(value)) {
55-
if (value.length === 0) return <span className="text-quaternary">[]</span>
56-
57-
return (
58-
<>
59-
<span className="text-quaternary">[</span>
60-
{'\n'}
61-
{value.map((item, index) => (
62-
<span key={index}>
63-
<Indent depth={depth + 1} />
64-
{renderValue(item, depth + 1)}
65-
{index < value.length - 1 && <span className="text-quaternary">,</span>}
66-
{'\n'}
67-
</span>
68-
))}
69-
<Indent depth={depth} />
70-
<span className="text-quaternary">]</span>
71-
</>
72-
)
73-
}
74-
75-
if (typeof value === 'object') {
76-
const entries = Object.entries(value)
77-
if (entries.length === 0) return <span className="text-quaternary">{'{}'}</span>
78-
79-
return (
80-
<>
81-
<span className="text-quaternary">{'{'}</span>
82-
{'\n'}
83-
{entries.map(([key, val], index) => (
84-
<span key={key}>
85-
<Indent depth={depth + 1} />
86-
<span className="text-default">{key}</span>
87-
<span className="text-quaternary">: </span>
88-
{renderValue(val, depth + 1)}
89-
{index < entries.length - 1 && <span className="text-quaternary">,</span>}
90-
{'\n'}
91-
</span>
92-
))}
93-
<Indent depth={depth} />
94-
<span className="text-quaternary">{'}'}</span>
95-
</>
96-
)
97-
}
98-
99-
return String(value)
100-
}
101-
102-
try {
103-
const parsed = JSON.parse(jsonString)
104-
return <>{renderValue(parsed)}</>
105-
} catch {
106-
return <>{jsonString}</>
107-
}
108-
})
109-
11028
export const handle = { crumb: 'Audit Log' }
11129

112-
export default function SiloAuditLogsPage() {
113-
const [expandedItem, setExpandedItem] = useState<string | null>(null)
30+
// for virtualizer
31+
const estimateSize = () => 36
11432

33+
export default function SiloAuditLogsPage() {
11534
// pass refetch interval to this to keep the date up to date
11635
const { preset, startTime, endTime, dateTimeRangePicker, onRangeChange } =
11736
useDateTimeRangePicker({
@@ -161,28 +80,13 @@ export default function SiloAuditLogsPage() {
16180

16281
const parentRef = useRef<HTMLDivElement>(null)
16382

164-
const EXPANDED_HEIGHT = 282
165-
16683
const rowVirtualizer = useVirtualizer({
16784
count: auditLogs.length,
16885
getScrollElement: () => document.querySelector('#scroll-container'),
169-
estimateSize: useCallback(
170-
(index) => {
171-
return expandedItem === index.toString() ? 36 + EXPANDED_HEIGHT : 36
172-
},
173-
[expandedItem, EXPANDED_HEIGHT]
174-
),
86+
estimateSize,
17587
overscan: 20,
17688
})
17789

178-
const handleToggle = useCallback(
179-
(index: string | null) => {
180-
setExpandedItem(index)
181-
rowVirtualizer.measure()
182-
},
183-
[rowVirtualizer]
184-
)
185-
18690
const LogTable = () => (
18791
<>
18892
<div
@@ -193,8 +97,6 @@ export default function SiloAuditLogsPage() {
19397
>
19498
{rowVirtualizer.getVirtualItems().map((virtualRow) => {
19599
const log = auditLogs[virtualRow.index]
196-
const isExpanded = expandedItem === virtualRow.index.toString()
197-
const jsonString = JSON.stringify(log, null, 2)
198100

199101
return (
200102
<div
@@ -205,58 +107,44 @@ export default function SiloAuditLogsPage() {
205107
transform: `translateY(${virtualRow.start}px)`,
206108
}}
207109
>
208-
<div>
209-
<button
210-
className={cn(
211-
'grid h-9 w-full cursor-pointer items-center gap-8 px-[var(--content-gutter)] text-left text-sans-md border-secondary',
212-
isExpanded ? 'bg-raise' : 'hover:bg-raise',
213-
virtualRow.index !== 0 && 'border-t'
214-
)}
215-
style={{
216-
gridTemplateColumns: '7rem 4.25rem 180px 120px 120px 120px 300px 300px',
217-
}}
218-
onClick={() => {
219-
const newValue = isExpanded ? null : virtualRow.index.toString()
220-
handleToggle(newValue)
221-
}}
222-
type="button"
223-
>
224-
<div className="overflow-hidden whitespace-nowrap text-mono-sm">
225-
<span className="text-tertiary">
226-
{toSyslogDateString(log.timeCompleted)}
227-
</span>{' '}
228-
{toSyslogTimeString(log.timeCompleted)}
229-
</div>
230-
<div className="flex gap-1 overflow-hidden whitespace-nowrap">
231-
<span className="text-mono-sm text-tertiary">POST</span>
232-
<Badge>200</Badge>
233-
</div>
234-
<div>
110+
<div
111+
className={cn(
112+
'grid h-9 w-full items-center gap-8 px-[var(--content-gutter)] text-left text-sans-md border-secondary',
113+
virtualRow.index !== 0 && 'border-t'
114+
)}
115+
style={{
116+
gridTemplateColumns: '7rem 4.25rem 180px 120px 120px 120px 300px 300px',
117+
}}
118+
onClick={() => {}}
119+
>
120+
<div className="overflow-hidden whitespace-nowrap text-mono-sm">
121+
<span className="text-tertiary">
122+
{toSyslogDateString(log.timeCompleted)}
123+
</span>{' '}
124+
{toSyslogTimeString(log.timeCompleted)}
125+
</div>
126+
<div className="flex gap-1 overflow-hidden whitespace-nowrap">
127+
<span className="text-mono-sm text-tertiary">POST</span>
128+
<Badge>200</Badge>
129+
</div>
130+
<div>
131+
<Badge color="neutral" className="text-tertiary">
132+
{log.operationId.split('_').join(' ')}
133+
</Badge>
134+
</div>
135+
<div className="text-secondary">hannah.arendt</div>
136+
<div>
137+
{!!log.accessMethod && (
235138
<Badge color="neutral" className="text-tertiary">
236-
{log.operationId.split('_').join(' ')}
139+
{log.accessMethod.split('_').join(' ')}
237140
</Badge>
238-
</div>
239-
<div className="text-secondary">hannah.arendt</div>
240-
<div>
241-
{!!log.accessMethod && (
242-
<Badge color="neutral" className="text-tertiary">
243-
{log.accessMethod.split('_').join(' ')}
244-
</Badge>
245-
)}
246-
</div>
247-
<div className="text-secondary">maze-war</div>
248-
<div className="text-secondary">
249-
{differenceInMilliseconds(new Date(log.timeCompleted), log.timeStarted)}
250-
ms
251-
</div>
252-
</button>
253-
{isExpanded && (
254-
<div className="border-t px-[var(--content-gutter)] py-3 border-secondary">
255-
<pre className="h-full overflow-auto border-l pl-4 text-mono-code border-secondary">
256-
<HighlightJSON jsonString={jsonString} />
257-
</pre>
258-
</div>
259-
)}
141+
)}
142+
</div>
143+
<div className="text-secondary">maze-war</div>
144+
<div className="text-secondary">
145+
{differenceInMilliseconds(new Date(log.timeCompleted), log.timeStarted)}
146+
ms
147+
</div>
260148
</div>
261149
</div>
262150
)

app/routes.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ export const routes = createRoutesFromElements(
211211
</Route>
212212
<Route
213213
path="audit-log"
214-
lazy={() => import('./pages/SiloAuditLogsPage').then(convert)}
214+
lazy={() => import('./pages/system/AuditLog').then(convert)}
215215
/>
216216
</Route>
217217

0 commit comments

Comments
 (0)