| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- import { zodResolver } from '@hookform/resolvers/zod'
- import { PermissionAction } from '@supabase/shared-types/out/constants'
- import { useQueryClient } from '@tanstack/react-query'
- import { LOCAL_STORAGE_KEYS } from 'common'
- import { useForm } from 'react-hook-form'
- import { toast } from 'sonner'
- import * as z from 'zod'
- import { useOrganizationUpdateMutation } from '@/data/organizations/organization-update-mutation'
- import { invalidateOrganizationsQuery } from '@/data/organizations/organizations-query'
- import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
- import { useLocalStorageQuery } from '@/hooks/misc/useLocalStorage'
- import { getAiOptInLevel } from '@/hooks/misc/useOrgOptedIntoAi'
- import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization'
- import { OPT_IN_TAGS } from '@/lib/constants'
- import type { ResponseError } from '@/types'
- // Shared schema definition
- export const AIOptInSchema = z.object({
- aiOptInLevel: z.enum(['disabled', 'schema', 'schema_and_log', 'schema_and_log_and_data'], {
- required_error: 'AI Opt-in level selection is required',
- }),
- })
- export type AIOptInFormValues = z.infer<typeof AIOptInSchema>
- /**
- * Hook to manage the AI Opt-In form state and submission logic.
- * Optionally takes an onSuccess callback (e.g., to close a modal).
- */
- export const useAIOptInForm = (onSuccessCallback?: () => void) => {
- const queryClient = useQueryClient()
- const { data: selectedOrganization } = useSelectedOrganizationQuery()
- const { can: canUpdateOrganization } = useAsyncCheckPermissions(
- PermissionAction.UPDATE,
- 'organizations'
- )
- const [, setUpdatedOptInSinceMCP] = useLocalStorageQuery(
- LOCAL_STORAGE_KEYS.AI_ASSISTANT_MCP_OPT_IN,
- false
- )
- const { mutate: updateOrganization, isPending: isUpdating } = useOrganizationUpdateMutation()
- const form = useForm<AIOptInFormValues>({
- resolver: zodResolver(AIOptInSchema as any),
- defaultValues: {
- aiOptInLevel: getAiOptInLevel(selectedOrganization?.opt_in_tags),
- },
- })
- const onSubmit = async (values: AIOptInFormValues) => {
- if (!canUpdateOrganization) {
- return toast.error('You do not have the required permissions to update this organization')
- }
- if (!selectedOrganization?.slug) {
- console.error('Organization slug is required')
- return toast.error('Failed to update settings: Organization not found.')
- }
- const existingOptInTags = selectedOrganization?.opt_in_tags ?? []
- let updatedOptInTags = existingOptInTags.filter(
- (tag: string) =>
- tag !== OPT_IN_TAGS.AI_SQL &&
- tag !== (OPT_IN_TAGS.AI_DATA ?? 'AI_DATA') &&
- tag !== (OPT_IN_TAGS.AI_LOG ?? 'AI_LOG')
- )
- if (
- values.aiOptInLevel === 'schema' ||
- values.aiOptInLevel === 'schema_and_log' ||
- values.aiOptInLevel === 'schema_and_log_and_data'
- ) {
- updatedOptInTags.push(OPT_IN_TAGS.AI_SQL)
- }
- if (
- values.aiOptInLevel === 'schema_and_log' ||
- values.aiOptInLevel === 'schema_and_log_and_data'
- ) {
- updatedOptInTags.push(OPT_IN_TAGS.AI_LOG)
- }
- if (values.aiOptInLevel === 'schema_and_log_and_data') {
- updatedOptInTags.push(OPT_IN_TAGS.AI_DATA)
- }
- updatedOptInTags = [...new Set(updatedOptInTags)]
- updateOrganization(
- { slug: selectedOrganization.slug, opt_in_tags: updatedOptInTags },
- {
- onSuccess: () => {
- invalidateOrganizationsQuery(queryClient)
- toast.success('Successfully updated AI opt-in settings')
- setUpdatedOptInSinceMCP(true)
- onSuccessCallback?.() // Call optional callback on success
- },
- onError: (error: ResponseError) => {
- toast.error(`Failed to update settings: ${error.message}`)
- },
- }
- )
- }
- return {
- form,
- onSubmit,
- isUpdating,
- currentOptInLevel: getAiOptInLevel(selectedOrganization?.opt_in_tags),
- }
- }
|