import type {ModalTypes} from 'sentry/components/globalModal'; import type {CreateNewIntegrationModalOptions} from 'sentry/components/modals/createNewIntegrationModal'; import type {CreateReleaseIntegrationModalOptions} from 'sentry/components/modals/createReleaseIntegrationModal'; import type {DashboardWidgetQuerySelectorModalOptions} from 'sentry/components/modals/dashboardWidgetQuerySelectorModal'; import type {InviteRow} from 'sentry/components/modals/inviteMembersModal/types'; import type {ReprocessEventModalOptions} from 'sentry/components/modals/reprocessEventModal'; import type {OverwriteWidgetModalProps} from 'sentry/components/modals/widgetBuilder/overwriteWidgetModal'; import type {WidgetViewerModalOptions} from 'sentry/components/modals/widgetViewerModal'; import type {Category} from 'sentry/components/platformPicker'; import ModalStore from 'sentry/stores/modalStore'; import type {AppStoreConnectStatusData, CustomRepoType} from 'sentry/types/debugFiles'; import type {Event} from 'sentry/types/event'; import type {Group, IssueOwnership} from 'sentry/types/group'; import type {SentryApp} from 'sentry/types/integrations'; import type {MissingMember, Organization, OrgRole, Team} from 'sentry/types/organization'; import type {Project} from 'sentry/types/project'; import {WidgetType} from 'sentry/views/dashboards/types'; export type ModalOptions = ModalTypes['options']; export type ModalRenderProps = ModalTypes['renderProps']; /** * Show a modal */ export function openModal( renderer: (renderProps: ModalRenderProps) => React.ReactNode, options?: ModalOptions ) { ModalStore.openModal(renderer, options ?? {}); } /** * Close modal */ export function closeModal() { ModalStore.closeModal(); } type EmailVerificationModalOptions = { actionMessage?: string; emailVerified?: boolean; onClose?: () => void; }; type InviteMembersModalOptions = { initialData?: Partial[]; onClose?: () => void; source?: string; }; export async function openEmailVerification({ onClose, ...args }: EmailVerificationModalOptions = {}) { const mod = await import('sentry/components/modals/emailVerificationModal'); const {default: Modal} = mod; openModal(deps => , {onClose}); } type OpenDiffModalOptions = { baseIssueId: Group['id']; orgId: Organization['id']; project: Project; targetIssueId: string; baseEventId?: Event['id']; shouldBeGrouped?: string; targetEventId?: string; }; export async function openDiffModal(options: OpenDiffModalOptions) { const mod = await import('sentry/components/modals/diffModal'); const {default: Modal, modalCss} = mod; openModal(deps => , {modalCss}); } type CreateTeamModalOptions = { /** * The organization to create a team for */ organization: Organization; onClose?: (team: Team) => void; /** * An initial project to add the team to. This may be deprecated soon as we may add a project selection inside of the modal flow */ project?: Project; }; export async function openCreateTeamModal(options: CreateTeamModalOptions) { const mod = await import('sentry/components/modals/createTeamModal'); const {default: Modal} = mod; openModal(deps => ); } type CreateOwnershipRuleModalOptions = { issueId: string; /** * The organization to create a rules for */ organization: Organization; /** * The project to create a rules for */ project: Project; /** * Suggestions will be created from the current event */ eventData?: Event; }; /** * Open the edit ownership modal within issue details */ export async function openIssueOwnershipRuleModal( options: CreateOwnershipRuleModalOptions ) { const mod = await import('sentry/components/modals/issueOwnershipRuleModal'); const {default: Modal, modalCss} = mod; openModal(deps => , {modalCss}); } export type EditOwnershipRulesModalOptions = { onSave: (ownership: IssueOwnership) => void; organization: Organization; ownership: IssueOwnership; project: Project; }; export async function openEditOwnershipRules(options: EditOwnershipRulesModalOptions) { const mod = await import('sentry/components/modals/editOwnershipRulesModal'); const {default: Modal, modalCss} = mod; openModal(deps => , { closeEvents: 'escape-key', modalCss, }); } export async function openCommandPalette(options: ModalOptions = {}) { const mod = await import('sentry/components/modals/commandPalette'); const {default: Modal, modalCss} = mod; openModal(deps => , {modalCss}); } type RecoveryModalOptions = { authenticatorName: string; }; export async function openRecoveryOptions(options: RecoveryModalOptions) { const mod = await import('sentry/components/modals/recoveryOptionsModal'); const {default: Modal} = mod; openModal(deps => ); } export type TeamAccessRequestModalOptions = { memberId: string; orgId: string; teamId: string; }; export async function openTeamAccessRequestModal(options: TeamAccessRequestModalOptions) { const mod = await import('sentry/components/modals/teamAccessRequestModal'); const {default: Modal} = mod; openModal(deps => ); } type HelpSearchModalOptions = { organization?: Organization; placeholder?: string; }; export async function openHelpSearchModal(options?: HelpSearchModalOptions) { const mod = await import('sentry/components/modals/helpSearchModal'); const {default: Modal, modalCss} = mod; openModal(deps => , {modalCss}); } export type SentryAppDetailsModalOptions = { isInstalled: boolean; onInstall: () => Promise; organization: Organization; sentryApp: SentryApp; onCloseModal?: () => void; // used for analytics }; type DebugFileSourceModalOptions = { appStoreConnectSourcesQuantity: number; onSave: (data: Record) => Promise; organization: Organization; sourceType: CustomRepoType; appStoreConnectStatusData?: AppStoreConnectStatusData; onClose?: () => void; sourceConfig?: Record; }; export async function openDebugFileSourceModal({ onClose, ...restOptions }: DebugFileSourceModalOptions) { const mod = await import('sentry/components/modals/debugFileCustomRepository'); const {default: Modal, modalCss} = mod; openModal(deps => , { modalCss, onClose, }); } export async function openInviteMembersModal({ onClose, ...args }: InviteMembersModalOptions = {}) { const mod = await import('sentry/components/modals/inviteMembersModal'); const {default: Modal, modalCss} = mod; openModal(deps => , {modalCss, onClose}); } type InviteMissingMembersModalOptions = { allowedRoles: OrgRole[]; missingMembers: MissingMember[]; onClose: () => void; organization: Organization; }; export async function openInviteMissingMembersModal({ onClose, ...args }: InviteMissingMembersModalOptions) { const mod = await import('sentry/components/modals/inviteMissingMembersModal'); const {default: Modal, modalCss} = mod; openModal(deps => , {modalCss, onClose}); } export async function openWidgetBuilderOverwriteModal( options: OverwriteWidgetModalProps ) { const mod = await import('sentry/components/modals/widgetBuilder/overwriteWidgetModal'); const {default: Modal, modalCss} = mod; openModal(deps => , { closeEvents: 'escape-key', modalCss, }); } export async function openAddToDashboardModal(options) { const mod = await import('sentry/components/modals/widgetBuilder/addToDashboardModal'); const {default: Modal, modalCss} = mod; openModal(deps => , { closeEvents: 'escape-key', modalCss, }); } export async function openImportDashboardFromFileModal(options) { const mod = await import('sentry/components/modals/importDashboardFromFileModal'); const {default: Modal, modalCss} = mod; openModal(deps => , { closeEvents: 'escape-key', modalCss, }); } export async function openCreateDashboardFromScratchpad(options) { const mod = await import('sentry/components/modals/createDashboardFromScratchpadModal'); const {default: Modal, modalCss} = mod; openModal(deps => , { closeEvents: 'escape-key', modalCss, }); } export async function openReprocessEventModal({ onClose, ...options }: ReprocessEventModalOptions & {onClose?: () => void}) { const {ReprocessingEventModal} = await import( 'sentry/components/modals/reprocessEventModal' ); openModal(deps => , {onClose}); } export async function demoSignupModal(options: ModalOptions = {}) { const mod = await import('sentry/components/modals/demoSignUp'); const {default: Modal, modalCss} = mod; openModal(deps => , {modalCss}); } export type DemoEndModalOptions = { orgSlug: string | null; tour: string; }; export async function demoEndModal(options: DemoEndModalOptions) { const mod = await import('sentry/components/modals/demoEndModal'); const {default: Modal, modalCss} = mod; openModal(deps => , {modalCss}); } export async function openDashboardWidgetQuerySelectorModal( options: DashboardWidgetQuerySelectorModalOptions ) { const mod = await import('sentry/components/modals/dashboardWidgetQuerySelectorModal'); const {default: Modal, modalCss} = mod; openModal(deps => , { closeEvents: 'escape-key', modalCss, }); } export async function openWidgetViewerModal({ onClose, ...options }: WidgetViewerModalOptions & {onClose?: () => void}) { const modalPromise = options.widget.widgetType === WidgetType.METRICS ? import('sentry/components/modals/metricWidgetViewerModal') : import('sentry/components/modals/widgetViewerModal'); const mod = await modalPromise; const {default: Modal, modalCss} = mod; openModal(deps => , { closeEvents: 'escape-key', modalCss, onClose, }); } export async function openCreateNewIntegrationModal( options: CreateNewIntegrationModalOptions ) { const mod = await import('sentry/components/modals/createNewIntegrationModal'); const {default: Modal} = mod; openModal(deps => ); } export async function openCreateReleaseIntegration( options: CreateReleaseIntegrationModalOptions ) { const mod = await import('sentry/components/modals/createReleaseIntegrationModal'); const {default: Modal} = mod; openModal(deps => ); } export type NavigateToExternalLinkModalOptions = { linkText: string; }; export async function openNavigateToExternalLinkModal( options: NavigateToExternalLinkModalOptions ) { const mod = await import('sentry/components/modals/navigateToExternalLinkModal'); const {default: Modal} = mod; openModal(deps => ); } export async function openProjectCreationModal(options: {defaultCategory: Category}) { const mod = await import('sentry/components/modals/projectCreationModal'); const {default: Modal, modalCss} = mod; openModal(deps => , {modalCss}); } export async function openBulkEditMonitorsModal({onClose, ...options}: ModalOptions) { const mod = await import('sentry/components/modals/bulkEditMonitorsModal'); const {default: Modal, modalCss} = mod; openModal(deps => , {modalCss, onClose}); }