import {Fragment} from 'react'; import type {Location} from 'history'; import Feature from 'sentry/components/acl/feature'; import FeatureDisabled from 'sentry/components/acl/featureDisabled'; import GuideAnchor from 'sentry/components/assistant/guideAnchor'; import {Button} from 'sentry/components/button'; import DataExport, {ExportQueryType} from 'sentry/components/dataExport'; import {InvestigationRuleCreation} from 'sentry/components/dynamicSampling/investigationRule'; import {Hovercard} from 'sentry/components/hovercard'; import {IconDownload, IconSliders, IconTag} from 'sentry/icons'; import {t} from 'sentry/locale'; import type {OrganizationSummary} from 'sentry/types/organization'; import {trackAnalytics} from 'sentry/utils/analytics'; import {parseCursor} from 'sentry/utils/cursor'; import type {TableData} from 'sentry/utils/discover/discoverQuery'; import type EventView from 'sentry/utils/discover/eventView'; import {SavedQueryDatasets} from 'sentry/utils/discover/types'; import {useLocation} from 'sentry/utils/useLocation'; import useOrganization from 'sentry/utils/useOrganization'; import {hasDatasetSelector} from 'sentry/views/dashboards/utils'; import {downloadAsCsv} from '../utils'; type Props = { error: string | null; eventView: EventView; isLoading: boolean; location: Location; onChangeShowTags: () => void; onEdit: () => void; organization: OrganizationSummary; showTags: boolean; tableData: TableData | null | undefined; title: string; queryDataset?: SavedQueryDatasets; supportsInvestigationRule?: boolean; }; function handleDownloadAsCsv(title: string, {organization, eventView, tableData}: Props) { trackAnalytics('discover_v2.results.download_csv', { organization: organization.id, // org summary }); downloadAsCsv(tableData, eventView.getColumns(), title); } function renderDownloadButton(canEdit: boolean, props: Props) { const {tableData} = props; return ( renderBrowserExportButton(canEdit, props)} > {tableData?.data && tableData.data.length < 50 ? renderBrowserExportButton(canEdit, props) : renderAsyncExportButton(canEdit, props)} ); } function renderBrowserExportButton(canEdit: boolean, props: Props) { const {isLoading, error} = props; const disabled = isLoading || error !== null || canEdit === false; const onClick = disabled ? undefined : () => handleDownloadAsCsv(props.title, props); return ( ); } function renderAsyncExportButton(canEdit: boolean, props: Props) { const {isLoading, error, location, eventView} = props; const disabled = isLoading || error !== null || canEdit === false; return ( } > {t('Export All')} ); } // Placate eslint proptype checking function renderEditButton(canEdit: boolean, props: Props) { const onClick = canEdit ? props.onEdit : undefined; return ( ); } // Placate eslint proptype checking function renderSummaryButton({onChangeShowTags, showTags}: Props) { return ( ); } type FeatureWrapperProps = Props & { children: (hasFeature: boolean, props: Props) => React.ReactNode; }; function FeatureWrapper(props: FeatureWrapperProps) { const noEditMessage = t('Requires discover query feature.'); const editFeatures = ['organizations:discover-query']; const renderDisabled = p => ( } > {p.children(p)} ); return ( {({hasFeature}) => props.children(hasFeature, props)} ); } function TableActions(props: Props) { const {tableData, queryDataset, supportsInvestigationRule} = props; const location = useLocation(); const organization = useOrganization(); const cursor = location?.query?.cursor; const cursorOffset = parseCursor(cursor)?.offset ?? 0; const numSamples = tableData?.data?.length ?? null; const totalNumSamples = numSamples === null ? null : numSamples + cursorOffset; const isTransactions = hasDatasetSelector(organization) && queryDataset === SavedQueryDatasets.TRANSACTIONS; return ( {supportsInvestigationRule && (!hasDatasetSelector(organization) || isTransactions) && ( )} {renderEditButton} {renderDownloadButton} {renderSummaryButton(props)} ); } export default TableActions;