Skip to content

Commit 769a542

Browse files
committed
refactor gridrow
1 parent d23440d commit 769a542

File tree

2 files changed

+161
-133
lines changed

2 files changed

+161
-133
lines changed

catalog/app/containers/Bucket/PackageCompare/Diff/Entries.tsx

Lines changed: 112 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,12 @@ import type { Revision, RevisionResult } from '../useRevision'
1616

1717
import Change from './Change'
1818
import type { Dir, Order } from './Change'
19+
import GridRow from './GridRow'
1920

2021
const useAddedStyles = M.makeStyles((t) => ({
2122
root: {
2223
...t.typography.body2,
2324
},
24-
cell: {
25-
padding: t.spacing(1.5, 1),
26-
},
2725
}))
2826

2927
interface AddedProps {
@@ -35,13 +33,9 @@ interface AddedProps {
3533
function Added({ className, dir, logicalKey }: AddedProps) {
3634
const classes = useAddedStyles()
3735
return (
38-
<GridRow className={cx(classes.root, className)}>
39-
<div className={classes.cell}>
40-
<Change order={dir === 'forward' ? 'former' : 'latter'}>{logicalKey}</Change>
41-
</div>
42-
<div className={classes.cell}>
43-
<Change order={dir === 'forward' ? 'latter' : 'former'}>{logicalKey}</Change>
44-
</div>
36+
<GridRow className={cx(classes.root, className)} divided>
37+
<Change order={dir === 'forward' ? 'former' : 'latter'}>{logicalKey}</Change>
38+
<Change order={dir === 'forward' ? 'latter' : 'former'}>{logicalKey}</Change>
4539
</GridRow>
4640
)
4741
}
@@ -50,10 +44,6 @@ const useUnmodifiedStyles = M.makeStyles((t) => ({
5044
root: {
5145
...t.typography.body2,
5246
color: t.palette.text.secondary,
53-
padding: t.spacing(1.5, 1),
54-
},
55-
label: {
56-
paddingLeft: t.spacing(1),
5747
},
5848
}))
5949

@@ -66,43 +56,90 @@ function Unmodified({ className, logicalKey }: UnmodifiedProps) {
6656
const classes = useUnmodifiedStyles()
6757
return (
6858
<GridRow className={cx(classes.root, className)}>
69-
<span>{logicalKey}</span>
70-
<i className={classes.label}>Unmodified</i>
59+
{logicalKey}
60+
<i>Unmodified</i>
7161
</GridRow>
7262
)
7363
}
7464

75-
const useGridRowStyles = M.makeStyles({
76-
root: {
77-
display: 'grid',
78-
gridTemplateColumns: '1fr 1fr',
79-
},
80-
})
65+
type Modifications = Record<keyof Model.PackageEntry, boolean>
8166

82-
interface GridRowProps {
67+
function getEntryChanges(
68+
entry: Model.PackageEntry,
69+
modified: Modifications,
70+
): Partial<Model.PackageEntry> {
71+
return {
72+
physicalKey: modified.physicalKey ? entry.physicalKey : undefined,
73+
hash: modified.hash ? entry.hash : undefined,
74+
size: modified.size ? entry.size : undefined,
75+
meta: modified.meta ? entry.meta : undefined,
76+
}
77+
}
78+
79+
interface ModifiedProps {
80+
className: string
81+
logicalKey: string
82+
dir: Dir
83+
left: Model.PackageEntry
84+
right: Model.PackageEntry
85+
modified: Modifications
86+
}
87+
88+
function Modified({ className, dir, logicalKey, left, right, modified }: ModifiedProps) {
89+
const changes = React.useMemo(
90+
() => ({
91+
left: getEntryChanges(left, modified),
92+
right: getEntryChanges(right, modified),
93+
}),
94+
[left, right, modified],
95+
)
96+
return (
97+
<GridRow className={className} dense divided>
98+
<EntrySide
99+
logicalKey={logicalKey}
100+
order={dir === 'forward' ? 'former' : 'latter'}
101+
changes={changes.left}
102+
/>
103+
<EntrySide
104+
logicalKey={logicalKey}
105+
order={dir === 'forward' ? 'latter' : 'former'}
106+
changes={changes.right}
107+
/>
108+
</GridRow>
109+
)
110+
}
111+
112+
interface PhysicalKeyProps {
83113
className?: string
84-
children: React.ReactNode
114+
url: string
85115
}
86116

87-
function GridRow({ className, children }: GridRowProps) {
88-
const classes = useGridRowStyles()
89-
return <div className={cx(className, classes.root)}>{children}</div>
117+
function PhysicalKey({ className, url }: PhysicalKeyProps) {
118+
const { urls } = NamedRoutes.use()
119+
const to = React.useMemo(() => {
120+
const { bucket, key, version } = s3paths.parseS3Url(url)
121+
return urls.bucketFile(bucket, key, version)
122+
}, [url, urls])
123+
return (
124+
<StyledLink className={className} to={to}>
125+
{url}
126+
</StyledLink>
127+
)
90128
}
91129

92130
type Changes =
93-
| { _tag: 'unmodified'; logicalKey: string }
94-
| { _tag: 'added'; logicalKey: string; entry: Model.PackageEntry; dir: Dir }
131+
| { _tag: 'added'; entry: Model.PackageEntry }
132+
| { _tag: 'unmodified' }
95133
| {
96134
_tag: 'modified'
97-
logicalKey: string
98-
left: Partial<Model.PackageEntry>
99-
right: Partial<Model.PackageEntry>
135+
modified: Modifications
136+
left: Model.PackageEntry
137+
right: Model.PackageEntry
100138
}
101139

102140
const useEntrySideStyles = M.makeStyles((t) => ({
103141
root: {
104-
overflow: 'hidden',
105-
padding: t.spacing(1),
142+
...t.typography.body1,
106143
},
107144
hash: {
108145
fontFamily: t.typography.monospace.fontFamily,
@@ -111,7 +148,7 @@ const useEntrySideStyles = M.makeStyles((t) => ({
111148
whiteSpace: 'nowrap',
112149
display: 'flex',
113150
alignItems: 'center',
114-
marginTop: t.spacing(1),
151+
margin: t.spacing(1, 0, 0),
115152
},
116153
value: {
117154
overflow: 'hidden',
@@ -130,39 +167,39 @@ interface EntrySideProps {
130167
order: Order
131168
}
132169

133-
function EntrySide({ className, changes, logicalKey, order }: EntrySideProps) {
170+
function EntrySide({ changes, logicalKey, order }: EntrySideProps) {
134171
const classes = useEntrySideStyles()
135172
return (
136-
<div className={cx(classes.root, className)}>
173+
<div className={classes.root}>
137174
<M.Typography variant="subtitle2" color="textSecondary">
138175
{logicalKey}
139176
</M.Typography>
140177

141178
{changes.physicalKey && (
142-
<M.Typography className={classes.property}>
179+
<p className={classes.property}>
143180
<Icons.LinkOutlined className={classes.icon} fontSize="small" />
144181
<Change order={order} className={classes.value}>
145182
<PhysicalKey url={changes.physicalKey} />
146183
</Change>
147-
</M.Typography>
184+
</p>
148185
)}
149186

150187
{changes.hash && (
151-
<M.Typography className={classes.property}>
188+
<p className={classes.property}>
152189
<Icons.LockOutlined className={classes.icon} fontSize="small" />
153190
<Change order={order} className={cx(classes.hash, classes.value)}>
154191
{changes.hash.value}
155192
</Change>
156-
</M.Typography>
193+
</p>
157194
)}
158195

159196
{changes.size && (
160-
<M.Typography variant="body2" className={classes.property}>
197+
<p className={classes.property}>
161198
<Icons.InsertDriveFileOutlined className={classes.icon} fontSize="small" />
162199
<Change order={order} className={classes.value}>
163200
{readableBytes(changes.size)}
164201
</Change>
165-
</M.Typography>
202+
</p>
166203
)}
167204

168205
{changes.meta && (
@@ -175,85 +212,34 @@ function EntrySide({ className, changes, logicalKey, order }: EntrySideProps) {
175212
)
176213
}
177214

178-
interface PhysicalKeyProps {
179-
className?: string
180-
url: string
181-
}
182-
183-
function PhysicalKey({ className, url }: PhysicalKeyProps) {
184-
const { urls } = NamedRoutes.use()
185-
const to = React.useMemo(() => {
186-
const { bucket, key, version } = s3paths.parseS3Url(url)
187-
return urls.bucketFile(bucket, key, version)
188-
}, [url, urls])
189-
return (
190-
<StyledLink className={className} to={to}>
191-
{url}
192-
</StyledLink>
193-
)
194-
}
195-
196-
function getEntryChanges(
197-
entry: Model.PackageEntry,
198-
modified: Record<keyof Model.PackageEntry, boolean>,
199-
) {
200-
return {
201-
physicalKey: modified.physicalKey ? entry.physicalKey : undefined,
202-
hash: modified.hash ? entry.hash : undefined,
203-
size: modified.size ? entry.size : undefined,
204-
meta: modified.meta ? entry.meta : undefined,
205-
}
206-
}
207-
208-
function getChanges(
209-
dir: Dir,
210-
logicalKey: string,
211-
left?: Model.PackageEntry,
212-
right?: Model.PackageEntry,
213-
): Changes {
215+
function getChanges(left?: Model.PackageEntry, right?: Model.PackageEntry): Changes {
214216
if (!left || !right) {
215217
const entry = left || right
216218
if (!entry) {
217219
throw new Error('Must be at least one entry')
218220
}
219-
return { _tag: 'added', logicalKey, entry, dir }
221+
return { _tag: 'added', entry }
220222
}
221223

222224
const physicalKey = left.physicalKey !== right.physicalKey
223225
const hash = left.hash.value !== right.hash.value
224226
const size = left.size !== right.size
225227
const meta = JSON.stringify(left.meta) !== JSON.stringify(right.meta)
226-
if (!physicalKey && !hash && !size && !meta) return { _tag: 'unmodified', logicalKey }
227-
const modified = { physicalKey, hash, size, meta }
228-
return {
229-
_tag: 'modified',
230-
logicalKey,
231-
left: getEntryChanges(left, modified),
232-
right: getEntryChanges(right, modified),
233-
}
234-
}
228+
if (!physicalKey && !hash && !size && !meta) return { _tag: 'unmodified' }
235229

236-
const useEntriesRowStyles = M.makeStyles((t) => ({
237-
side: {
238-
borderLeft: `1px solid ${t.palette.divider}`,
239-
},
240-
}))
230+
return { _tag: 'modified', modified: { physicalKey, hash, size, meta }, left, right }
231+
}
241232

242-
interface EntriesRowProps {
233+
interface RowProps {
243234
className: string
244235
logicalKey: string
245236
left?: Model.PackageEntry
246237
right?: Model.PackageEntry
247238
dir: Dir
248239
}
249240

250-
function EntriesRow({ className, dir, logicalKey, left, right }: EntriesRowProps) {
251-
const classes = useEntriesRowStyles()
252-
253-
const changes = React.useMemo(
254-
() => getChanges(dir, logicalKey, left, right),
255-
[dir, logicalKey, left, right],
256-
)
241+
function Row({ className, dir, logicalKey, left, right }: RowProps) {
242+
const changes = React.useMemo(() => getChanges(left, right), [left, right])
257243

258244
switch (changes._tag) {
259245
case 'unmodified':
@@ -262,19 +248,14 @@ function EntriesRow({ className, dir, logicalKey, left, right }: EntriesRowProps
262248
return <Added className={className} dir={dir} logicalKey={logicalKey} />
263249
case 'modified':
264250
return (
265-
<GridRow className={className}>
266-
<EntrySide
267-
logicalKey={logicalKey}
268-
order={dir === 'forward' ? 'former' : 'latter'}
269-
changes={changes.left}
270-
/>
271-
<EntrySide
272-
className={classes.side}
273-
logicalKey={logicalKey}
274-
order={dir === 'forward' ? 'latter' : 'former'}
275-
changes={changes.right}
276-
/>
277-
</GridRow>
251+
<Modified
252+
className={className}
253+
dir={dir}
254+
logicalKey={logicalKey}
255+
left={changes.left}
256+
right={changes.right}
257+
modified={changes.modified}
258+
/>
278259
)
279260
default:
280261
assertNever(changes)
@@ -284,14 +265,20 @@ function EntriesRow({ className, dir, logicalKey, left, right }: EntriesRowProps
284265
const useStyles = M.makeStyles((t) => ({
285266
row: {
286267
borderBottom: `1px solid ${t.palette.divider}`,
268+
'&:last-child': {
269+
borderBottom: 'none',
270+
},
287271
},
288272
head: {
289-
overflow: 'hidden',
290-
padding: t.spacing(1),
291273
background: t.palette.background.default,
292-
'& + &': {
293-
borderLeft: `1px solid ${t.palette.divider}`,
294-
},
274+
...t.typography.caption,
275+
},
276+
empty: {
277+
...t.typography.body2,
278+
color: t.palette.text.secondary,
279+
fontStyle: 'italic',
280+
textAlign: 'center',
281+
padding: t.spacing(2),
295282
},
296283
}))
297284

@@ -321,25 +308,17 @@ function EntriesDiff({ left, right }: EntriesDiffProps) {
321308
)
322309

323310
if (entries.keys.length === 0) {
324-
return (
325-
<M.Typography
326-
variant="body2"
327-
color="textSecondary"
328-
style={{ fontStyle: 'italic', textAlign: 'center', padding: 16 }}
329-
>
330-
No entries found
331-
</M.Typography>
332-
)
311+
return <div className={classes.empty}>No entries found</div>
333312
}
334313

335314
return (
336315
<div>
337-
<GridRow className={classes.row}>
338-
<div className={classes.head}>{left.hash}</div>
339-
<div className={classes.head}>{right.hash}</div>
316+
<GridRow className={cx(classes.row, classes.head)} dense divided>
317+
{left.hash}
318+
{right.hash}
340319
</GridRow>
341320
{entries.keys.map((logicalKey) => (
342-
<EntriesRow
321+
<Row
343322
className={classes.row}
344323
key={logicalKey}
345324
logicalKey={logicalKey}

0 commit comments

Comments
 (0)