import {closeModal, openEditOwnershipRules, openModal} from 'sentry/actionCreators/modal'; import Access, {hasEveryAccess} from 'sentry/components/acl/access'; import Alert from 'sentry/components/alert'; import {Button} from 'sentry/components/button'; import ButtonBar from 'sentry/components/buttonBar'; import ErrorBoundary from 'sentry/components/errorBoundary'; import Form from 'sentry/components/forms/form'; import JsonForm from 'sentry/components/forms/jsonForm'; import ExternalLink from 'sentry/components/links/externalLink'; import LoadingIndicator from 'sentry/components/loadingIndicator'; import SentryDocumentTitle from 'sentry/components/sentryDocumentTitle'; import {IconEdit} from 'sentry/icons'; import {t, tct} from 'sentry/locale'; import type {IssueOwnership} from 'sentry/types/group'; import type {CodeOwner} from 'sentry/types/integrations'; import type {Project} from 'sentry/types/project'; import { type ApiQueryKey, setApiQueryData, useApiQuery, useQueryClient, } from 'sentry/utils/queryClient'; import routeTitleGen from 'sentry/utils/routeTitle'; import useOrganization from 'sentry/utils/useOrganization'; import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader'; import TextBlock from 'sentry/views/settings/components/text/textBlock'; import PermissionAlert from 'sentry/views/settings/project/permissionAlert'; import AddCodeOwnerModal from 'sentry/views/settings/project/projectOwnership/addCodeOwnerModal'; import {CodeOwnerErrors} from 'sentry/views/settings/project/projectOwnership/codeownerErrors'; import {CodeOwnerFileTable} from 'sentry/views/settings/project/projectOwnership/codeOwnerFileTable'; import {OwnershipRulesTable} from 'sentry/views/settings/project/projectOwnership/ownershipRulesTable'; export default function ProjectOwnership({project}: {project: Project}) { const organization = useOrganization(); const queryClient = useQueryClient(); const ownershipTitle = t('Ownership Rules'); const ownershipQueryKey: ApiQueryKey = [ `/projects/${organization.slug}/${project.slug}/ownership/`, ]; const { data: ownership, isLoading: isOwnershipLoading, isError: isOwnershipError, } = useApiQuery(ownershipQueryKey, {staleTime: Infinity}); const codeownersQueryKey: ApiQueryKey = [ `/projects/${organization.slug}/${project.slug}/codeowners/`, {query: {expand: ['codeMapping', 'ownershipSyntax']}}, ]; const { data: codeowners = [], isLoading: isCodeownersLoading, error: codeownersRequestError, } = useApiQuery(codeownersQueryKey, {staleTime: Infinity}); const handleOwnershipSave = (newOwnership: IssueOwnership) => { setApiQueryData(queryClient, ownershipQueryKey, data => newOwnership ? newOwnership : data ); closeModal(); }; const handleCodeOwnerAdded = (data: CodeOwner) => { setApiQueryData(queryClient, codeownersQueryKey, existingCodeowners => [ data, ...(existingCodeowners || []), ]); }; const handleCodeOwnerDeleted = (data: CodeOwner) => { setApiQueryData(queryClient, codeownersQueryKey, existingCodeowners => (existingCodeowners || []).filter(codeowner => codeowner.id !== data.id) ); }; const handleCodeOwnerUpdated = (data: CodeOwner) => { setApiQueryData(queryClient, codeownersQueryKey, stateCodeOwners => { const existingCodeowners = stateCodeOwners || []; const index = existingCodeowners.findIndex(item => item.id === data.id); return [ ...existingCodeowners.slice(0, index), data, ...existingCodeowners.slice(index + 1), ]; }); }; const handleAddCodeOwner = () => { openModal(modalProps => ( )); }; const disabled = !hasEveryAccess(['project:write'], {organization, project}); const editOwnershipRulesDisabled = !hasEveryAccess(['project:read'], { organization, project, }); const hasCodeowners = organization.features?.includes('integrations-codeowners'); if (isOwnershipLoading || isCodeownersLoading) { return ; } return ( {hasCodeowners && ( {({hasAccess}) => ( )} )} } /> {tct( `Auto-assign issues to users and teams. To learn more, [link:read the docs].`, { link: ( ), } )} {codeownersRequestError && ( {t( "There was an error loading this project's codeowners. If this issue persists, consider importing it again." )} )} {ownership && ( )} {hasCodeowners && ( )} {ownership && !isOwnershipError ? (
) : ( {t('There was an error issue owner settings.')} )}
); }