diff --git a/frontend/src/queries/nodes/DataTable/DataTableExport.tsx b/frontend/src/queries/nodes/DataTable/DataTableExport.tsx index 347b882d14e70..fececcef672ff 100644 --- a/frontend/src/queries/nodes/DataTable/DataTableExport.tsx +++ b/frontend/src/queries/nodes/DataTable/DataTableExport.tsx @@ -16,14 +16,14 @@ import { } from '~/queries/nodes/DataTable/utils' import { getPersonsEndpoint } from '~/queries/query' import { DataNode, DataTableNode, NodeKind } from '~/queries/schema' -import { isEventsQuery, isHogQLQuery, isPersonsNode } from '~/queries/utils' +import { isActorsQuery, isEventsQuery, isHogQLQuery, isPersonsNode } from '~/queries/utils' import { ExporterFormat } from '~/types' import { dataTableLogic, DataTableRow } from './dataTableLogic' -const EXPORT_MAX_LIMIT = 10000 +export const EXPORT_MAX_LIMIT = 10000 -async function startDownload(query: DataTableNode, onlySelectedColumns: boolean): Promise { +export async function startDownload(query: DataTableNode, onlySelectedColumns: boolean): Promise { const exportContext = isPersonsNode(query.source) ? { path: getPersonsEndpoint(query.source) } : { source: query.source } @@ -33,7 +33,7 @@ async function startDownload(query: DataTableNode, onlySelectedColumns: boolean) if (onlySelectedColumns) { exportContext['columns'] = ( - (isEventsQuery(query.source) ? query.source.select : null) ?? + (isEventsQuery(query.source) || isActorsQuery(query.source) ? query.source.select : null) ?? query.columns ?? defaultDataTableColumns(query.source.kind) )?.filter((c) => c !== 'person.$delete') diff --git a/frontend/src/scenes/retention/RetentionModal.tsx b/frontend/src/scenes/retention/RetentionModal.tsx index 72b0e59fb9a3e..4c5c8cea6b432 100644 --- a/frontend/src/scenes/retention/RetentionModal.tsx +++ b/frontend/src/scenes/retention/RetentionModal.tsx @@ -14,6 +14,9 @@ import { RetentionTableAppearanceType } from 'scenes/retention/types' import { MissingPersonsAlert } from 'scenes/trends/persons-modal/PersonsModal' import { urls } from 'scenes/urls' +import { EXPORT_MAX_LIMIT, startDownload } from '~/queries/nodes/DataTable/DataTableExport' +import { ExportWithConfirmation } from '~/queries/nodes/DataTable/ExportWithConfirmation' +import { DataTableNode, NodeKind } from '~/queries/schema' import { ExporterFormat } from '~/types' import { retentionLogic } from './retentionLogic' @@ -25,9 +28,18 @@ export function RetentionModal(): JSX.Element | null { const { results } = useValues(retentionLogic(insightProps)) const { people, peopleLoading, peopleLoadingMore } = useValues(retentionPeopleLogic(insightProps)) const { loadMorePeople } = useActions(retentionPeopleLogic(insightProps)) - const { aggregationTargetLabel, selectedInterval, exploreUrl } = useValues(retentionModalLogic(insightProps)) + const { aggregationTargetLabel, selectedInterval, exploreUrl, actorsQuery } = useValues( + retentionModalLogic(insightProps) + ) const { closeModal } = useActions(retentionModalLogic(insightProps)) + const dataTableNodeQuery: DataTableNode | undefined = actorsQuery + ? { + kind: NodeKind.DataTableNode, + source: actorsQuery, + } + : undefined + if (!results || selectedInterval === null) { return null } @@ -41,19 +53,34 @@ export function RetentionModal(): JSX.Element | null { footer={
- - void triggerExport({ - export_format: ExporterFormat.CSV, - export_context: { - path: row?.people_url, - }, - }) - } - > - Download CSV - + {!exploreUrl && ( + + void triggerExport({ + export_format: ExporterFormat.CSV, + export_context: { + path: row?.people_url, + }, + }) + } + > + Download CSV + + )} + {!!dataTableNodeQuery && ( + { + dataTableNodeQuery && void startDownload(dataTableNodeQuery, true) + }} + actor={'persons'} + limit={EXPORT_MAX_LIMIT} + > + Export all as CSV + + )}
{exploreUrl && (