Skip to content

Commit 47788b7

Browse files
authored
React 19 improvements (#4160)
Split mirror pages into server/client components, fetch data server-side and resolve via React.use() Add Suspense fallbacks to layouts, error boundary for mirror detail Replace setLoading callbacks with useTransition in form handlers Use <Context> directly instead of <Context.Provider>
1 parent feaf68a commit 47788b7

15 files changed

Lines changed: 901 additions & 860 deletions

File tree

ui/app/mirror-logs/layout.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import { Configuration } from '@/app/config/config';
33
import SidebarComponent from '@/components/SidebarComponent';
44
import { Layout } from '@/lib/Layout';
5+
import { ProgressCircle } from '@/lib/ProgressCircle';
56
import { PropsWithChildren, Suspense } from 'react';
67

78
export default async function PageLayout({ children }: PropsWithChildren) {
@@ -13,7 +14,11 @@ export default async function PageLayout({ children }: PropsWithChildren) {
1314
/>
1415
}
1516
>
16-
<Suspense>{children}</Suspense>
17+
<Suspense
18+
fallback={<ProgressCircle variant='determinate_progress_circle' />}
19+
>
20+
{children}
21+
</Suspense>
1722
</Layout>
1823
);
1924
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
'use client';
2+
import { FormatStatus } from '@/app/utils/flowstatus';
3+
import MirrorActions from '@/components/MirrorActionsDropdown';
4+
import { FlowStatus } from '@/grpc_generated/flow';
5+
import { DBType, dBTypeFromJSON } from '@/grpc_generated/peers';
6+
import { MirrorStatusResponse } from '@/grpc_generated/route';
7+
import { Badge } from '@/lib/Badge';
8+
import { Header } from '@/lib/Header';
9+
import { Label } from '@/lib/Label';
10+
import { LayoutMain } from '@/lib/Layout';
11+
import React from 'react';
12+
import { CDCMirror } from './cdc';
13+
import QrepGraph from './qrepGraph';
14+
import QRepStatusButtons from './qrepStatusButtons';
15+
import QRepStatusTable from './qrepStatusTable';
16+
import SyncStatus from './syncStatus';
17+
18+
type ViewMirrorProps = {
19+
mirrorId: string;
20+
mirrorStatePromise: Promise<MirrorStatusResponse>;
21+
};
22+
23+
export default function ViewMirror({
24+
mirrorId,
25+
mirrorStatePromise,
26+
}: ViewMirrorProps) {
27+
const mirrorState = React.use(mirrorStatePromise);
28+
29+
if (mirrorState?.cdcStatus) {
30+
const dbType = dBTypeFromJSON(mirrorState.cdcStatus.destinationType);
31+
32+
const isNotPaused =
33+
mirrorState.currentFlowState.toString() !==
34+
FlowStatus[FlowStatus.STATUS_PAUSED];
35+
const canResync =
36+
mirrorState.currentFlowState.toString() !==
37+
FlowStatus[FlowStatus.STATUS_SETUP] &&
38+
(dbType.valueOf() === DBType.BIGQUERY.valueOf() ||
39+
dbType.valueOf() === DBType.SNOWFLAKE.valueOf() ||
40+
dbType.valueOf() === DBType.POSTGRES.valueOf() ||
41+
dbType.valueOf() === DBType.CLICKHOUSE.valueOf());
42+
43+
return (
44+
<LayoutMain alignSelf='flex-start' justifySelf='flex-start' width='full'>
45+
<div
46+
style={{
47+
display: 'flex',
48+
alignItems: 'center',
49+
justifyContent: 'space-between',
50+
paddingRight: '2rem',
51+
}}
52+
>
53+
<Header variant='title2'>{mirrorId}</Header>
54+
<MirrorActions
55+
mirrorName={mirrorId}
56+
editLink={`/mirrors/${mirrorId}/edit`}
57+
canResync={canResync}
58+
isNotPaused={isNotPaused}
59+
/>
60+
</div>
61+
<CDCMirror
62+
syncStatusChild={<SyncStatus flowJobName={mirrorId} />}
63+
status={mirrorState}
64+
/>
65+
</LayoutMain>
66+
);
67+
} else if (mirrorState?.qrepStatus) {
68+
return (
69+
<LayoutMain alignSelf='flex-start' justifySelf='flex-start' width='full'>
70+
<div
71+
style={{
72+
display: 'flex',
73+
alignItems: 'center',
74+
justifyContent: 'space-between',
75+
paddingRight: '2rem',
76+
marginBottom: '1rem',
77+
}}
78+
>
79+
<Header variant='title2'>{mirrorId}</Header>
80+
<QRepStatusButtons mirrorId={mirrorId} />
81+
</div>
82+
<Label>
83+
Status: <Badge>{FormatStatus(mirrorState.currentFlowState)}</Badge>
84+
</Label>
85+
<QrepGraph syncs={mirrorState.qrepStatus.partitions} />
86+
<br></br>
87+
<QRepStatusTable
88+
flowJobName={mirrorId}
89+
partitions={mirrorState.qrepStatus.partitions}
90+
/>
91+
</LayoutMain>
92+
);
93+
}
94+
}

0 commit comments

Comments
 (0)