ProjectComplianceMode.tsx126 lines · main
1import { PermissionAction } from '@supabase/shared-types/out/constants'
2import { useParams } from 'common'
3import { Loader2 } from 'lucide-react'
4import { useEffect, useState } from 'react'
5import { toast } from 'sonner'
6import { Card, CardContent, Switch, Tooltip, TooltipContent, TooltipTrigger } from 'ui'
7import {
8 PageSection,
9 PageSectionContent,
10 PageSectionDescription,
11 PageSectionMeta,
12 PageSectionSummary,
13 PageSectionTitle,
14} from 'ui-patterns/PageSection'
15
16import AlertError from '@/components/ui/AlertError'
17import { DocsButton } from '@/components/ui/DocsButton'
18import { InlineLink } from '@/components/ui/InlineLink'
19import { useComplianceConfigUpdateMutation } from '@/data/config/project-compliance-config-mutation'
20import { useProjectSettingsV2Query } from '@/data/config/project-settings-v2-query'
21import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
22import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
23import { DOCS_URL } from '@/lib/constants'
24
25export const ComplianceConfig = () => {
26 const { ref } = useParams()
27 const { data: project } = useSelectedProjectQuery()
28 const [isSensitive, setIsSensitive] = useState(false)
29
30 const { can: canUpdateComplianceConfig } = useAsyncCheckPermissions(
31 PermissionAction.UPDATE,
32 'projects',
33 {
34 resource: { project_id: project?.id },
35 }
36 )
37
38 const {
39 data: settings,
40 error,
41 isError,
42 isPending: isLoading,
43 isSuccess,
44 } = useProjectSettingsV2Query({ projectRef: ref })
45 const initialIsSensitive = settings?.is_sensitive || false
46
47 const { mutate: updateComplianceConfig, isPending: isSubmitting } =
48 useComplianceConfigUpdateMutation({
49 onSuccess: () => {
50 toast.success('Successfully updated project compliance configuration')
51 },
52 onError: (error) => {
53 setIsSensitive(initialIsSensitive)
54 toast.error(`Failed to update project compliance configuration: ${error.message}`)
55 },
56 })
57
58 const toggleIsSensitive = async () => {
59 if (!ref) return console.error('Project ref is required')
60 setIsSensitive(!isSensitive)
61 updateComplianceConfig({ projectRef: ref, isSensitive: !isSensitive })
62 }
63
64 useEffect(() => {
65 if (!isLoading) setIsSensitive(initialIsSensitive)
66 }, [isLoading])
67
68 return (
69 <PageSection id="compliance-configuration">
70 <PageSectionMeta>
71 <div className="flex flex-col gap-3 @lg:flex-row @lg:items-center @lg:justify-between">
72 <PageSectionSummary>
73 <PageSectionTitle>High Compliance Configuration</PageSectionTitle>
74 <PageSectionDescription>
75 For projects storing and processing sensitive data (HIPAA).
76 </PageSectionDescription>
77 </PageSectionSummary>
78 <DocsButton href={`${DOCS_URL}/guides/platform/hipaa-projects`} />
79 </div>
80 </PageSectionMeta>
81 <PageSectionContent>
82 <Card>
83 <CardContent className="flex flex-col gap-4 @lg:flex-row @lg:items-center @lg:justify-between">
84 <div className="space-y-2 max-w-2xl">
85 <p className="text-sm">Apply additional compliance controls to project</p>
86 <p className="text-sm text-foreground-light">
87 Enable security warnings in the{' '}
88 <InlineLink href={`/project/${ref}/advisors/security`}>Security Advisor</InlineLink>{' '}
89 to enforce requirements for managing sensitive data.
90 </p>
91 </div>
92 <div className="flex items-center justify-end space-x-2">
93 {(isLoading || isSubmitting) && (
94 <Loader2 className="animate-spin" strokeWidth={1.5} size={16} />
95 )}
96 {isError && (
97 <AlertError error={error} subject="Failed to retrieve project settings" />
98 )}
99 {isSuccess && (
100 <Tooltip>
101 <TooltipTrigger asChild>
102 {/* [Joshen] Added div as tooltip is messing with data state property of toggle */}
103 <div>
104 <Switch
105 size="large"
106 checked={isSensitive}
107 disabled={isLoading || isSubmitting || !canUpdateComplianceConfig}
108 onCheckedChange={toggleIsSensitive}
109 />
110 </div>
111 </TooltipTrigger>
112 {!canUpdateComplianceConfig && (
113 <TooltipContent side="bottom" className="w-64 text-center">
114 You need additional permissions to update the compliance configuration for
115 your project
116 </TooltipContent>
117 )}
118 </Tooltip>
119 )}
120 </div>
121 </CardContent>
122 </Card>
123 </PageSectionContent>
124 </PageSection>
125 )
126}