EdgeFunctionRenderer.tsx 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // @ts-nocheck
  2. import { useParams } from 'common'
  3. import { useMemo, useState, type PropsWithChildren } from 'react'
  4. import { EdgeFunctionBlock } from '../EdgeFunctionBlock/EdgeFunctionBlock'
  5. import { ConfirmFooter } from './ConfirmFooter'
  6. import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query'
  7. import { useEdgeFunctionQuery } from '@/data/edge-functions/edge-function-query'
  8. import { useSendEventMutation } from '@/data/telemetry/send-event-mutation'
  9. import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
  10. interface EdgeFunctionRendererProps {
  11. label: string
  12. code: string
  13. functionName: string
  14. onApprove?: () => void
  15. onDeny?: () => void
  16. isDeploying?: boolean
  17. initialIsDeployed?: boolean
  18. showConfirmFooter?: boolean
  19. }
  20. export const EdgeFunctionRenderer = ({
  21. label,
  22. code,
  23. functionName,
  24. onApprove,
  25. onDeny,
  26. isDeploying = false,
  27. initialIsDeployed,
  28. showConfirmFooter = true,
  29. }: PropsWithChildren<EdgeFunctionRendererProps>) => {
  30. const { ref } = useParams()
  31. const { data: org } = useSelectedOrganizationQuery()
  32. const { mutate: sendEvent } = useSendEventMutation()
  33. const [showReplaceWarning, setShowReplaceWarning] = useState(false)
  34. const { data: settings } = useProjectSettingsV2Query({ projectRef: ref }, { enabled: !!ref })
  35. const { data: existingFunction } = useEdgeFunctionQuery(
  36. { projectRef: ref, slug: functionName },
  37. { enabled: !!ref && !!functionName && !initialIsDeployed }
  38. )
  39. const functionUrl = useMemo(() => {
  40. const endpoint = settings?.app_config?.endpoint
  41. if (!endpoint || !ref || !functionName) return undefined
  42. try {
  43. const url = new URL(`https://${endpoint}`)
  44. const restUrlTld = url.hostname.split('.').pop()
  45. return restUrlTld
  46. ? `https://${ref}.briven.${restUrlTld}/functions/v1/${functionName}`
  47. : undefined
  48. } catch (error) {
  49. return undefined
  50. }
  51. }, [settings?.app_config?.endpoint, ref, functionName])
  52. const deploymentDetailsUrl = useMemo(() => {
  53. if (!ref || !functionName) return undefined
  54. return `/project/${ref}/functions/${functionName}/details`
  55. }, [ref, functionName])
  56. const downloadCommand = useMemo(() => {
  57. if (!functionName) return undefined
  58. return `briven functions download ${functionName}`
  59. }, [functionName])
  60. const approveDeploy = () => {
  61. if (!code || isDeploying || !ref || !functionName) return
  62. setShowReplaceWarning(false)
  63. sendEvent({
  64. action: 'edge_function_deploy_button_clicked',
  65. properties: { origin: 'functions_ai_assistant' },
  66. groups: {
  67. project: ref ?? 'Unknown',
  68. organization: org?.slug ?? 'Unknown',
  69. },
  70. })
  71. onApprove?.()
  72. }
  73. const handleDeploy = () => {
  74. if (!code || isDeploying || !ref || !functionName) return
  75. if (existingFunction) {
  76. setShowReplaceWarning(true)
  77. return
  78. }
  79. approveDeploy()
  80. }
  81. return (
  82. <div className="w-auto overflow-x-hidden my-4">
  83. <EdgeFunctionBlock
  84. label={label}
  85. code={code}
  86. functionName={functionName}
  87. disabled={showConfirmFooter}
  88. isDeploying={isDeploying}
  89. isDeployed={initialIsDeployed}
  90. functionUrl={functionUrl}
  91. deploymentDetailsUrl={deploymentDetailsUrl}
  92. downloadCommand={downloadCommand}
  93. hideDeployButton={showConfirmFooter || initialIsDeployed}
  94. showReplaceWarning={showReplaceWarning}
  95. onCancelReplace={() => setShowReplaceWarning(false)}
  96. onConfirmReplace={approveDeploy}
  97. />
  98. {showConfirmFooter && (
  99. <div className="mx-4">
  100. <ConfirmFooter
  101. message="Assistant wants to deploy this Edge Function"
  102. cancelLabel="Skip"
  103. confirmLabel="Deploy"
  104. confirmLabelLoading="Deploying..."
  105. isLoading={isDeploying}
  106. onCancel={() => onDeny?.()}
  107. onConfirm={handleDeploy}
  108. />
  109. </div>
  110. )}
  111. </div>
  112. )
  113. }