import { PermissionAction } from '@supabase/shared-types/out/constants' import { Eye, EyeOff, Loader2 } from 'lucide-react' import { useState } from 'react' import type { UseFormReturn } from 'react-hook-form' import { useParams } from 'common' import { InlineLink } from 'components/ui/InlineLink' import { getKeys, useAPIKeysQuery } from 'data/api-keys/api-keys-query' import { useAnalyticsBucketsQuery } from 'data/storage/analytics-buckets-query' import { useIcebergNamespacesQuery } from 'data/storage/iceberg-namespaces-query' import { useStorageCredentialsQuery } from 'data/storage/s3-access-key-query' import { useAsyncCheckPermissions } from 'hooks/misc/useCheckPermissions' import { Button, FormControl_Shadcn_, FormField_Shadcn_, Input_Shadcn_, Select_Shadcn_, SelectContent_Shadcn_, SelectGroup_Shadcn_, SelectItem_Shadcn_, SelectSeparator_Shadcn_, SelectTrigger_Shadcn_, TextArea_Shadcn_, WarningIcon, } from 'ui' import { Admonition } from 'ui-patterns' import { Input } from 'ui-patterns/DataInputs/Input' import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import { CREATE_NEW_KEY, CREATE_NEW_NAMESPACE } from './DestinationPanel.constants' import type { DestinationPanelSchemaType } from './DestinationPanel.schema' export const BigQueryFields = ({ form }: { form: UseFormReturn }) => { return ( <>

BigQuery settings

Configure how data is sent to your BigQuery destination

( )} /> ( )} /> ( )} />
) } /** * [Joshen] JFYI I'd foresee a possible UX friction point here regarding S3 access key IDs and secret access keys * - We'd allow users to select access key IDs via a dropdown here, but require a text input for secret access keys * - Chances are most users wouldn't have the corresponding secret access key for the selected key ID at the top of their heads * - So highly likely may have to default to "Create a new key" -> which from here they won't know the secret access key thereafter * - And it'll end up just creating more keys for each destination * Ideal scenario: Just select an access key ID, we then apply the secret access key in the PATCH request, so FE has no * context of the secret access key at any point */ export const AnalyticsBucketFields = ({ form, setIsFormInteracting, }: { form: UseFormReturn setIsFormInteracting: (value: boolean) => void }) => { const { warehouseName, type, s3AccessKeyId, namespace } = form.watch() const [showCatalogToken, setShowCatalogToken] = useState(false) const [showSecretAccessKey, setShowSecretAccessKey] = useState(false) const { ref: projectRef } = useParams() const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*') const { data: apiKeys } = useAPIKeysQuery( { projectRef, reveal: true }, { enabled: canReadAPIKeys } ) const { serviceKey } = getKeys(apiKeys) const serviceApiKey = serviceKey?.api_key ?? '' const { data: keysData, isSuccess: isSuccessKeys, isPending: isLoadingKeys, isError: isErrorKeys, } = useStorageCredentialsQuery({ projectRef }) const s3Keys = keysData?.data ?? [] const keyNoLongerExists = (s3AccessKeyId ?? '').length > 0 && s3AccessKeyId !== CREATE_NEW_KEY && !s3Keys.find((k) => k.access_key === s3AccessKeyId) const { data: analyticsBuckets = [], isPending: isLoadingBuckets, isError: isErrorBuckets, } = useAnalyticsBucketsQuery({ projectRef }) const canSelectNamespace = !!warehouseName && !!serviceApiKey const { data: namespaces = [], isPending: isLoadingNamespaces, isError: isErrorNamespaces, } = useIcebergNamespacesQuery( { projectRef, warehouse: warehouseName, }, { enabled: type === 'Analytics Bucket' && !!serviceApiKey, } ) return ( <>

Analytics Bucket settings

Configure how data is sent to your Analytics Bucket destination

( {isLoadingBuckets ? ( ) : isErrorBuckets ? ( ) : ( { setIsFormInteracting(true) field.onChange(value) // [Joshen] Ideally should select the first namespace of the selected bucket form.setValue('namespace', '') }} > {field.value || 'Select a bucket'} {analyticsBuckets.length === 0 ? ( No buckets available ) : ( analyticsBuckets.map((bucket) => ( {bucket.name} )) )} )} )} /> ( {isLoadingNamespaces && canSelectNamespace ? ( ) : isErrorNamespaces ? ( ) : ( { setIsFormInteracting(true) field.onChange(value) }} disabled={!canSelectNamespace} > {!canSelectNamespace ? 'Select a warehouse first' : field.value === CREATE_NEW_NAMESPACE ? 'Create a new namespace' : field.value || 'Select a namespace'} {namespaces.length === 0 ? ( No namespaces available ) : ( namespaces.map((namespace) => ( {namespace} )) )} {namespaces.length > 0 && } Create a new namespace )} )} /> {namespace === CREATE_NEW_NAMESPACE && ( ( )} /> )} ( Automatically retrieved from your project's{' '} service role key } >
) : null } /> )} /> ( {isLoadingKeys ? ( ) : isErrorKeys ? ( ) : ( {field.value === CREATE_NEW_KEY ? 'Create a new key' : (field.value ?? '').length === 0 ? 'Select an access key ID' : field.value} {s3Keys.map((key) => ( {key.access_key}

{key.description}

))} Create a new key
)}
)} /> {isSuccessKeys && keyNoLongerExists && (

Please select another key or create a new set, as this destination will not work otherwise. S3 access keys can be managed in your{' '} storage settings

)} {s3AccessKeyId === CREATE_NEW_KEY ? (

S3 access keys can be managed in your{' '} storage settings .

) : ( (