Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Selected tab is stored in the route #34

Merged
merged 7 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions packages/engine-frontend/components/AGConnectionPortal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@ import {Card, ResourceCard} from '@openint/ui'
import {cn} from '@openint/ui/utils'
import {R} from '@openint/util'
import {WithConnectConfig} from '../hocs/WithConnectConfig'
import {ConnectEventType} from '../hocs/WithConnectorConnect'
import {_trpcReact} from '../providers/TRPCProvider'
import {AgResourceRowActions} from './AgResourceRowActions'
import {ConnectDialog} from './ConnectDialog'

type ConnectEventType = 'open' | 'close' | 'error'

export interface AGConnectionPortalProps extends UIPropsNoChildren {
onEvent?: (event: {type: ConnectEventType; ccfgId: Id['ccfg']}) => void
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import {ConnectIntegrations} from './ConnectIntegrations'
interface AddConnectionTabContentProps {
connectorConfigFilters: ConnectorConfigFilters
refetch: () => void
onSuccessCallback?: () => void
}

export function AddConnectionTabContent({
connectorConfigFilters,
refetch,
onSuccessCallback,
}: AddConnectionTabContentProps) {
return (
<div className="flex flex-col gap-2 p-4">
Expand All @@ -21,6 +23,9 @@ export function AddConnectionTabContent({
onEvent={(event) => {
if (event.type === 'close') {
refetch()
} else if (event.type === 'success') {
onSuccessCallback?.()
refetch()
}
}}
/>
Expand Down
27 changes: 15 additions & 12 deletions packages/engine-frontend/components/AgResourceRowActions.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
'use client'

import { RefreshCw} from 'lucide-react'
import {RefreshCw} from 'lucide-react'
import type {RouterOutput} from '@openint/engine-backend'
import {useToast, type UIProps} from '@openint/ui'
import type {ConnectorConfig} from '../hocs/WithConnectConfig'
import {WithConnectorConnect} from '../hocs/WithConnectorConnect'
import {
WithConnectorConnect,
type ConnectEventType,
} from '../hocs/WithConnectorConnect'
import {useOptionalOpenIntConnectContext} from '../providers/OpenIntConnectProvider'
import {_trpcReact} from '../providers/TRPCProvider'

type ConnectEventType = 'open' | 'close' | 'error'

type Resource = RouterOutput['listConnections'][number]

/**
Expand Down Expand Up @@ -91,19 +92,21 @@ export function AgResourceRowActions(
syncResourceMutate()
e.preventDefault()
}}
className="inline-flex items-center justify-center gap-1 whitespace-nowrap group border bg-white border-stroke enabled:active:bg-background-mid enabled:active:border-1 focus:border-1 hover:border-[#8192FF] enabled:hover:bg-background-mid disabled:bg-background-mid disabled:border-stroke disabled:cursor-not-allowed disabled:text-black-light disabled:opacity-50 h-9 py-2 px-3 rounded-lg"
>
<RefreshCw className="text-black-light w-5 h-5" />
<p className="antialiased text-sm tracking-[-0.01em] text-[#8192FF]">Update</p>
className="border-stroke enabled:active:bg-background-mid enabled:active:border-1 focus:border-1 enabled:hover:bg-background-mid disabled:bg-background-mid disabled:border-stroke disabled:text-black-light group inline-flex h-9 items-center justify-center gap-1 whitespace-nowrap rounded-lg border bg-white px-3 py-2 hover:border-[#8192FF] disabled:cursor-not-allowed disabled:opacity-50">
<RefreshCw className="text-black-light h-5 w-5" />
<p className="text-sm tracking-[-0.01em] text-[#8192FF] antialiased">
Update
</p>
</button>
)}
<button
type="button"
onClick={() => deleteResource.mutate({id: props.resource.id})}
className="inline-flex items-center justify-center gap-1 whitespace-nowrap group border bg-white border-stroke enabled:active:bg-background-mid enabled:active:border-1 focus:border-1 hover:border-[#8192FF] enabled:hover:bg-background-mid disabled:bg-background-mid disabled:border-stroke disabled:cursor-not-allowed disabled:text-black-light disabled:opacity-50 h-9 py-2 px-3 rounded-lg"
>
<RefreshCw className="text-black-light w-5 h-5" />
<p className="antialiased text-sm tracking-[-0.01em] text-[#8192FF]">Disconnect</p>
className="border-stroke enabled:active:bg-background-mid enabled:active:border-1 focus:border-1 enabled:hover:bg-background-mid disabled:bg-background-mid disabled:border-stroke disabled:text-black-light group inline-flex h-9 items-center justify-center gap-1 whitespace-nowrap rounded-lg border bg-white px-3 py-2 hover:border-[#8192FF] disabled:cursor-not-allowed disabled:opacity-50">
<RefreshCw className="text-black-light h-5 w-5" />
<p className="text-sm tracking-[-0.01em] text-[#8192FF] antialiased">
Disconnect
</p>
</button>
</div>
)}
Expand Down
39 changes: 36 additions & 3 deletions packages/engine-frontend/components/ConnectionPortal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use client'

import {Loader} from 'lucide-react'
import {usePathname, useRouter, useSearchParams} from 'next/navigation'
import type {Id} from '@openint/cdk'
import type {UIPropsNoChildren} from '@openint/ui'
import {useToast} from '@openint/ui'
Expand All @@ -21,6 +23,10 @@ export interface ConnectionPortalProps extends UIPropsNoChildren {
// Also it would be nice if there was an easy way to automatically prefetch on the server side
// based on calls to useQuery so it doesn't need to be separately handled again on the client...
export function ConnectionPortal({className}: ConnectionPortalProps) {
const router = useRouter()
const searchParams = useSearchParams()
const pathname = usePathname()

const {toast} = useToast()
const ctx = _trpcReact.useContext()
const listConnectionsRes = _trpcReact.listConnections.useQuery({})
Expand All @@ -41,6 +47,14 @@ export function ConnectionPortal({className}: ConnectionPortalProps) {
},
})

const navigateToTab = (tab: string) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use this library rather than re-inventing the wheel ourselves here. https://www.npmjs.com/package/next-usequerystate

const params = new URLSearchParams(searchParams ?? {})
params.set('connectTab', tab)
router.replace(`${pathname}?${params.toString()}`, {
scroll: false,
})
}

return (
<WithConnectConfig>
{({ccfgs, verticals: categories}) => {
Expand Down Expand Up @@ -74,10 +88,10 @@ export function ConnectionPortal({className}: ConnectionPortalProps) {
content: (
<ConnectionsTabContent
connectionCount={connectionCount}
refetch={listConnectionsRes.refetch}
isLoading={listConnectionsRes.isLoading}
deleteResource={deleteResource.mutate}
categoriesWithConnections={categoriesWithConnections}
onConnect={() => navigateToTab('add-connection')}
/>
),
},
Expand All @@ -88,14 +102,33 @@ export function ConnectionPortal({className}: ConnectionPortalProps) {
<AddConnectionTabContent
connectorConfigFilters={{}}
refetch={listConnectionsRes.refetch}
onSuccessCallback={() => {
navigateToTab('connections')
}}
/>
),
},
]

return (
<div className={cn('gap-4 p-4 lg:p-8', className)}>
<Tabs tabConfig={tabConfig} defaultValue="connections" />
<div
className={cn(
'flex size-full flex-col gap-4 p-4 lg:p-8',
className,
)}>
{listConnectionsRes.isLoading ||
listConnectionsRes.isFetching ||
listConnectionsRes.isRefetching ? (
<div className="flex h-full min-h-[500px] flex-1 items-center justify-center">
<Loader className="size-8 animate-spin text-button" />
</div>
) : (
<Tabs
tabConfig={tabConfig}
value={searchParams?.get('connectTab') ?? 'connections'}
onValueChange={navigateToTab}
/>
)}
</div>
)
}}
Expand Down
29 changes: 12 additions & 17 deletions packages/engine-frontend/components/ConnectionsTabContent.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {Loader, Settings} from 'lucide-react'
import {Fragment} from 'react'
import {
Badge,
Button,
ConnectorLogo,
DropdownMenu,
DropdownMenuContent,
Expand All @@ -9,7 +11,6 @@ import {
Separator,
} from '@openint/ui'
import type {ConnectorConfig} from '../hocs/WithConnectConfig'
import {ConnectDialog} from './ConnectDialog'

interface ConnectionsTabContentProps {
connectionCount: number
Expand All @@ -23,33 +24,29 @@ interface ConnectionsTabContentProps {
syncInProgress: boolean
}>
}>
refetch: () => void
isLoading: boolean
deleteResource: ({id}: {id: string}) => void
onConnect: () => void
}

export function ConnectionsTabContent({
connectionCount,
refetch,
isLoading,
deleteResource,
categoriesWithConnections,
onConnect,
}: ConnectionsTabContentProps) {
return connectionCount === 0 ? (
<div className="flex flex-col gap-2 p-4">
<div>
<p className="text-base font-semibold">No connections yet</p>
<p className="text-base">Add a connection to get started</p>
</div>
<ConnectDialog
className="self-end bg-[#8A5DF6] hover:bg-[#A082E9]"
connectorConfigFilters={{}}
onEvent={(event) => {
if (event.type === 'close') {
refetch() // Trigger refetch
}
}}
/>
<Button
onClick={onConnect}
className="inline-flex h-10 items-center justify-center self-end">
Connect
</Button>
</div>
) : (
<div className="p-4">
Expand All @@ -61,10 +58,8 @@ export function ConnectionsTabContent({
categoriesWithConnections.map((category) => (
<div key={category.name} className="flex flex-col space-y-4">
{category.connections.map((conn) => (
<>
<div
key={conn.id}
className="flex flex-row justify-between gap-4">
<Fragment key={conn.id}>
<div className="flex flex-row justify-between gap-4">
<div className="flex flex-row gap-4">
<ConnectorLogo
connector={conn.connectorConfig.connector}
Expand Down Expand Up @@ -113,7 +108,7 @@ export function ConnectionsTabContent({
over all categories and all connections, would be good to have a single array of connections with the category
information included already */}
<Separator className="w-full" />
</>
</Fragment>
))}
</div>
))
Expand Down
4 changes: 2 additions & 2 deletions packages/engine-frontend/hocs/WithConnectorConnect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import {
} from '../providers/OpenIntConnectProvider'
import {_trpcReact} from '../providers/TRPCProvider'

export type ConnectEventType = 'open' | 'close' | 'error'
export type ConnectEventType = 'open' | 'close' | 'error' | 'success'

type Resource = RouterOutput['listConnections'][number]

Expand Down Expand Up @@ -153,7 +153,7 @@ export const WithConnectorConnect = ({
})
}
setOpen(false)
onEvent?.({type: 'close'})
onEvent?.({type: 'success'})
},
onError: (err) => {
if (err === CANCELLATION_TOKEN) {
Expand Down
16 changes: 13 additions & 3 deletions packages/ui/components/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,22 @@ interface TabsProps {
title: string
content: ReactElement
}>
defaultValue: string
defaultValue?: string
value?: string
onValueChange?: (value: string) => void
}

export function Tabs({tabConfig, defaultValue}: TabsProps) {
export function Tabs({
tabConfig,
defaultValue,
value,
onValueChange,
}: TabsProps) {
return (
<ShadcnTabs defaultValue="connections">
<ShadcnTabs
defaultValue={defaultValue}
value={value}
onValueChange={onValueChange}>
<TabsList>
{tabConfig.map((config) => (
<TabsTrigger key={config.key} value={config.key}>
Expand Down
Loading