diff --git a/ui/app/mirrors/[mirrorId]/page.tsx b/ui/app/mirrors/[mirrorId]/page.tsx index 939b82a3bd..d7a78f9187 100644 --- a/ui/app/mirrors/[mirrorId]/page.tsx +++ b/ui/app/mirrors/[mirrorId]/page.tsx @@ -1,7 +1,6 @@ import { SyncStatusRow } from '@/app/dto/MirrorsDTO'; import prisma from '@/app/utils/prisma'; -import EditButton from '@/components/EditButton'; -import { ResyncDialog } from '@/components/ResyncDialog'; +import MirrorActions from '@/components/MirrorActionsDropdown'; import { FlowConnectionConfigs, FlowStatus } from '@/grpc_generated/flow'; import { DBType } from '@/grpc_generated/peers'; import { MirrorStatusResponse } from '@/grpc_generated/route'; @@ -77,8 +76,7 @@ export default async function ViewMirror({ } let syncStatusChild = null; - let resyncComponent = null; - let editButtonHTML = null; + let actionsDropdown = null; if (mirrorStatus.cdcStatus) { let rowsSynced = syncs.reduce((acc, sync) => { @@ -88,32 +86,27 @@ export default async function ViewMirror({ return acc; }, 0); const mirrorConfig = FlowConnectionConfigs.decode(mirrorInfo.config_proto!); + syncStatusChild = ( + + ); + const dbType = mirrorConfig.destination!.type; const canResync = dbType.valueOf() === DBType.BIGQUERY.valueOf() || dbType.valueOf() === DBType.SNOWFLAKE.valueOf(); - if (canResync) { - resyncComponent = ( - - ); - } - syncStatusChild = ( - - ); const isNotPaused = mirrorStatus.currentFlowState.toString() !== FlowStatus[FlowStatus.STATUS_PAUSED]; - editButtonHTML = ( -
- -
+ + actionsDropdown = ( + ); } else { redirect(`/mirrors/status/qrep/${mirrorId}`); @@ -129,11 +122,8 @@ export default async function ViewMirror({ paddingRight: '2rem', }} > -
-
{mirrorId}
- {editButtonHTML} -
- {resyncComponent} +
{mirrorId}
+ {actionsDropdown} !prevOpen); }; - const handleClose = () => { - setOpen(false); - }; - return ( diff --git a/ui/components/EditButton.tsx b/ui/components/EditButton.tsx index 1e598de2c9..5e87cbfaa8 100644 --- a/ui/components/EditButton.tsx +++ b/ui/components/EditButton.tsx @@ -1,6 +1,5 @@ 'use client'; import { Button } from '@/lib/Button'; -import { Icon } from '@/lib/Icon'; import { Label } from '@/lib/Label'; import { ProgressCircle } from '@/lib/ProgressCircle'; import { useRouter } from 'next/navigation'; @@ -25,22 +24,17 @@ const EditButton = ({ className='IconButton' onClick={handleEdit} aria-label='sort up' + variant='normal' style={{ display: 'flex', - marginLeft: '1rem', - alignItems: 'center', - backgroundColor: 'whitesmoke', - border: '1px solid rgba(0,0,0,0.1)', - borderRadius: '0.5rem', + alignItems: 'flex-start', + columnGap: '0.3rem', + width: '100%', }} disabled={disabled} > - {loading ? ( - - ) : ( - - )} + {loading && } ); }; diff --git a/ui/components/MirrorActionsDropdown.tsx b/ui/components/MirrorActionsDropdown.tsx new file mode 100644 index 0000000000..c11e68e019 --- /dev/null +++ b/ui/components/MirrorActionsDropdown.tsx @@ -0,0 +1,72 @@ +'use client'; +import EditButton from '@/components/EditButton'; +import { ResyncDialog } from '@/components/ResyncDialog'; +import { FlowConnectionConfigs } from '@/grpc_generated/flow'; +import { Button } from '@/lib/Button/Button'; +import { Icon } from '@/lib/Icon'; +import { Label } from '@/lib/Label/Label'; +import * as DropdownMenu from '@radix-ui/react-dropdown-menu'; +import { useEffect, useState } from 'react'; + +const MirrorActions = ({ + mirrorConfig, + workflowId, + editLink, + canResync, + isNotPaused, +}: { + mirrorConfig: FlowConnectionConfigs; + workflowId: string; + editLink: string; + canResync: boolean; + isNotPaused: boolean; +}) => { + const [mounted, setMounted] = useState(false); + const [open, setOpen] = useState(false); + const handleToggle = () => { + setOpen((prevOpen) => !prevOpen); + }; + useEffect(() => setMounted(true), []); + if (mounted) + return ( + + + + + + + + + + {canResync && ( + + )} + + + + ); + return <>; +}; + +export default MirrorActions; diff --git a/ui/components/ResyncDialog.tsx b/ui/components/ResyncDialog.tsx index a8ef4f39aa..6caeea3821 100644 --- a/ui/components/ResyncDialog.tsx +++ b/ui/components/ResyncDialog.tsx @@ -62,8 +62,8 @@ export const ResyncDialog = ({ noInteract={true} size='xLarge' triggerButton={ - } >