import { useParams } from 'common' import { ChevronRight, Trash } from 'lucide-react' import { useState } from 'react' import { toast } from 'sonner' import { Badge, Button, Card, CardContent, cn, Collapsible, CollapsibleContent, CollapsibleTrigger, } from 'ui' import { GenericSkeletonLoader } from 'ui-patterns' import ConfirmationModal from 'ui-patterns/Dialogs/ConfirmationModal' import { LintInfo } from '../Linter/Linter.constants' import { generateRuleText } from './AdvisorRules.utils' import { CreateRuleSheet } from './CreateRuleSheet' import { DisableRuleModal } from './DisableRuleModal' import { EnableRuleModal } from './EnableRuleModal' import AlertError from '@/components/ui/AlertError' import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import { DocsButton } from '@/components/ui/DocsButton' import { useLintRuleDeleteMutation } from '@/data/lint/delete-lint-rule-mutation' import { useProjectLintRulesQuery } from '@/data/lint/lint-rules-query' import { useOrganizationMembersQuery } from '@/data/organizations/organization-members-query' import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' interface AdvisorRuleItemProps { lint: LintInfo } // [Joshen] Context: We're going with a simplified interface for LW15 as we launch // this as a feature preview. Going to be purely disabling rules for the whole project, // not assigning to members, etc (all these can come in the future when we're ready) // Hence using this to clearly indicate where is being simplified const SIMPLIFIED_INTERFACE = true export const AdvisorRuleItem = ({ lint }: AdvisorRuleItemProps) => { const { ref: projectRef } = useParams() const { data: organization } = useSelectedOrganizationQuery() const [open, setOpen] = useState(false) const [expandedLint, setExpandedLint] = useState() const [selectedRuleToDelete, setSelectedRuleToDelete] = useState() const { data: members = [] } = useOrganizationMembersQuery({ slug: organization?.slug }) const { data = { exceptions: [] }, error, isPending: isLoading, isSuccess, isError, } = useProjectLintRulesQuery({ projectRef }) const rules = data.exceptions.filter((x) => x.lint_name === lint.name) const selectedRuleMeta = data.exceptions.find((x) => x.id === selectedRuleToDelete) const selectedMemberForRule = members.find((x) => x.gotrue_id === selectedRuleMeta?.assigned_to) const { mutate: deleteRule, isPending: isDeleting } = useLintRuleDeleteMutation({ onSuccess: () => { toast.success('Successfully deleted rule') setSelectedRuleToDelete(undefined) }, }) const onDeleteRule = () => { if (!projectRef) return console.error('Project ref is required') if (!selectedRuleToDelete) return console.error('No rules selected') deleteRule({ projectRef, ids: [selectedRuleToDelete] }) } if (SIMPLIFIED_INTERFACE) { return (
{lint.icon}
{lint.title} {rules.length > 0 && Disabled}
{rules.length > 0 ? ( ) : ( )}
) } return ( <> { if (open) setExpandedLint(lint.name) else setExpandedLint(undefined) }} >
{lint.icon}
{lint.title} {rules.length > 0 && ( {rules.length} )}
0 ? 'divide-y' : '' )} > {isLoading && (
)} {isError && ( )} {isSuccess && ( <> {rules.length === 0 ? (

Lint is visible to all project members in the{' '} {lint.category} Advisor.

Create a rule to configure the visibility of this lint in your project

) : ( rules.map((rule) => { const member = members.find((x) => x.gotrue_id === rule.assigned_to) const ruleText = generateRuleText(rule, member) return (

{ruleText}

{rule.note && (

{rule.note}

)}
{/* [Joshen] Will implement in part 2 */} {/* } className="w-7" tooltip={{ content: { side: 'bottom', text: 'Edit rule' } }} /> */} } className="w-7" onClick={() => setSelectedRuleToDelete(rule.id)} tooltip={{ content: { side: 'bottom', text: 'Delete rule' } }} />
) }) )} )}
setSelectedRuleToDelete(undefined)} title="Confirm to delete selected rule" onConfirm={() => onDeleteRule()} alert={{ base: { variant: 'warning' }, title: 'The following rule will be removed', description: !!selectedRuleMeta ? generateRuleText(selectedRuleMeta, selectedMemberForRule) : '', }} > {!!selectedRuleMeta && ( <>

The selected lint will appear under the{' '} {lint.category} Advisor again {!!selectedRuleMeta.assigned_to ? ' for all project members' : ''} once this rule is removed.

)}
) }