import {useState} from 'react'; import styled from '@emotion/styled'; import keyBy from 'lodash/keyBy'; import {Button} from 'sentry/components/button'; import SelectControl from 'sentry/components/forms/controls/selectControl'; import IdBadge from 'sentry/components/idBadge'; import LoadingError from 'sentry/components/loadingError'; import LoadingIndicator from 'sentry/components/loadingIndicator'; import Panel from 'sentry/components/panels/panel'; import PanelBody from 'sentry/components/panels/panelBody'; import PanelHeader from 'sentry/components/panels/panelHeader'; import {IconAdd, IconDelete} from 'sentry/icons'; import {t} from 'sentry/locale'; import ConfigStore from 'sentry/stores/configStore'; import {space} from 'sentry/styles/space'; import type {Organization} from 'sentry/types/organization'; import type {Project} from 'sentry/types/project'; import {useApiQuery} from 'sentry/utils/queryClient'; import useRouter from 'sentry/utils/useRouter'; import type {NotificationOptionsObject} from './constants'; import {NOTIFICATION_SETTING_FIELDS} from './fields2'; import {OrganizationSelectHeader} from './organizationSelectHeader'; type Value = 'always' | 'never' | 'subscribe_only' | 'committed_only'; interface NotificationSettingsByEntityProps { entityType: 'project' | 'organization'; handleAddNotificationOption: ( notificationOption: Omit ) => void; handleEditNotificationOption: (notificationOption: NotificationOptionsObject) => void; handleRemoveNotificationOption: (id: string) => void; notificationOptions: NotificationOptionsObject[]; notificationType: string; organizations: Organization[]; } function NotificationSettingsByEntity({ entityType, handleAddNotificationOption, handleEditNotificationOption, handleRemoveNotificationOption, notificationOptions, notificationType, organizations, }: NotificationSettingsByEntityProps) { const router = useRouter(); const [selectedEntityId, setSelectedEntityId] = useState(null); const [selectedValue, setSelectedValue] = useState(null); const customerDomain = ConfigStore.get('customerDomain'); const orgFromSubdomain = organizations.find( ({slug}) => slug === customerDomain?.subdomain )?.id; const orgId = router.location?.query?.organizationId ?? orgFromSubdomain ?? organizations[0]?.id; let organization = organizations.find(({id}) => id === orgId); if (!organization) { organization = organizations[0]; } const orgSlug = organization.slug; // loads all the projects for an org const { data: projects, isLoading, isSuccess, isError, refetch, } = useApiQuery( [ `/organizations/${orgSlug}/projects/`, { host: organization.links.regionUrl, query: { all_projects: '1', collapse: ['latestDeploys', 'unusedFeatures'], }, }, ], {staleTime: Infinity} ); // always loading all projects even though we only need it sometimes const entities = entityType === 'project' ? projects || [] : organizations; // create maps by the project id for constant time lookups const entityById = keyBy(entities, 'id'); const handleOrgChange = (organizationId: string) => { router.replace({ ...router.location, query: {organizationId}, }); }; const handleAdd = () => { // should never happen if (!selectedEntityId || !selectedValue) { return; } const data = { type: notificationType, scopeType: entityType, scopeIdentifier: selectedEntityId, value: selectedValue, }; setSelectedEntityId(null); setSelectedValue(null); handleAddNotificationOption(data); }; const valueOptions = NOTIFICATION_SETTING_FIELDS[notificationType].choices; const renderOverrides = () => { const matchedOptions = notificationOptions.filter( option => option.type === notificationType && option.scopeType === entityType ); return matchedOptions.map(option => { const entity = entityById[`${option.scopeIdentifier}`]; if (!entity) { return null; } const idBadgeProps = entityType === 'project' ? {project: entity as Project} : {organization: entity as Organization}; return (
{ handleEditNotificationOption({ ...option, value: value as Value, }); }} />