import {Fragment} from 'react'; import { addErrorMessage, addLoadingMessage, clearIndicators, } from 'sentry/actionCreators/indicator'; import {LinkButton} from 'sentry/components/button'; import EmptyMessage from 'sentry/components/emptyMessage'; import FieldGroup from 'sentry/components/forms/fieldGroup'; import Link from 'sentry/components/links/link'; import LoadingError from 'sentry/components/loadingError'; import LoadingIndicator from 'sentry/components/loadingIndicator'; import Panel from 'sentry/components/panels/panel'; import PanelAlert from 'sentry/components/panels/panelAlert'; import PanelBody from 'sentry/components/panels/panelBody'; import PanelHeader from 'sentry/components/panels/panelHeader'; import Switch from 'sentry/components/switchButton'; import Truncate from 'sentry/components/truncate'; import {IconAdd} from 'sentry/icons'; import {t} from 'sentry/locale'; import type {ServiceHook} from 'sentry/types/integrations'; import { setApiQueryData, useApiQuery, useMutation, useQueryClient, } from 'sentry/utils/queryClient'; import useApi from 'sentry/utils/useApi'; import useOrganization from 'sentry/utils/useOrganization'; import {useParams} from 'sentry/utils/useParams'; import withOrganization from 'sentry/utils/withOrganization'; import SettingsPageHeader from 'sentry/views/settings/components/settingsPageHeader'; type RowProps = { hook: ServiceHook; onToggleActive: () => void; orgId: string; projectId: string; }; function ServiceHookRow({orgId, projectId, hook, onToggleActive}: RowProps) { return ( } help={ {hook.events && hook.events.length !== 0 ? ( hook.events.join(', ') ) : ( {t('no events configured')} )} } > ); } function ProjectServiceHooks() { const organization = useOrganization(); const {projectId} = useParams<{projectId: string}>(); const api = useApi({persistInFlight: true}); const queryClient = useQueryClient(); const { data: hookList, isPending, isError, refetch, } = useApiQuery([`/projects/${organization.slug}/${projectId}/hooks/`], { staleTime: 0, }); const onToggleActiveMutation = useMutation({ mutationFn: ({hook}: {hook: ServiceHook}) => { return api.requestPromise( `/projects/${organization.slug}/${projectId}/hooks/${hook.id}/`, { method: 'PUT', data: { isActive: hook.status !== 'active', }, } ); }, onMutate: () => { addLoadingMessage(t('Saving changes\u2026')); }, onSuccess: data => { clearIndicators(); setApiQueryData( queryClient, [`/projects/${organization.slug}/${projectId}/hooks/`], oldHookList => { return oldHookList.map(h => { if (h.id === data.id) { return { ...h, ...data, }; } return h; }); } ); }, onError: () => { addErrorMessage(t('Unable to remove application. Please try again.')); }, }); if (isPending) { return ; } if (isError) { return ; } const renderEmpty = () => { return ( {t('There are no service hooks associated with this project.')} ); }; const renderResults = () => { return ( {t('Service Hook')} {t( 'Service Hooks are an early adopter preview feature and will change in the future.' )} {hookList?.map(hook => ( onToggleActiveMutation.mutate({hook})} /> ))} ); }; const body = hookList && hookList.length > 0 ? renderResults() : renderEmpty(); return ( } > {t('Create New Hook')} ) : null } /> {body} ); } export default withOrganization(ProjectServiceHooks);