From 5669b301db2a78f6bea1261c39c2e974d86d47a8 Mon Sep 17 00:00:00 2001 From: Mia Hsu Date: Fri, 16 May 2025 13:40:27 -0700 Subject: [PATCH] feat(aci): add eventUniqueUserFrequency and percentSessions data condition nodes --- .../types/workflowEngine/dataConditions.tsx | 2 + .../actionFilters/comparisonBranches.tsx | 72 +++++++++++++++++++ .../components/actionFilters/constants.tsx | 2 + .../actionFilters/eventFrequency.tsx | 71 +----------------- .../eventUniqueUserFrequency.tsx | 47 ++++++++++++ .../actionFilters/percentSessions.tsx | 45 ++++++++++++ .../components/dataConditionNodes.tsx | 44 ++++++++++++ 7 files changed, 215 insertions(+), 68 deletions(-) create mode 100644 static/app/views/automations/components/actionFilters/comparisonBranches.tsx create mode 100644 static/app/views/automations/components/actionFilters/eventUniqueUserFrequency.tsx create mode 100644 static/app/views/automations/components/actionFilters/percentSessions.tsx diff --git a/static/app/types/workflowEngine/dataConditions.tsx b/static/app/types/workflowEngine/dataConditions.tsx index bfd62ed54d9381..05f83051f05170 100644 --- a/static/app/types/workflowEngine/dataConditions.tsx +++ b/static/app/types/workflowEngine/dataConditions.tsx @@ -57,6 +57,8 @@ export enum DataConditionType { // frequency types for UI only EVENT_FREQUENCY = 'event_frequency', + EVENT_UNIQUE_USER_FREQUENCY = 'event_unique_user_frequency', + PERCENT_SESSIONS = 'percent_sessions', } export enum DataConditionGroupLogicType { diff --git a/static/app/views/automations/components/actionFilters/comparisonBranches.tsx b/static/app/views/automations/components/actionFilters/comparisonBranches.tsx new file mode 100644 index 00000000000000..1dc1bf508850e2 --- /dev/null +++ b/static/app/views/automations/components/actionFilters/comparisonBranches.tsx @@ -0,0 +1,72 @@ +import AutomationBuilderNumberField from 'sentry/components/workflowEngine/form/automationBuilderNumberField'; +import AutomationBuilderSelectField from 'sentry/components/workflowEngine/form/automationBuilderSelectField'; +import {tct} from 'sentry/locale'; +import { + COMPARISON_INTERVAL_CHOICES, + INTERVAL_CHOICES, +} from 'sentry/views/automations/components/actionFilters/constants'; +import {useDataConditionNodeContext} from 'sentry/views/automations/components/dataConditionNodes'; + +export function CountBranch() { + return tct('more than [value] [interval]', { + value: , + interval: , + }); +} + +export function PercentBranch() { + return tct('[value] higher [interval] compared to [comparison_interval]', { + value: , + interval: , + comparison_interval: , + }); +} + +function ValueField() { + const {condition, condition_id, onUpdate} = useDataConditionNodeContext(); + return ( + { + onUpdate({ + value, + }); + }} + /> + ); +} + +function IntervalField() { + const {condition, condition_id, onUpdate} = useDataConditionNodeContext(); + return ( + { + onUpdate({ + interval: value, + }); + }} + /> + ); +} + +function ComparisonIntervalField() { + const {condition, condition_id, onUpdate} = useDataConditionNodeContext(); + return ( + { + onUpdate({ + comparison_interval: value, + }); + }} + /> + ); +} diff --git a/static/app/views/automations/components/actionFilters/constants.tsx b/static/app/views/automations/components/actionFilters/constants.tsx index d7b53a614764b2..6ee904c3c07ba7 100644 --- a/static/app/views/automations/components/actionFilters/constants.tsx +++ b/static/app/views/automations/components/actionFilters/constants.tsx @@ -22,6 +22,8 @@ export const FILTER_DATA_CONDITION_TYPES = [ DataConditionType.TAGGED_EVENT, DataConditionType.LEVEL, DataConditionType.EVENT_FREQUENCY, + DataConditionType.EVENT_UNIQUE_USER_FREQUENCY, + DataConditionType.PERCENT_SESSIONS, ]; export enum MatchType { diff --git a/static/app/views/automations/components/actionFilters/eventFrequency.tsx b/static/app/views/automations/components/actionFilters/eventFrequency.tsx index 8375974762201d..8485bd442f20fb 100644 --- a/static/app/views/automations/components/actionFilters/eventFrequency.tsx +++ b/static/app/views/automations/components/actionFilters/eventFrequency.tsx @@ -1,11 +1,10 @@ -import AutomationBuilderNumberField from 'sentry/components/workflowEngine/form/automationBuilderNumberField'; import AutomationBuilderSelectField from 'sentry/components/workflowEngine/form/automationBuilderSelectField'; import {tct} from 'sentry/locale'; import {DataConditionType} from 'sentry/types/workflowEngine/dataConditions'; import { - COMPARISON_INTERVAL_CHOICES, - INTERVAL_CHOICES, -} from 'sentry/views/automations/components/actionFilters/constants'; + CountBranch, + PercentBranch, +} from 'sentry/views/automations/components/actionFilters/comparisonBranches'; import {useDataConditionNodeContext} from 'sentry/views/automations/components/dataConditionNodes'; export default function EventFrequencyNode() { @@ -44,67 +43,3 @@ function ComparisonTypeField() { /> ); } - -function CountBranch() { - return tct('more than [value] [interval]', { - value: , - interval: , - }); -} - -function PercentBranch() { - return tct('[value] higher [interval] compared to [comparison_interval]', { - value: , - interval: , - comparison_interval: , - }); -} - -function ValueField() { - const {condition, condition_id, onUpdate} = useDataConditionNodeContext(); - return ( - { - onUpdate({ - value, - }); - }} - /> - ); -} - -function IntervalField() { - const {condition, condition_id, onUpdate} = useDataConditionNodeContext(); - return ( - { - onUpdate({ - interval: value, - }); - }} - /> - ); -} - -function ComparisonIntervalField() { - const {condition, condition_id, onUpdate} = useDataConditionNodeContext(); - return ( - { - onUpdate({ - comparison_interval: value, - }); - }} - /> - ); -} diff --git a/static/app/views/automations/components/actionFilters/eventUniqueUserFrequency.tsx b/static/app/views/automations/components/actionFilters/eventUniqueUserFrequency.tsx new file mode 100644 index 00000000000000..f0fe5d20b2a0be --- /dev/null +++ b/static/app/views/automations/components/actionFilters/eventUniqueUserFrequency.tsx @@ -0,0 +1,47 @@ +import AutomationBuilderSelectField from 'sentry/components/workflowEngine/form/automationBuilderSelectField'; +import {tct} from 'sentry/locale'; +import {DataConditionType} from 'sentry/types/workflowEngine/dataConditions'; +import { + CountBranch, + PercentBranch, +} from 'sentry/views/automations/components/actionFilters/comparisonBranches'; +import {useDataConditionNodeContext} from 'sentry/views/automations/components/dataConditionNodes'; + +export default function EventUniqueUserFrequencyNode() { + return tct('Number of users affected by an issue is [select]', { + select: , + }); +} + +function ComparisonTypeField() { + const {condition, condition_id, onUpdateType} = useDataConditionNodeContext(); + + if (condition.comparison_type === DataConditionType.EVENT_UNIQUE_USER_FREQUENCY_COUNT) { + return ; + } + if ( + condition.comparison_type === DataConditionType.EVENT_UNIQUE_USER_FREQUENCY_PERCENT + ) { + return ; + } + + return ( + { + onUpdateType(value); + }} + /> + ); +} diff --git a/static/app/views/automations/components/actionFilters/percentSessions.tsx b/static/app/views/automations/components/actionFilters/percentSessions.tsx new file mode 100644 index 00000000000000..d3df0be4acdf54 --- /dev/null +++ b/static/app/views/automations/components/actionFilters/percentSessions.tsx @@ -0,0 +1,45 @@ +import AutomationBuilderSelectField from 'sentry/components/workflowEngine/form/automationBuilderSelectField'; +import {tct} from 'sentry/locale'; +import {DataConditionType} from 'sentry/types/workflowEngine/dataConditions'; +import { + CountBranch, + PercentBranch, +} from 'sentry/views/automations/components/actionFilters/comparisonBranches'; +import {useDataConditionNodeContext} from 'sentry/views/automations/components/dataConditionNodes'; + +export default function PercentSessionsNode() { + return tct('Percentage of sessions affected by an issue is [select]', { + select: , + }); +} + +function ComparisonTypeField() { + const {condition, condition_id, onUpdateType} = useDataConditionNodeContext(); + + if (condition.comparison_type === DataConditionType.PERCENT_SESSIONS_COUNT) { + return ; + } + if (condition.comparison_type === DataConditionType.PERCENT_SESSIONS_PERCENT) { + return ; + } + + return ( + { + onUpdateType(value); + }} + /> + ); +} diff --git a/static/app/views/automations/components/dataConditionNodes.tsx b/static/app/views/automations/components/dataConditionNodes.tsx index baed208a5fd3bb..2116f8ffda75ee 100644 --- a/static/app/views/automations/components/dataConditionNodes.tsx +++ b/static/app/views/automations/components/dataConditionNodes.tsx @@ -8,10 +8,12 @@ import { import AgeComparisonNode from 'sentry/views/automations/components/actionFilters/ageComparison'; import EventAttributeNode from 'sentry/views/automations/components/actionFilters/eventAttribute'; import EventFrequencyNode from 'sentry/views/automations/components/actionFilters/eventFrequency'; +import EventUniqueUserFrequencyNode from 'sentry/views/automations/components/actionFilters/eventUniqueUserFrequency'; import IssueOccurrencesNode from 'sentry/views/automations/components/actionFilters/issueOccurrences'; import IssuePriorityNode from 'sentry/views/automations/components/actionFilters/issuePriority'; import LatestAdoptedReleaseNode from 'sentry/views/automations/components/actionFilters/latestAdoptedRelease'; import LevelNode from 'sentry/views/automations/components/actionFilters/level'; +import PercentSessionsNode from 'sentry/views/automations/components/actionFilters/percentSessions'; import TaggedEventNode from 'sentry/views/automations/components/actionFilters/taggedEvent'; interface DataConditionNodeProps { @@ -136,4 +138,46 @@ export const dataConditionNodesMap = new Map, }, ], + [ + DataConditionType.EVENT_UNIQUE_USER_FREQUENCY, + { + label: t('Number of users affected'), + dataCondition: , + }, + ], + [ + DataConditionType.EVENT_UNIQUE_USER_FREQUENCY_COUNT, + { + label: t('Number of users affected'), + dataCondition: , + }, + ], + [ + DataConditionType.EVENT_UNIQUE_USER_FREQUENCY_PERCENT, + { + label: t('Number of users affected'), + dataCondition: , + }, + ], + [ + DataConditionType.PERCENT_SESSIONS, + { + label: t('Percentage of sessions affected'), + dataCondition: , + }, + ], + [ + DataConditionType.PERCENT_SESSIONS_COUNT, + { + label: t('Percentage of sessions affected'), + dataCondition: , + }, + ], + [ + DataConditionType.PERCENT_SESSIONS_PERCENT, + { + label: t('Percentage of sessions affected'), + dataCondition: , + }, + ], ]);