@startsimpli/funnels 0.1.4 → 0.1.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -31
- package/src/api/README.md +507 -0
- package/src/api/adapter.ts +106 -0
- package/src/api/client.test.ts +640 -0
- package/src/api/client.ts +385 -0
- package/src/api/default-adapter.ts +243 -0
- package/src/api/index.ts +24 -0
- package/src/components/FilterRuleEditor/ARCHITECTURE.md +354 -0
- package/src/components/FilterRuleEditor/FieldSelector.tsx +91 -0
- package/src/components/FilterRuleEditor/FilterRuleEditor.stories.tsx +462 -0
- package/src/components/FilterRuleEditor/FilterRuleEditor.test.tsx +520 -0
- package/src/components/FilterRuleEditor/FilterRuleEditor.tsx +225 -0
- package/src/components/FilterRuleEditor/LogicToggle.tsx +64 -0
- package/src/components/FilterRuleEditor/OperatorSelector.tsx +75 -0
- package/src/components/FilterRuleEditor/README.md +291 -0
- package/src/components/FilterRuleEditor/RuleRow.tsx +246 -0
- package/src/components/FilterRuleEditor/ValueInputs/BooleanValueInput.tsx +54 -0
- package/src/components/FilterRuleEditor/ValueInputs/ChoiceValueInput.tsx +83 -0
- package/src/components/FilterRuleEditor/ValueInputs/DateValueInput.tsx +70 -0
- package/src/components/FilterRuleEditor/ValueInputs/MultiChoiceValueInput.tsx +132 -0
- package/src/components/FilterRuleEditor/ValueInputs/NumberValueInput.tsx +73 -0
- package/src/components/FilterRuleEditor/ValueInputs/TextValueInput.tsx +50 -0
- package/src/components/FilterRuleEditor/ValueInputs/index.ts +12 -0
- package/src/components/FilterRuleEditor/constants.ts +64 -0
- package/src/components/FilterRuleEditor/index.ts +14 -0
- package/src/components/FunnelCard/DESIGN.md +447 -0
- package/src/components/FunnelCard/FunnelCard.stories.tsx +484 -0
- package/src/components/FunnelCard/FunnelCard.test.ts +257 -0
- package/src/components/FunnelCard/FunnelCard.test.tsx +336 -0
- package/src/components/FunnelCard/FunnelCard.tsx +204 -0
- package/src/components/FunnelCard/FunnelStats.tsx +68 -0
- package/src/components/FunnelCard/IMPLEMENTATION_SUMMARY.md +505 -0
- package/src/components/FunnelCard/INSTALLATION.md +304 -0
- package/src/components/FunnelCard/MatchBar.tsx +49 -0
- package/src/components/FunnelCard/README.md +294 -0
- package/src/components/FunnelCard/StageIndicator.tsx +62 -0
- package/src/components/FunnelCard/StatusBadge.tsx +52 -0
- package/src/components/FunnelCard/index.ts +14 -0
- package/src/components/FunnelPreview/EntityCard.tsx +72 -0
- package/src/components/FunnelPreview/FunnelPreview.stories.tsx +227 -0
- package/src/components/FunnelPreview/FunnelPreview.test.tsx +316 -0
- package/src/components/FunnelPreview/FunnelPreview.tsx +249 -0
- package/src/components/FunnelPreview/LoadingPreview.tsx +60 -0
- package/src/components/FunnelPreview/PreviewStats.tsx +78 -0
- package/src/components/FunnelPreview/README.md +337 -0
- package/src/components/FunnelPreview/StageBreakdown.tsx +94 -0
- package/src/components/FunnelPreview/example.tsx +286 -0
- package/src/components/FunnelPreview/index.ts +14 -0
- package/src/components/FunnelRunHistory/COMPONENT_SUMMARY.md +246 -0
- package/src/components/FunnelRunHistory/FunnelRunHistory.stories.tsx +272 -0
- package/src/components/FunnelRunHistory/FunnelRunHistory.test.tsx +323 -0
- package/src/components/FunnelRunHistory/FunnelRunHistory.tsx +329 -0
- package/src/components/FunnelRunHistory/README.md +325 -0
- package/src/components/FunnelRunHistory/RunActions.tsx +168 -0
- package/src/components/FunnelRunHistory/RunDetailsModal.tsx +221 -0
- package/src/components/FunnelRunHistory/RunFilters.tsx +128 -0
- package/src/components/FunnelRunHistory/RunRow.tsx +122 -0
- package/src/components/FunnelRunHistory/RunStatusBadge.tsx +75 -0
- package/src/components/FunnelRunHistory/StageBreakdownList.tsx +110 -0
- package/src/components/FunnelRunHistory/index.ts +51 -0
- package/src/components/FunnelRunHistory/types.ts +40 -0
- package/src/components/FunnelRunHistory/utils.test.ts +126 -0
- package/src/components/FunnelRunHistory/utils.ts +100 -0
- package/src/components/FunnelStageBuilder/AddStageButton.tsx +52 -0
- package/src/components/FunnelStageBuilder/FunnelStageBuilder.css +413 -0
- package/src/components/FunnelStageBuilder/FunnelStageBuilder.stories.tsx +312 -0
- package/src/components/FunnelStageBuilder/FunnelStageBuilder.test.tsx +304 -0
- package/src/components/FunnelStageBuilder/FunnelStageBuilder.tsx +321 -0
- package/src/components/FunnelStageBuilder/README.md +341 -0
- package/src/components/FunnelStageBuilder/StageActions.test.tsx +205 -0
- package/src/components/FunnelStageBuilder/StageActions.tsx +126 -0
- package/src/components/FunnelStageBuilder/StageCard.tsx +202 -0
- package/src/components/FunnelStageBuilder/StageForm.tsx +262 -0
- package/src/components/FunnelStageBuilder/TagInput.test.tsx +178 -0
- package/src/components/FunnelStageBuilder/TagInput.tsx +129 -0
- package/src/components/FunnelStageBuilder/index.ts +21 -0
- package/src/components/FunnelVisualFlow/FlowLegend.tsx +77 -0
- package/{dist/components/index.css → src/components/FunnelVisualFlow/FunnelVisualFlow.css} +89 -13
- package/src/components/FunnelVisualFlow/FunnelVisualFlow.stories.tsx +254 -0
- package/src/components/FunnelVisualFlow/FunnelVisualFlow.test.tsx +208 -0
- package/src/components/FunnelVisualFlow/FunnelVisualFlow.tsx +229 -0
- package/src/components/FunnelVisualFlow/README.md +323 -0
- package/src/components/FunnelVisualFlow/StageNode.tsx +188 -0
- package/src/components/FunnelVisualFlow/example.tsx +227 -0
- package/src/components/FunnelVisualFlow/index.ts +10 -0
- package/src/components/index.ts +102 -0
- package/src/core/README.md +307 -0
- package/src/core/engine.test.ts +1087 -0
- package/src/core/engine.ts +329 -0
- package/src/core/evaluator.example.ts +353 -0
- package/src/core/evaluator.test.ts +639 -0
- package/src/core/evaluator.ts +261 -0
- package/src/core/field-resolver.example.ts +175 -0
- package/src/core/field-resolver.test.ts +541 -0
- package/src/core/field-resolver.ts +247 -0
- package/src/core/index.ts +34 -0
- package/src/core/operators.test.ts +539 -0
- package/src/core/operators.ts +241 -0
- package/src/hooks/index.ts +5 -0
- package/src/hooks/useDebouncedValue.ts +28 -0
- package/src/index.ts +155 -0
- package/src/store/README.md +342 -0
- package/src/store/create-funnel-store.test.ts +686 -0
- package/src/store/create-funnel-store.ts +538 -0
- package/src/store/index.ts +9 -0
- package/src/store/types.ts +294 -0
- package/src/stories/CrossDomain.stories.tsx +149 -0
- package/src/stories/Welcome.stories.tsx +81 -0
- package/src/stories/demo-data/index.ts +3 -0
- package/src/stories/demo-data/investors.ts +216 -0
- package/src/stories/demo-data/leads.ts +223 -0
- package/src/stories/demo-data/recipes.ts +217 -0
- package/src/test/setup.ts +5 -0
- package/src/types/index.ts +843 -0
- package/dist/client-3ESO2NHy.d.ts +0 -310
- package/dist/client-CZu03ACp.d.cts +0 -310
- package/dist/components/index.cjs +0 -3241
- package/dist/components/index.cjs.map +0 -1
- package/dist/components/index.css.map +0 -1
- package/dist/components/index.d.cts +0 -726
- package/dist/components/index.d.ts +0 -726
- package/dist/components/index.js +0 -3194
- package/dist/components/index.js.map +0 -1
- package/dist/core/index.cjs +0 -500
- package/dist/core/index.cjs.map +0 -1
- package/dist/core/index.d.cts +0 -359
- package/dist/core/index.d.ts +0 -359
- package/dist/core/index.js +0 -486
- package/dist/core/index.js.map +0 -1
- package/dist/hooks/index.cjs +0 -20
- package/dist/hooks/index.cjs.map +0 -1
- package/dist/hooks/index.d.cts +0 -11
- package/dist/hooks/index.d.ts +0 -11
- package/dist/hooks/index.js +0 -18
- package/dist/hooks/index.js.map +0 -1
- package/dist/index-BGDEXbuz.d.cts +0 -434
- package/dist/index-BGDEXbuz.d.ts +0 -434
- package/dist/index.cjs +0 -4499
- package/dist/index.cjs.map +0 -1
- package/dist/index.css +0 -198
- package/dist/index.css.map +0 -1
- package/dist/index.d.cts +0 -99
- package/dist/index.d.ts +0 -99
- package/dist/index.js +0 -4421
- package/dist/index.js.map +0 -1
- package/dist/store/index.cjs +0 -389
- package/dist/store/index.cjs.map +0 -1
- package/dist/store/index.d.cts +0 -225
- package/dist/store/index.d.ts +0 -225
- package/dist/store/index.js +0 -386
- package/dist/store/index.js.map +0 -1
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FunnelCard Storybook Stories
|
|
3
|
+
*
|
|
4
|
+
* Visual regression testing and component documentation.
|
|
5
|
+
* Shows all states and variations of FunnelCard component.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
9
|
+
import { FunnelCard } from './FunnelCard';
|
|
10
|
+
import { Funnel, FunnelRun } from '../../types';
|
|
11
|
+
|
|
12
|
+
const meta: Meta<typeof FunnelCard> = {
|
|
13
|
+
title: 'Components/FunnelCard',
|
|
14
|
+
component: FunnelCard,
|
|
15
|
+
parameters: {
|
|
16
|
+
layout: 'padded',
|
|
17
|
+
docs: {
|
|
18
|
+
description: {
|
|
19
|
+
component: 'BRUTALLY GENERIC funnel card component. Works for investor funnels, recipe funnels, lead funnels, or any domain.',
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
tags: ['autodocs'],
|
|
24
|
+
argTypes: {
|
|
25
|
+
onViewFlow: { action: 'onViewFlow' },
|
|
26
|
+
onEdit: { action: 'onEdit' },
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export default meta;
|
|
31
|
+
type Story = StoryObj<typeof FunnelCard>;
|
|
32
|
+
|
|
33
|
+
// Base funnel for stories
|
|
34
|
+
const baseFunnel: Funnel = {
|
|
35
|
+
id: 'funnel-1',
|
|
36
|
+
name: 'Series A Investor Qualification',
|
|
37
|
+
description: 'Identifies qualified Series A investors based on stage focus, check size, and geography.',
|
|
38
|
+
status: 'active',
|
|
39
|
+
input_type: 'contacts',
|
|
40
|
+
stages: [
|
|
41
|
+
{
|
|
42
|
+
id: 'stage-1',
|
|
43
|
+
order: 0,
|
|
44
|
+
name: 'Stage Filter',
|
|
45
|
+
filter_logic: 'AND',
|
|
46
|
+
rules: [
|
|
47
|
+
{ field_path: 'firm.stage', operator: 'in', value: ['Series A', 'Multi-Stage'] },
|
|
48
|
+
],
|
|
49
|
+
match_action: 'tag_continue',
|
|
50
|
+
no_match_action: 'exclude',
|
|
51
|
+
match_tags: ['qualified_stage'],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
id: 'stage-2',
|
|
55
|
+
order: 1,
|
|
56
|
+
name: 'Check Size Filter',
|
|
57
|
+
filter_logic: 'AND',
|
|
58
|
+
rules: [
|
|
59
|
+
{ field_path: 'firm.check_size_min', operator: 'lte', value: 5000000 },
|
|
60
|
+
{ field_path: 'firm.check_size_max', operator: 'gte', value: 3000000 },
|
|
61
|
+
{ field_path: 'firm.active', operator: 'is_true', value: null },
|
|
62
|
+
],
|
|
63
|
+
match_action: 'tag_continue',
|
|
64
|
+
no_match_action: 'tag_exclude',
|
|
65
|
+
match_tags: ['qualified_check_size'],
|
|
66
|
+
no_match_tags: ['excluded_check_size'],
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: 'stage-3',
|
|
70
|
+
order: 2,
|
|
71
|
+
name: 'Geography Filter',
|
|
72
|
+
filter_logic: 'OR',
|
|
73
|
+
rules: [
|
|
74
|
+
{ field_path: 'firm.geography', operator: 'has_any', value: ['US', 'North America'] },
|
|
75
|
+
],
|
|
76
|
+
match_action: 'tag_continue',
|
|
77
|
+
no_match_action: 'exclude',
|
|
78
|
+
match_tags: ['qualified_geography'],
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: 'stage-4',
|
|
82
|
+
order: 3,
|
|
83
|
+
name: 'Industry Filter',
|
|
84
|
+
filter_logic: 'OR',
|
|
85
|
+
rules: [
|
|
86
|
+
{ field_path: 'firm.industries', operator: 'has_any', value: ['SaaS', 'Enterprise'] },
|
|
87
|
+
],
|
|
88
|
+
match_action: 'tag_continue',
|
|
89
|
+
no_match_action: 'exclude',
|
|
90
|
+
match_tags: ['qualified_industry'],
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
id: 'stage-5',
|
|
94
|
+
order: 4,
|
|
95
|
+
name: 'Final Qualification',
|
|
96
|
+
filter_logic: 'AND',
|
|
97
|
+
rules: [
|
|
98
|
+
{ field_path: 'tags', operator: 'has_all', value: ['qualified_stage', 'qualified_check_size', 'qualified_geography'] },
|
|
99
|
+
],
|
|
100
|
+
match_action: 'output',
|
|
101
|
+
no_match_action: 'exclude',
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
created_at: '2024-01-01T00:00:00Z',
|
|
105
|
+
updated_at: '2024-01-15T10:30:00Z',
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
const completedRun: FunnelRun = {
|
|
109
|
+
id: 'run-1',
|
|
110
|
+
funnel_id: 'funnel-1',
|
|
111
|
+
status: 'completed',
|
|
112
|
+
trigger_type: 'manual',
|
|
113
|
+
started_at: '2024-01-15T10:00:00Z',
|
|
114
|
+
completed_at: '2024-01-15T10:05:00Z',
|
|
115
|
+
duration_ms: 300000,
|
|
116
|
+
total_input: 83061,
|
|
117
|
+
total_matched: 235,
|
|
118
|
+
total_excluded: 82826,
|
|
119
|
+
total_tagged: 235,
|
|
120
|
+
stage_stats: {},
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
// Stories
|
|
124
|
+
|
|
125
|
+
export const Active: Story = {
|
|
126
|
+
args: {
|
|
127
|
+
funnel: baseFunnel,
|
|
128
|
+
latestRun: completedRun,
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export const Draft: Story = {
|
|
133
|
+
args: {
|
|
134
|
+
funnel: {
|
|
135
|
+
...baseFunnel,
|
|
136
|
+
status: 'draft',
|
|
137
|
+
name: 'Draft Funnel - In Development',
|
|
138
|
+
description: 'This funnel is still being configured and tested.',
|
|
139
|
+
},
|
|
140
|
+
latestRun: completedRun,
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
export const Paused: Story = {
|
|
145
|
+
args: {
|
|
146
|
+
funnel: {
|
|
147
|
+
...baseFunnel,
|
|
148
|
+
status: 'paused',
|
|
149
|
+
name: 'Paused Funnel - Temporarily Disabled',
|
|
150
|
+
description: 'This funnel has been paused while we update criteria.',
|
|
151
|
+
},
|
|
152
|
+
latestRun: completedRun,
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
export const Archived: Story = {
|
|
157
|
+
args: {
|
|
158
|
+
funnel: {
|
|
159
|
+
...baseFunnel,
|
|
160
|
+
status: 'archived',
|
|
161
|
+
name: 'Archived Funnel - Historical Reference',
|
|
162
|
+
description: 'This funnel is no longer in use but kept for reference.',
|
|
163
|
+
},
|
|
164
|
+
latestRun: completedRun,
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export const NoRunsYet: Story = {
|
|
169
|
+
args: {
|
|
170
|
+
funnel: baseFunnel,
|
|
171
|
+
latestRun: undefined,
|
|
172
|
+
},
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
export const Running: Story = {
|
|
176
|
+
args: {
|
|
177
|
+
funnel: baseFunnel,
|
|
178
|
+
latestRun: {
|
|
179
|
+
...completedRun,
|
|
180
|
+
status: 'running',
|
|
181
|
+
completed_at: undefined,
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
export const Failed: Story = {
|
|
187
|
+
args: {
|
|
188
|
+
funnel: baseFunnel,
|
|
189
|
+
latestRun: {
|
|
190
|
+
...completedRun,
|
|
191
|
+
status: 'failed',
|
|
192
|
+
error: 'Database connection timeout',
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
export const NoStages: Story = {
|
|
198
|
+
args: {
|
|
199
|
+
funnel: {
|
|
200
|
+
...baseFunnel,
|
|
201
|
+
stages: [],
|
|
202
|
+
name: 'Empty Funnel',
|
|
203
|
+
description: 'This funnel has no stages defined yet.',
|
|
204
|
+
},
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
export const OneStage: Story = {
|
|
209
|
+
args: {
|
|
210
|
+
funnel: {
|
|
211
|
+
...baseFunnel,
|
|
212
|
+
stages: [baseFunnel.stages[0]],
|
|
213
|
+
name: 'Single Stage Funnel',
|
|
214
|
+
},
|
|
215
|
+
latestRun: {
|
|
216
|
+
...completedRun,
|
|
217
|
+
total_input: 1000,
|
|
218
|
+
total_matched: 450,
|
|
219
|
+
total_excluded: 550,
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
export const TenStages: Story = {
|
|
225
|
+
args: {
|
|
226
|
+
funnel: {
|
|
227
|
+
...baseFunnel,
|
|
228
|
+
stages: Array.from({ length: 10 }, (_, i) => ({
|
|
229
|
+
id: `stage-${i}`,
|
|
230
|
+
order: i,
|
|
231
|
+
name: `Stage ${i + 1}: Filter ${i + 1}`,
|
|
232
|
+
filter_logic: 'AND' as const,
|
|
233
|
+
rules: [
|
|
234
|
+
{ field_path: `field${i}`, operator: 'eq' as const, value: i },
|
|
235
|
+
],
|
|
236
|
+
match_action: 'continue' as const,
|
|
237
|
+
no_match_action: 'exclude' as const,
|
|
238
|
+
})),
|
|
239
|
+
name: 'Complex Multi-Stage Funnel',
|
|
240
|
+
description: 'Demonstrates card with many stages.',
|
|
241
|
+
},
|
|
242
|
+
latestRun: completedRun,
|
|
243
|
+
},
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
export const HighMatchRate: Story = {
|
|
247
|
+
args: {
|
|
248
|
+
funnel: baseFunnel,
|
|
249
|
+
latestRun: {
|
|
250
|
+
...completedRun,
|
|
251
|
+
total_input: 1000,
|
|
252
|
+
total_matched: 950,
|
|
253
|
+
total_excluded: 50,
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
export const LowMatchRate: Story = {
|
|
259
|
+
args: {
|
|
260
|
+
funnel: baseFunnel,
|
|
261
|
+
latestRun: {
|
|
262
|
+
...completedRun,
|
|
263
|
+
total_input: 100000,
|
|
264
|
+
total_matched: 12,
|
|
265
|
+
total_excluded: 99988,
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
export const ZeroMatches: Story = {
|
|
271
|
+
args: {
|
|
272
|
+
funnel: baseFunnel,
|
|
273
|
+
latestRun: {
|
|
274
|
+
...completedRun,
|
|
275
|
+
total_matched: 0,
|
|
276
|
+
total_excluded: 83061,
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
export const NoDescription: Story = {
|
|
282
|
+
args: {
|
|
283
|
+
funnel: {
|
|
284
|
+
...baseFunnel,
|
|
285
|
+
description: undefined,
|
|
286
|
+
},
|
|
287
|
+
latestRun: completedRun,
|
|
288
|
+
},
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
export const LongName: Story = {
|
|
292
|
+
args: {
|
|
293
|
+
funnel: {
|
|
294
|
+
...baseFunnel,
|
|
295
|
+
name: 'This is an extremely long funnel name that demonstrates how the card handles text overflow and wrapping in the header section',
|
|
296
|
+
},
|
|
297
|
+
latestRun: completedRun,
|
|
298
|
+
},
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
export const LongDescription: Story = {
|
|
302
|
+
args: {
|
|
303
|
+
funnel: {
|
|
304
|
+
...baseFunnel,
|
|
305
|
+
description: 'This is a very long description that explains in great detail what this funnel does, how it works, why it matters, and all the edge cases it handles. It should demonstrate how the card truncates long descriptions to maintain a clean layout. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.',
|
|
306
|
+
},
|
|
307
|
+
latestRun: completedRun,
|
|
308
|
+
},
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
// Domain-specific examples showing BRUTALLY GENERIC nature
|
|
312
|
+
|
|
313
|
+
export const RecipeFunnel: Story = {
|
|
314
|
+
args: {
|
|
315
|
+
funnel: {
|
|
316
|
+
id: 'recipe-funnel-1',
|
|
317
|
+
name: 'Quick Easy Dinner Recommendations',
|
|
318
|
+
description: 'Filters recipes for vegetarian, gluten-free, quick prep, easy difficulty.',
|
|
319
|
+
status: 'active',
|
|
320
|
+
input_type: 'any',
|
|
321
|
+
stages: [
|
|
322
|
+
{
|
|
323
|
+
id: 'stage-1',
|
|
324
|
+
order: 0,
|
|
325
|
+
name: 'Dietary Restrictions',
|
|
326
|
+
filter_logic: 'AND',
|
|
327
|
+
rules: [
|
|
328
|
+
{ field_path: 'dietary_restrictions', operator: 'has_all', value: ['vegetarian', 'gluten-free'] },
|
|
329
|
+
],
|
|
330
|
+
match_action: 'tag_continue',
|
|
331
|
+
no_match_action: 'exclude',
|
|
332
|
+
match_tags: ['meets_dietary_needs'],
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
id: 'stage-2',
|
|
336
|
+
order: 1,
|
|
337
|
+
name: 'Time Constraint',
|
|
338
|
+
filter_logic: 'AND',
|
|
339
|
+
rules: [
|
|
340
|
+
{ field_path: 'prep_time_minutes', operator: 'lte', value: 30 },
|
|
341
|
+
],
|
|
342
|
+
match_action: 'tag_continue',
|
|
343
|
+
no_match_action: 'exclude',
|
|
344
|
+
match_tags: ['quick_prep'],
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
id: 'stage-3',
|
|
348
|
+
order: 2,
|
|
349
|
+
name: 'Difficulty Level',
|
|
350
|
+
filter_logic: 'OR',
|
|
351
|
+
rules: [
|
|
352
|
+
{ field_path: 'difficulty', operator: 'in', value: ['easy', 'medium'] },
|
|
353
|
+
],
|
|
354
|
+
match_action: 'output',
|
|
355
|
+
no_match_action: 'exclude',
|
|
356
|
+
},
|
|
357
|
+
],
|
|
358
|
+
created_at: '2024-01-01T00:00:00Z',
|
|
359
|
+
updated_at: '2024-01-15T10:30:00Z',
|
|
360
|
+
},
|
|
361
|
+
latestRun: {
|
|
362
|
+
...completedRun,
|
|
363
|
+
total_input: 5420,
|
|
364
|
+
total_matched: 87,
|
|
365
|
+
total_excluded: 5333,
|
|
366
|
+
},
|
|
367
|
+
},
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
export const LeadScoringFunnel: Story = {
|
|
371
|
+
args: {
|
|
372
|
+
funnel: {
|
|
373
|
+
id: 'lead-funnel-1',
|
|
374
|
+
name: 'Enterprise Lead Scoring',
|
|
375
|
+
description: 'Scores and qualifies enterprise leads based on company size, engagement, and fit.',
|
|
376
|
+
status: 'active',
|
|
377
|
+
input_type: 'any',
|
|
378
|
+
stages: [
|
|
379
|
+
{
|
|
380
|
+
id: 'stage-1',
|
|
381
|
+
order: 0,
|
|
382
|
+
name: 'Company Size',
|
|
383
|
+
filter_logic: 'AND',
|
|
384
|
+
rules: [
|
|
385
|
+
{ field_path: 'company.employee_count', operator: 'gte', value: 100 },
|
|
386
|
+
],
|
|
387
|
+
match_action: 'tag_continue',
|
|
388
|
+
no_match_action: 'tag_continue',
|
|
389
|
+
match_tags: ['enterprise_size'],
|
|
390
|
+
no_match_tags: ['smb_size'],
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
id: 'stage-2',
|
|
394
|
+
order: 1,
|
|
395
|
+
name: 'Engagement Score',
|
|
396
|
+
filter_logic: 'OR',
|
|
397
|
+
rules: [
|
|
398
|
+
{ field_path: 'engagement.email_opens', operator: 'gte', value: 5 },
|
|
399
|
+
{ field_path: 'engagement.demo_requested', operator: 'is_true', value: null },
|
|
400
|
+
],
|
|
401
|
+
match_action: 'tag_continue',
|
|
402
|
+
no_match_action: 'tag_continue',
|
|
403
|
+
match_tags: ['engaged'],
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
id: 'stage-3',
|
|
407
|
+
order: 2,
|
|
408
|
+
name: 'Final Qualification',
|
|
409
|
+
filter_logic: 'AND',
|
|
410
|
+
rules: [
|
|
411
|
+
{ field_path: 'tags', operator: 'has_all', value: ['enterprise_size', 'engaged'] },
|
|
412
|
+
],
|
|
413
|
+
match_action: 'output',
|
|
414
|
+
no_match_action: 'continue',
|
|
415
|
+
match_tags: ['hot_lead'],
|
|
416
|
+
},
|
|
417
|
+
],
|
|
418
|
+
created_at: '2024-01-01T00:00:00Z',
|
|
419
|
+
updated_at: '2024-01-15T10:30:00Z',
|
|
420
|
+
},
|
|
421
|
+
latestRun: {
|
|
422
|
+
...completedRun,
|
|
423
|
+
total_input: 12500,
|
|
424
|
+
total_matched: 342,
|
|
425
|
+
total_excluded: 12158,
|
|
426
|
+
},
|
|
427
|
+
},
|
|
428
|
+
};
|
|
429
|
+
|
|
430
|
+
export const GitHubIssueFunnel: Story = {
|
|
431
|
+
args: {
|
|
432
|
+
funnel: {
|
|
433
|
+
id: 'github-funnel-1',
|
|
434
|
+
name: 'GitHub Issue Priority Triage',
|
|
435
|
+
description: 'Filters GitHub issues to identify high-priority items requiring immediate attention.',
|
|
436
|
+
status: 'active',
|
|
437
|
+
input_type: 'any',
|
|
438
|
+
stages: [
|
|
439
|
+
{
|
|
440
|
+
id: 'stage-1',
|
|
441
|
+
order: 0,
|
|
442
|
+
name: 'Filter PRs',
|
|
443
|
+
filter_logic: 'AND',
|
|
444
|
+
rules: [
|
|
445
|
+
{ field_path: 'is_pull_request', operator: 'is_false', value: null },
|
|
446
|
+
],
|
|
447
|
+
match_action: 'continue',
|
|
448
|
+
no_match_action: 'exclude',
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
id: 'stage-2',
|
|
452
|
+
order: 1,
|
|
453
|
+
name: 'Priority Labels',
|
|
454
|
+
filter_logic: 'OR',
|
|
455
|
+
rules: [
|
|
456
|
+
{ field_path: 'labels', operator: 'has_any', value: ['bug', 'security'] },
|
|
457
|
+
],
|
|
458
|
+
match_action: 'tag_continue',
|
|
459
|
+
no_match_action: 'continue',
|
|
460
|
+
match_tags: ['high_priority'],
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
id: 'stage-3',
|
|
464
|
+
order: 2,
|
|
465
|
+
name: 'Community Interest',
|
|
466
|
+
filter_logic: 'AND',
|
|
467
|
+
rules: [
|
|
468
|
+
{ field_path: 'comments_count', operator: 'gte', value: 5 },
|
|
469
|
+
],
|
|
470
|
+
match_action: 'output',
|
|
471
|
+
no_match_action: 'output',
|
|
472
|
+
},
|
|
473
|
+
],
|
|
474
|
+
created_at: '2024-01-01T00:00:00Z',
|
|
475
|
+
updated_at: '2024-01-15T10:30:00Z',
|
|
476
|
+
},
|
|
477
|
+
latestRun: {
|
|
478
|
+
...completedRun,
|
|
479
|
+
total_input: 1847,
|
|
480
|
+
total_matched: 92,
|
|
481
|
+
total_excluded: 1755,
|
|
482
|
+
},
|
|
483
|
+
},
|
|
484
|
+
};
|