Skip to content

Commit

Permalink
feat(landing): hide editor, use new conector list element
Browse files Browse the repository at this point in the history
  • Loading branch information
anteqkois committed May 19, 2024
1 parent 1aed4d6 commit 2e8da21
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 182 deletions.
14 changes: 11 additions & 3 deletions apps/web/app/app/connectors/page.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import { HydrationBoundary, dehydrate } from '@tanstack/react-query'
import { Heading } from '../../(landing)/components/Heading'
import { useServerQuery } from '../../../libs/react-query'
import { ConnectorsList } from '../../../modules/flows/connectors/ConnectorsList'
import { connectorsMetadataQueryConfig } from '../../../modules/flows/connectors/api/query-configs'
import { ConnectorsTable } from '../../../modules/flows/connectors/table/Table'
import { PageContainer } from '../components/PageContainer'

export default async function Page() {
const { queryClient } = await useServerQuery(connectorsMetadataQueryConfig.getSummaryMany())

return (
<PageContainer>
<PageContainer variant={'centered'}>
<HydrationBoundary state={dehydrate(queryClient)}>
<ConnectorsTable />
<div className="max-w-4xl relative">
<Heading className="pb-2">Avaible Connectors</Heading>
<ConnectorsList listClassName="bg-background h-100 overflow-y-scroll md:h-120 overflow-scroll" />
<div
className="w-full h-2/6 inline-block rotate-1 bg-primary absolute bottom-[15%] left-[42%] -translate-x-1/2 blur-[120px] -z-10 shadow"
style={{ animation: 'shadow-slide infinite 4s linear alternate' }}
/>
</div>
</HydrationBoundary>
</PageContainer>
)
Expand Down
194 changes: 15 additions & 179 deletions apps/web/app/app/flows/editor/[[...id]]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,184 +1,20 @@
'use client'

import {
ActionType,
CustomError,
ErrorCode,
FlowVersion,
TriggerType,
assertNotNullOrUndefined,
isCustomHttpExceptionAxios,
isQuotaErrorCode,
} from '@linkerry/shared'
import { useToast } from '@linkerry/ui-components/client'
import { ConnectorMetadataSummary } from '@linkerry/connectors-framework'
import { useRouter } from 'next/navigation'
import { useCallback, useEffect } from 'react'
import { Edge } from 'reactflow'
import { useClientQuery } from '../../../../../libs/react-query'
import { useSubscriptions } from '../../../../../modules/billing/subscriptions/useSubscriptions'
import { useReachLimitDialog } from '../../../../../modules/billing/useReachLimitDialog'
import { CustomNode, Editor, useEditor } from '../../../../../modules/editor'
import {
actionNodeFactory,
nodeConfigs,
selectTriggerNodeFactory,
testFlowNodeFactory,
triggerNodeFactory,
} from '../../../../../modules/editor/common/nodeFactory'
import { defaultEdgeFactory } from '../../../../../modules/editor/edges/edgesFactory'
import { connectorsMetadataQueryConfig } from '../../../../../modules/flows/connectors/api/query-configs'
import { FlowApi } from '../../../../../modules/flows/flows/api'
import { ErrorInfo, Spinner } from '../../../../../shared/components'

const renderFlow = (flowVersion: FlowVersion, connectorsMetadata: ConnectorMetadataSummary[]) => {
const nodes: CustomNode[] = [
testFlowNodeFactory({
position: {
x: nodeConfigs.BaseNode.width / 2 - nodeConfigs.TestFlowNode.width / 2,
y: -60,
},
}),
]
const edges: Edge[] = []

let parentNode: Pick<CustomNode, 'position' | 'id'> & {
height: number
width: number
} = {
id: '',
position: {
x: 0,
y: 0,
},
height: nodeConfigs.BaseNode.height,
width: nodeConfigs.BaseNode.width,
}

for (const trigger of flowVersion.triggers) {
switch (trigger.type) {
case TriggerType.EMPTY:
nodes.push(selectTriggerNodeFactory({ trigger }))
parentNode = nodes[nodes.length - 1]
break
case TriggerType.CONNECTOR: {
const connectorMetadata = connectorsMetadata.find((metadata) => trigger.settings.connectorName === metadata.name)
assertNotNullOrUndefined(connectorMetadata, 'connectorMetadata')
nodes.push(triggerNodeFactory({ trigger, connectorMetadata }))
parentNode = nodes[nodes.length - 1]
break
}
default:
throw new Error(`Can not find trigger type: ${trigger}`)
}
}

assertNotNullOrUndefined(parentNode, 'parentNode')

for (const action of flowVersion.actions) {
switch (action.type) {
case ActionType.BRANCH:
// case ActionType.LOOP_ON_ITEMS:
// case ActionType.MERGE_BRANCH:
throw new CustomError(`Unsuported action type`, ErrorCode.INVALID_TYPE, {
action,
})
case ActionType.CONNECTOR: {
const connectorMetadata = connectorsMetadata.find((metadata) => action.settings.connectorName === metadata.name)
assertNotNullOrUndefined(connectorMetadata, 'connectorMetadata')

const newNode = actionNodeFactory({
action,
connectorMetadata,
position: {
x: parentNode.position.x,
y: parentNode.position.y + parentNode.height + nodeConfigs.gap.y,
},
})
nodes.push(newNode)

edges.push(
defaultEdgeFactory({
sourceNodeId: parentNode.id,
targetNodeId: newNode.id,
}),
)

parentNode = newNode
}
}
}

return { nodes, edges }
}
import { Heading } from '../../../../(landing)/components/Heading'
import { HeroImage } from '../../../../(landing)/components/HeroImage'
import { PageContainer } from '../../../components/PageContainer'

export default function Page({ params }: { params: { id: string } }) {
const { data: connectorsMetadata, status } = useClientQuery(connectorsMetadataQueryConfig.getSummaryMany())
const { loadFlow, setFlow, setEdges, setNodes } = useEditor()
const { toast } = useToast()
const { showDialogBasedOnErrorCode } = useReachLimitDialog()
const { currentPlan, subscriptionsStatus, subscriptionsError } = useSubscriptions()
const { push } = useRouter()

const initEditor = useCallback(async () => {
if (!connectorsMetadata?.length) throw new Error('Can not retrive connectors metadata')
const id = params?.id?.[0]

// Fetch and render if exists
if (id) {
const flow = await loadFlow(id)
if (flow) {
const { nodes, edges } = renderFlow(flow.version, connectorsMetadata)
setNodes(nodes)
setEdges(edges)
return
}
}
// Create new flow
try {
const { data } = await FlowApi.create()
setFlow(data)

push(`/app/flows/editor/${data._id}`)

setNodes([selectTriggerNodeFactory({ trigger: data.version.triggers[0] })])
setEdges([])
} catch (error) {
let errorDescription = 'We can not retrive error message. Please inform our Team'

if (isCustomHttpExceptionAxios(error)) {
if (isQuotaErrorCode(error.response.data.code)) return showDialogBasedOnErrorCode(error.response.data.code)
else errorDescription = error.response.data.message
}

toast({
title: 'Can not create new Flow',
description: errorDescription,
variant: 'destructive',
})
}
}, [params.id, connectorsMetadata])

useEffect(() => {
if (status !== 'success') return
;(async () => {
await initEditor()
})()
}, [status])

if (subscriptionsStatus === 'pending') return <Spinner className="flex-center min-h-screen h-screen" />
if (subscriptionsStatus === 'error') return <ErrorInfo errorObject={subscriptionsError} />
if (!currentPlan) return <ErrorInfo message="Can not retrive yor plan configuration" />

return (
<Editor
mode="production"
limits={{
connections: currentPlan.config.connections,
flowSteps: currentPlan.config.flowSteps,
triggersAmount: currentPlan.config.triggersAmount,
}}
cache={{ saveState: undefined }}
/>
)
return (
<PageContainer variant={'fromTop'} className="flex-center flex-col">
<Heading className="pt-10 lg:pt-5">Will be avaible in 1-2 weeks 🎉</Heading>
<div className="z-10 p-1 pt-20 lg:max-w-4xl lg:pt-12 mx-auto col-span-12 md:col-span-6 skew-y-1 md:skew-y-3">
<HeroImage />
<div
className="w-4/5 h-4/6 inline-block rotate-1 bg-primary absolute top-[20%] left-[50%] -translate-x-1/2 blur-[120px] -z-10 shadow"
style={{ animation: 'shadow-slide infinite 4s linear alternate' }}
/>
</div>
</PageContainer>
)
}
Loading

0 comments on commit 2e8da21

Please sign in to comment.