@inspirer-dev/crm-dashboard 1.0.34 → 1.0.37
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/admin/src/components/StepFlowBuilder/index.tsx +73 -87
- package/admin/src/components/TriggerConfigField/index.tsx +157 -96
- package/dist/_chunks/{index-BcyafsrQ.js → index-Cj7L2FNg.js} +215 -145
- package/dist/_chunks/{index-C8xU0WGn.mjs → index-CrIUBH7C.mjs} +239 -174
- package/dist/_chunks/{index-JQqs7NM9.js → index-DGIbwLd4.js} +238 -173
- package/dist/_chunks/{index-CJFZspLC.mjs → index-DkY191XW.mjs} +62 -69
- package/dist/_chunks/{index-DHbvzPYf.js → index-DphnHWJg.js} +60 -67
- package/dist/admin/index.js +3 -3
- package/dist/admin/index.mjs +2 -2
- package/package.json +1 -1
|
@@ -2,129 +2,115 @@ import React, { forwardRef, useCallback, useEffect, useMemo, useState, useRef }
|
|
|
2
2
|
import { ReactFlowProvider } from 'reactflow';
|
|
3
3
|
import 'reactflow/dist/style.css';
|
|
4
4
|
import { Box, Field, Flex, Typography, Badge } from '@strapi/design-system';
|
|
5
|
-
import { useForm } from '@strapi/strapi/admin';
|
|
5
|
+
import { useForm, unstable_useContentManagerContext as useContentManagerContext } from '@strapi/strapi/admin';
|
|
6
6
|
|
|
7
7
|
import type { StepFlowBuilderProps, FlowStep, CampaignContext, EntrySegment } from './types';
|
|
8
8
|
import { parseValue } from './utils';
|
|
9
9
|
import { FlowCanvas } from './flow-canvas';
|
|
10
10
|
|
|
11
11
|
type SegmentItem = { id?: number; documentId?: string; name?: string };
|
|
12
|
-
|
|
13
|
-
type RawSegmentValue =
|
|
14
|
-
| number
|
|
15
|
-
| SegmentItem
|
|
16
|
-
| SegmentItem[]
|
|
17
|
-
| { connect?: SegmentItem[]; disconnect?: SegmentItem[] }
|
|
18
|
-
| null
|
|
19
|
-
| undefined;
|
|
20
|
-
|
|
21
|
-
const extractSegmentFromValue = (value: RawSegmentValue): SegmentItem | null => {
|
|
22
|
-
if (!value) return null;
|
|
23
|
-
if (typeof value === 'number') return { id: value };
|
|
24
|
-
if (Array.isArray(value)) {
|
|
25
|
-
return value.length > 0 ? value[0] : null;
|
|
26
|
-
}
|
|
27
|
-
if (typeof value === 'object') {
|
|
28
|
-
if ('connect' in value && Array.isArray(value.connect) && value.connect.length > 0) {
|
|
29
|
-
return value.connect[0];
|
|
30
|
-
}
|
|
31
|
-
if ('id' in value && value.id) {
|
|
32
|
-
return value as SegmentItem;
|
|
33
|
-
}
|
|
34
|
-
if ('documentId' in value && value.documentId) {
|
|
35
|
-
return value as SegmentItem;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return null;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const extractSegmentId = (value: RawSegmentValue): number | null => {
|
|
42
|
-
const segment = extractSegmentFromValue(value);
|
|
43
|
-
return segment?.id ?? null;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const extractSegmentName = (value: RawSegmentValue): string | null => {
|
|
47
|
-
const segment = extractSegmentFromValue(value);
|
|
48
|
-
return segment?.name ?? null;
|
|
49
|
-
};
|
|
12
|
+
type ConnectDisconnect = { connect?: SegmentItem[]; disconnect?: SegmentItem[] };
|
|
50
13
|
|
|
51
14
|
const StepFlowBuilderInner = forwardRef<HTMLDivElement, StepFlowBuilderProps>(
|
|
52
15
|
({ name, value, onChange, intlLabel, disabled, error, required, hint }, ref) => {
|
|
53
16
|
const [steps, setSteps] = useState<FlowStep[]>([]);
|
|
54
|
-
const [
|
|
17
|
+
const [initialSegment, setInitialSegment] = useState<EntrySegment | null>(null);
|
|
18
|
+
const [hasFetched, setHasFetched] = useState(false);
|
|
55
19
|
const isInitialMount = useRef(true);
|
|
56
20
|
const syncTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
|
57
21
|
|
|
58
22
|
const form = useForm('StepFlowBuilder', (state) => state);
|
|
59
23
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
const currentSegment = extractSegmentFromValue(currentValue);
|
|
71
|
-
if (currentSegment) {
|
|
72
|
-
return currentValue;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return initialValue;
|
|
76
|
-
}, [form?.values, form?.initialValues]);
|
|
24
|
+
let documentId: string | undefined;
|
|
25
|
+
let model: string | undefined;
|
|
26
|
+
try {
|
|
27
|
+
const ctx = useContentManagerContext();
|
|
28
|
+
documentId = ctx?.id;
|
|
29
|
+
model = ctx?.model;
|
|
30
|
+
console.log('[StepFlowBuilder] ContentManagerContext:', { documentId, model });
|
|
31
|
+
} catch (err) {
|
|
32
|
+
console.log('[StepFlowBuilder] No ContentManagerContext (test page?)');
|
|
33
|
+
}
|
|
77
34
|
|
|
78
35
|
useEffect(() => {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
console.log('[StepFlowBuilder] rawEntrySegment:', rawEntrySegment);
|
|
84
|
-
console.log('[StepFlowBuilder] segmentId:', segmentId, 'segmentName:', segmentName);
|
|
85
|
-
|
|
86
|
-
if (!segmentId) {
|
|
87
|
-
setPopulatedSegment(null);
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (segmentName) {
|
|
92
|
-
setPopulatedSegment({ id: segmentId, name: segmentName });
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
36
|
+
if (!documentId || !model || hasFetched) {
|
|
37
|
+
console.log('[StepFlowBuilder] Skip fetch:', { documentId, model, hasFetched });
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
95
40
|
|
|
41
|
+
const fetchCampaignData = async () => {
|
|
42
|
+
console.log('[StepFlowBuilder] Fetching campaign data...');
|
|
96
43
|
try {
|
|
97
44
|
const { useFetchClient } = await import('@strapi/strapi/admin');
|
|
98
45
|
const { get } = useFetchClient();
|
|
99
46
|
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
47
|
+
const url = `/content-manager/collection-types/${model}/${documentId}`;
|
|
48
|
+
console.log('[StepFlowBuilder] Fetch URL:', url);
|
|
49
|
+
|
|
50
|
+
const response = await get(url, { params: { populate: 'entrySegment' } });
|
|
51
|
+
console.log('[StepFlowBuilder] Campaign response:', response);
|
|
52
|
+
|
|
53
|
+
const data = response?.data as { entrySegment?: { id: number; name: string } } | undefined;
|
|
54
|
+
if (data?.entrySegment?.id) {
|
|
55
|
+
const seg = {
|
|
56
|
+
id: data.entrySegment.id,
|
|
57
|
+
name: data.entrySegment.name || `Segment #${data.entrySegment.id}`,
|
|
58
|
+
};
|
|
59
|
+
console.log('[StepFlowBuilder] Initial segment from API:', seg);
|
|
60
|
+
setInitialSegment(seg);
|
|
107
61
|
} else {
|
|
108
|
-
|
|
62
|
+
console.log('[StepFlowBuilder] No entrySegment in response');
|
|
109
63
|
}
|
|
110
64
|
} catch (err) {
|
|
111
|
-
console.
|
|
112
|
-
|
|
65
|
+
console.error('[StepFlowBuilder] Fetch error:', err);
|
|
66
|
+
} finally {
|
|
67
|
+
setHasFetched(true);
|
|
113
68
|
}
|
|
114
69
|
};
|
|
115
70
|
|
|
116
|
-
|
|
117
|
-
}, [
|
|
71
|
+
fetchCampaignData();
|
|
72
|
+
}, [documentId, model, hasFetched]);
|
|
73
|
+
|
|
74
|
+
const currentSegment = useMemo<EntrySegment | null>(() => {
|
|
75
|
+
const values = form?.values as Record<string, unknown> | undefined;
|
|
76
|
+
const entrySegmentValue = values?.entrySegment as ConnectDisconnect | undefined;
|
|
77
|
+
|
|
78
|
+
console.log('[StepFlowBuilder] form.values.entrySegment:', entrySegmentValue);
|
|
79
|
+
|
|
80
|
+
if (!entrySegmentValue) {
|
|
81
|
+
return initialSegment;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const { connect = [], disconnect = [] } = entrySegmentValue;
|
|
85
|
+
|
|
86
|
+
if (connect.length > 0) {
|
|
87
|
+
const seg = connect[0];
|
|
88
|
+
console.log('[StepFlowBuilder] Using connect segment:', seg);
|
|
89
|
+
return { id: seg.id!, name: seg.name || `Segment #${seg.id}` };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (disconnect.length > 0 && initialSegment) {
|
|
93
|
+
const disconnectedId = disconnect[0]?.id;
|
|
94
|
+
if (disconnectedId === initialSegment.id) {
|
|
95
|
+
console.log('[StepFlowBuilder] Segment disconnected');
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return initialSegment;
|
|
101
|
+
}, [form?.values, initialSegment]);
|
|
118
102
|
|
|
119
103
|
const campaignContext = useMemo<CampaignContext>(() => {
|
|
120
104
|
const values = form?.values as Record<string, unknown> | undefined;
|
|
121
105
|
if (!values) return {};
|
|
122
106
|
|
|
107
|
+
console.log('[StepFlowBuilder] Final segment for context:', currentSegment);
|
|
108
|
+
|
|
123
109
|
return {
|
|
124
110
|
triggerConfig: values.triggerConfig as CampaignContext['triggerConfig'],
|
|
125
|
-
entrySegment:
|
|
111
|
+
entrySegment: currentSegment,
|
|
126
112
|
};
|
|
127
|
-
}, [form?.values,
|
|
113
|
+
}, [form?.values, currentSegment]);
|
|
128
114
|
|
|
129
115
|
useEffect(() => {
|
|
130
116
|
const parsed = parseValue(value);
|
|
@@ -11,14 +11,12 @@ import {
|
|
|
11
11
|
ComboboxOption,
|
|
12
12
|
Badge,
|
|
13
13
|
} from '@strapi/design-system';
|
|
14
|
-
import {
|
|
14
|
+
import { Magic, Clock, Calendar, Code } from '@strapi/icons';
|
|
15
15
|
import { useTheme } from 'styled-components';
|
|
16
16
|
|
|
17
17
|
const ANALYTICS_EVENTS: Record<string, { value: string; label: string }[]> = {
|
|
18
|
-
'CRM (Backend)': [
|
|
19
|
-
|
|
20
|
-
],
|
|
21
|
-
'Case': [
|
|
18
|
+
'CRM (Backend)': [{ value: 'user_registered', label: 'User Registered' }],
|
|
19
|
+
Case: [
|
|
22
20
|
{ value: 'gg-case-fav', label: 'Case Favorite' },
|
|
23
21
|
{ value: 'gg-case-fav-rem', label: 'Case Favorite Remove' },
|
|
24
22
|
{ value: 'gg-case-open', label: 'Case Open' },
|
|
@@ -33,7 +31,7 @@ const ANALYTICS_EVENTS: Record<string, { value: string; label: string }[]> = {
|
|
|
33
31
|
{ value: 'gg-case-free-more', label: 'Case Free More' },
|
|
34
32
|
{ value: 'gg-case-welcome-open', label: 'Case Welcome Open' },
|
|
35
33
|
],
|
|
36
|
-
|
|
34
|
+
Header: [
|
|
37
35
|
{ value: 'gg-header-notify', label: 'Header Notify' },
|
|
38
36
|
{ value: 'gg-header-notify-all', label: 'Header Notify All' },
|
|
39
37
|
{ value: 'gg-header-page-dp', label: 'Header Page DP' },
|
|
@@ -55,7 +53,7 @@ const ANALYTICS_EVENTS: Record<string, { value: string; label: string }[]> = {
|
|
|
55
53
|
{ value: 'gg-genui-click2reg-15sec-popup-close-button-click', label: 'Click2Reg Popup Close' },
|
|
56
54
|
{ value: 'gg-genui-showed-popup-1500dp', label: 'Showed Popup 1500DP' },
|
|
57
55
|
],
|
|
58
|
-
|
|
56
|
+
Deposit: [
|
|
59
57
|
{ value: 'gg-depositbait-banner-herodepbonus-click', label: 'Hero Deposit Bonus Banner' },
|
|
60
58
|
{ value: 'gg-depositbait-banner-major-home-banner-c', label: 'Major Home Banner' },
|
|
61
59
|
{ value: 'gg-deposit-deppage-refill', label: 'Deposit Page Refill' },
|
|
@@ -66,14 +64,14 @@ const ANALYTICS_EVENTS: Record<string, { value: string; label: string }[]> = {
|
|
|
66
64
|
{ value: 'gg-deposit-suggestion-selected', label: 'Deposit Suggestion Selected' },
|
|
67
65
|
{ value: 'gg-deposit-black-friday-banner-deposit-click', label: 'Black Friday Banner Deposit' },
|
|
68
66
|
],
|
|
69
|
-
|
|
67
|
+
Battle: [
|
|
70
68
|
{ value: 'gg-battle-create', label: 'Battle Create' },
|
|
71
69
|
{ value: 'gg-battle-cancel', label: 'Battle Cancel' },
|
|
72
70
|
{ value: 'gg-battle-skin-sell', label: 'Battle Skin Sell' },
|
|
73
71
|
{ value: 'gg-battle-skin-sell-all', label: 'Battle Skin Sell All' },
|
|
74
72
|
{ value: 'gg-battle-retry', label: 'Battle Retry' },
|
|
75
73
|
],
|
|
76
|
-
|
|
74
|
+
Profile: [
|
|
77
75
|
{ value: 'gg-profile-logout', label: 'Profile Logout' },
|
|
78
76
|
{ value: 'gg-profile-skin-sell-all', label: 'Profile Skin Sell All' },
|
|
79
77
|
{ value: 'gg-profile-skin-sell', label: 'Profile Skin Sell' },
|
|
@@ -83,11 +81,11 @@ const ANALYTICS_EVENTS: Record<string, { value: string; label: string }[]> = {
|
|
|
83
81
|
{ value: 'gg-profile-skin-trade-replace-yes', label: 'Profile Skin Trade Replace Yes' },
|
|
84
82
|
{ value: 'gg-profile-skin-trade-replace-no', label: 'Profile Skin Trade Replace No' },
|
|
85
83
|
],
|
|
86
|
-
|
|
84
|
+
Upgrade: [
|
|
87
85
|
{ value: 'gg-upgrade-launch', label: 'Upgrade Launch' },
|
|
88
86
|
{ value: 'gg-upgrade-retry', label: 'Upgrade Retry' },
|
|
89
87
|
],
|
|
90
|
-
|
|
88
|
+
Contract: [
|
|
91
89
|
{ value: 'gg-contract-create', label: 'Contract Create' },
|
|
92
90
|
{ value: 'gg-contract-retry', label: 'Contract Retry' },
|
|
93
91
|
{ value: 'gg-contract-skin-sell', label: 'Contract Skin Sell' },
|
|
@@ -100,9 +98,7 @@ const ANALYTICS_EVENTS: Record<string, { value: string; label: string }[]> = {
|
|
|
100
98
|
{ value: 'gg-dp-ref-copy', label: 'DP Ref Copy' },
|
|
101
99
|
{ value: 'gg-dp-ref-stat', label: 'DP Ref Stat' },
|
|
102
100
|
],
|
|
103
|
-
|
|
104
|
-
{ value: 'gg-widget', label: 'Widget' },
|
|
105
|
-
],
|
|
101
|
+
Widget: [{ value: 'gg-widget', label: 'Widget' }],
|
|
106
102
|
};
|
|
107
103
|
|
|
108
104
|
interface TriggerConfig {
|
|
@@ -189,50 +185,53 @@ const useThemeColors = () => {
|
|
|
189
185
|
const theme = useTheme() as StrapiTheme;
|
|
190
186
|
const isDark = theme?.colors?.neutral0 === '#212134';
|
|
191
187
|
|
|
192
|
-
return useMemo(
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
188
|
+
return useMemo(
|
|
189
|
+
() => ({
|
|
190
|
+
isDark,
|
|
191
|
+
card: {
|
|
192
|
+
inactive: isDark ? '#1a1a2e' : '#fafafa',
|
|
193
|
+
inactiveBorder: isDark ? '#32324d' : '#eaeaef',
|
|
194
|
+
iconInactive: isDark ? '#4a4a6a' : '#e4e4e7',
|
|
195
|
+
iconInactiveColor: isDark ? '#a5a5ba' : '#71717a',
|
|
196
|
+
},
|
|
197
|
+
event: {
|
|
198
|
+
gradient: isDark
|
|
199
|
+
? 'linear-gradient(135deg, #2d1f4e 0%, #1f1635 100%)'
|
|
200
|
+
: 'linear-gradient(135deg, #f5f3ff 0%, #ede9fe 100%)',
|
|
201
|
+
gradientActive: isDark
|
|
202
|
+
? 'linear-gradient(135deg, #3d2a6e 0%, #2d1f4e 100%)'
|
|
203
|
+
: 'linear-gradient(135deg, #f5f3ff 0%, #ede9fe 100%)',
|
|
204
|
+
border: isDark ? '#6d28d9' : '#e9d5ff',
|
|
205
|
+
sectionBg: isDark
|
|
206
|
+
? 'linear-gradient(135deg, #1f1635 0%, #1a1a2e 100%)'
|
|
207
|
+
: 'linear-gradient(135deg, #faf5ff 0%, #f5f3ff 100%)',
|
|
208
|
+
innerCard: isDark ? '#1a1a2e' : '#ffffff',
|
|
209
|
+
color: '#8b5cf6',
|
|
210
|
+
},
|
|
211
|
+
schedule: {
|
|
212
|
+
gradient: isDark
|
|
213
|
+
? 'linear-gradient(135deg, #0c2d4a 0%, #0a1929 100%)'
|
|
214
|
+
: 'linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%)',
|
|
215
|
+
gradientActive: isDark
|
|
216
|
+
? 'linear-gradient(135deg, #0e3a5c 0%, #0c2d4a 100%)'
|
|
217
|
+
: 'linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%)',
|
|
218
|
+
border: isDark ? '#0284c7' : '#bae6fd',
|
|
219
|
+
sectionBg: isDark
|
|
220
|
+
? 'linear-gradient(135deg, #0a1929 0%, #1a1a2e 100%)'
|
|
221
|
+
: 'linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%)',
|
|
222
|
+
innerCard: isDark ? '#1a1a2e' : '#ffffff',
|
|
223
|
+
pillInactive: isDark ? '#1a1a2e' : '#ffffff',
|
|
224
|
+
color: '#0ea5e9',
|
|
225
|
+
},
|
|
226
|
+
weekday: {
|
|
227
|
+
inactive: isDark ? '#1a1a2e' : '#f8fafc',
|
|
228
|
+
inactiveBorder: isDark ? '#32324d' : '#e2e8f0',
|
|
229
|
+
weekend: isDark ? '#2d1f1f' : '#fef2f2',
|
|
230
|
+
weekendBorder: isDark ? '#7f1d1d' : '#fecaca',
|
|
231
|
+
},
|
|
232
|
+
}),
|
|
233
|
+
[isDark]
|
|
234
|
+
);
|
|
236
235
|
};
|
|
237
236
|
|
|
238
237
|
interface TriggerTypeCardProps {
|
|
@@ -279,7 +278,13 @@ const TriggerTypeCard: React.FC<TriggerTypeCardProps> = ({
|
|
|
279
278
|
}}
|
|
280
279
|
onClick={() => !disabled && onClick()}
|
|
281
280
|
>
|
|
282
|
-
<Flex
|
|
281
|
+
<Flex
|
|
282
|
+
direction="column"
|
|
283
|
+
alignItems="center"
|
|
284
|
+
justifyContent="center"
|
|
285
|
+
gap={2}
|
|
286
|
+
style={{ height: '100%' }}
|
|
287
|
+
>
|
|
283
288
|
<Flex
|
|
284
289
|
alignItems="center"
|
|
285
290
|
justifyContent="center"
|
|
@@ -303,11 +308,7 @@ const TriggerTypeCard: React.FC<TriggerTypeCardProps> = ({
|
|
|
303
308
|
>
|
|
304
309
|
{title}
|
|
305
310
|
</Typography>
|
|
306
|
-
<Typography
|
|
307
|
-
variant="pi"
|
|
308
|
-
textColor="neutral500"
|
|
309
|
-
style={{ textAlign: 'center' }}
|
|
310
|
-
>
|
|
311
|
+
<Typography variant="pi" textColor="neutral500" style={{ textAlign: 'center' }}>
|
|
311
312
|
{description}
|
|
312
313
|
</Typography>
|
|
313
314
|
</Flex>
|
|
@@ -374,17 +375,22 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
|
|
|
374
375
|
|
|
375
376
|
const getScheduleTypeIcon = () => {
|
|
376
377
|
switch (config.scheduleType) {
|
|
377
|
-
case 'interval':
|
|
378
|
-
|
|
379
|
-
case '
|
|
380
|
-
|
|
381
|
-
|
|
378
|
+
case 'interval':
|
|
379
|
+
return <Clock width={16} height={16} />;
|
|
380
|
+
case 'daily':
|
|
381
|
+
return <Clock width={16} height={16} />;
|
|
382
|
+
case 'weekly':
|
|
383
|
+
return <Calendar width={16} height={16} />;
|
|
384
|
+
case 'cron':
|
|
385
|
+
return <Code width={16} height={16} />;
|
|
386
|
+
default:
|
|
387
|
+
return <Clock width={16} height={16} />;
|
|
382
388
|
}
|
|
383
389
|
};
|
|
384
390
|
|
|
385
391
|
return (
|
|
386
392
|
<Field.Root name={name} error={error} required={required} hint={hint} ref={ref}>
|
|
387
|
-
<Flex direction="column" gap={4}>
|
|
393
|
+
<Flex direction="column" gap={4} alignItems="normal">
|
|
388
394
|
<Field.Label>{intlLabel?.defaultMessage || 'Trigger Configuration'}</Field.Label>
|
|
389
395
|
|
|
390
396
|
<Flex gap={3}>
|
|
@@ -392,7 +398,7 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
|
|
|
392
398
|
active={isEventBased}
|
|
393
399
|
onClick={() => handleUpdate({ type: 'event_based' })}
|
|
394
400
|
disabled={disabled}
|
|
395
|
-
icon={<
|
|
401
|
+
icon={<Magic width={24} height={24} />}
|
|
396
402
|
title="Event-Based"
|
|
397
403
|
description="Triggers on user action"
|
|
398
404
|
color={colors.event.color}
|
|
@@ -425,17 +431,23 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
|
|
|
425
431
|
style={{
|
|
426
432
|
background: colors.event.sectionBg,
|
|
427
433
|
border: `1px solid ${colors.event.border}`,
|
|
434
|
+
width: '100%',
|
|
428
435
|
}}
|
|
429
436
|
>
|
|
430
437
|
<SectionHeader
|
|
431
|
-
icon={<
|
|
438
|
+
icon={<Magic width={18} height={18} />}
|
|
432
439
|
title="Event Configuration"
|
|
433
440
|
color={colors.event.color}
|
|
434
441
|
/>
|
|
435
442
|
|
|
436
|
-
<Flex direction="column" gap={4}>
|
|
443
|
+
<Flex direction="column" gap={4} alignItems="normal">
|
|
437
444
|
<Box>
|
|
438
|
-
<Typography
|
|
445
|
+
<Typography
|
|
446
|
+
variant="pi"
|
|
447
|
+
fontWeight="bold"
|
|
448
|
+
textColor="neutral700"
|
|
449
|
+
style={{ marginBottom: 8, display: 'block' }}
|
|
450
|
+
>
|
|
439
451
|
Trigger Event
|
|
440
452
|
</Typography>
|
|
441
453
|
<Combobox
|
|
@@ -464,7 +476,11 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
|
|
|
464
476
|
))
|
|
465
477
|
)}
|
|
466
478
|
</Combobox>
|
|
467
|
-
<Typography
|
|
479
|
+
<Typography
|
|
480
|
+
variant="pi"
|
|
481
|
+
textColor="neutral500"
|
|
482
|
+
style={{ marginTop: 6, display: 'block' }}
|
|
483
|
+
>
|
|
468
484
|
Select from predefined events or enter a custom event name
|
|
469
485
|
</Typography>
|
|
470
486
|
</Box>
|
|
@@ -494,7 +510,12 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
|
|
|
494
510
|
<Clock width={20} height={20} />
|
|
495
511
|
</Box>
|
|
496
512
|
<Box style={{ flex: 1 }}>
|
|
497
|
-
<Typography
|
|
513
|
+
<Typography
|
|
514
|
+
variant="pi"
|
|
515
|
+
fontWeight="bold"
|
|
516
|
+
textColor="neutral700"
|
|
517
|
+
style={{ marginBottom: 4, display: 'block' }}
|
|
518
|
+
>
|
|
498
519
|
Delay Before Sending
|
|
499
520
|
</Typography>
|
|
500
521
|
<Typography variant="pi" textColor="neutral500">
|
|
@@ -541,6 +562,7 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
|
|
|
541
562
|
style={{
|
|
542
563
|
background: colors.schedule.sectionBg,
|
|
543
564
|
border: `1px solid ${colors.schedule.border}`,
|
|
565
|
+
width: '100%',
|
|
544
566
|
}}
|
|
545
567
|
>
|
|
546
568
|
<SectionHeader
|
|
@@ -549,10 +571,14 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
|
|
|
549
571
|
color={colors.schedule.color}
|
|
550
572
|
/>
|
|
551
573
|
|
|
552
|
-
<Flex direction="column" gap={4}>
|
|
574
|
+
<Flex direction="column" gap={4} alignItems="normal">
|
|
553
575
|
<Flex gap={2}>
|
|
554
576
|
{[
|
|
555
|
-
{
|
|
577
|
+
{
|
|
578
|
+
value: 'interval',
|
|
579
|
+
label: 'Interval',
|
|
580
|
+
icon: <Clock width={14} height={14} />,
|
|
581
|
+
},
|
|
556
582
|
{ value: 'daily', label: 'Daily', icon: <Clock width={14} height={14} /> },
|
|
557
583
|
{ value: 'weekly', label: 'Weekly', icon: <Calendar width={14} height={14} /> },
|
|
558
584
|
{ value: 'cron', label: 'Cron', icon: <Code width={14} height={14} /> },
|
|
@@ -563,19 +589,29 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
|
|
|
563
589
|
hasRadius
|
|
564
590
|
style={{
|
|
565
591
|
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
566
|
-
background:
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
592
|
+
background:
|
|
593
|
+
config.scheduleType === type.value
|
|
594
|
+
? `linear-gradient(135deg, ${colors.schedule.color} 0%, #0284c7 100%)`
|
|
595
|
+
: colors.schedule.pillInactive,
|
|
596
|
+
border:
|
|
597
|
+
config.scheduleType === type.value
|
|
598
|
+
? `1px solid ${colors.schedule.color}`
|
|
599
|
+
: `1px solid ${colors.schedule.border}`,
|
|
572
600
|
flex: 1,
|
|
573
601
|
transition: 'all 0.15s ease',
|
|
574
602
|
}}
|
|
575
|
-
onClick={() =>
|
|
603
|
+
onClick={() =>
|
|
604
|
+
!disabled &&
|
|
605
|
+
handleUpdate({ scheduleType: type.value as TriggerConfig['scheduleType'] })
|
|
606
|
+
}
|
|
576
607
|
>
|
|
577
608
|
<Flex direction="column" alignItems="center" gap={1}>
|
|
578
|
-
<Box
|
|
609
|
+
<Box
|
|
610
|
+
style={{
|
|
611
|
+
color:
|
|
612
|
+
config.scheduleType === type.value ? '#fff' : colors.schedule.color,
|
|
613
|
+
}}
|
|
614
|
+
>
|
|
579
615
|
{type.icon}
|
|
580
616
|
</Box>
|
|
581
617
|
<Typography
|
|
@@ -598,7 +634,11 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
|
|
|
598
634
|
border: `1px solid ${colors.schedule.border}`,
|
|
599
635
|
}}
|
|
600
636
|
>
|
|
601
|
-
<Flex
|
|
637
|
+
<Flex
|
|
638
|
+
alignItems="center"
|
|
639
|
+
gap={3}
|
|
640
|
+
style={{ marginBottom: config.scheduleType === 'weekly' ? 16 : 0 }}
|
|
641
|
+
>
|
|
602
642
|
<Box
|
|
603
643
|
style={{
|
|
604
644
|
width: 40,
|
|
@@ -655,7 +695,9 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
|
|
|
655
695
|
size="S"
|
|
656
696
|
/>
|
|
657
697
|
</Box>
|
|
658
|
-
<Badge backgroundColor="warning100" textColor="warning700">
|
|
698
|
+
<Badge backgroundColor="warning100" textColor="warning700">
|
|
699
|
+
UTC
|
|
700
|
+
</Badge>
|
|
659
701
|
</Flex>
|
|
660
702
|
)}
|
|
661
703
|
|
|
@@ -675,7 +717,9 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
|
|
|
675
717
|
size="S"
|
|
676
718
|
/>
|
|
677
719
|
</Box>
|
|
678
|
-
<Badge backgroundColor="warning100" textColor="warning700">
|
|
720
|
+
<Badge backgroundColor="warning100" textColor="warning700">
|
|
721
|
+
UTC
|
|
722
|
+
</Badge>
|
|
679
723
|
</Flex>
|
|
680
724
|
)}
|
|
681
725
|
|
|
@@ -692,14 +736,20 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
|
|
|
692
736
|
size="S"
|
|
693
737
|
/>
|
|
694
738
|
</Box>
|
|
695
|
-
<Badge backgroundColor="neutral150" textColor="neutral600">
|
|
739
|
+
<Badge backgroundColor="neutral150" textColor="neutral600">
|
|
740
|
+
cron
|
|
741
|
+
</Badge>
|
|
696
742
|
</Flex>
|
|
697
743
|
)}
|
|
698
744
|
</Flex>
|
|
699
745
|
|
|
700
746
|
{config.scheduleType === 'weekly' && (
|
|
701
747
|
<Box>
|
|
702
|
-
<Typography
|
|
748
|
+
<Typography
|
|
749
|
+
variant="pi"
|
|
750
|
+
textColor="neutral600"
|
|
751
|
+
style={{ marginBottom: 8, display: 'block' }}
|
|
752
|
+
>
|
|
703
753
|
Select days
|
|
704
754
|
</Typography>
|
|
705
755
|
<Flex gap={2}>
|
|
@@ -715,10 +765,14 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
|
|
|
715
765
|
borderRadius: '50%',
|
|
716
766
|
background: isSelected
|
|
717
767
|
? `linear-gradient(135deg, ${colors.schedule.color} 0%, #0284c7 100%)`
|
|
718
|
-
: isWeekend
|
|
768
|
+
: isWeekend
|
|
769
|
+
? colors.weekday.weekend
|
|
770
|
+
: colors.weekday.inactive,
|
|
719
771
|
border: isSelected
|
|
720
772
|
? `2px solid ${colors.schedule.color}`
|
|
721
|
-
: isWeekend
|
|
773
|
+
: isWeekend
|
|
774
|
+
? `2px solid ${colors.weekday.weekendBorder}`
|
|
775
|
+
: `2px solid ${colors.weekday.inactiveBorder}`,
|
|
722
776
|
display: 'flex',
|
|
723
777
|
alignItems: 'center',
|
|
724
778
|
justifyContent: 'center',
|
|
@@ -732,7 +786,9 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
|
|
|
732
786
|
<Typography
|
|
733
787
|
variant="pi"
|
|
734
788
|
fontWeight="bold"
|
|
735
|
-
textColor={
|
|
789
|
+
textColor={
|
|
790
|
+
isSelected ? 'neutral0' : isWeekend ? 'danger600' : 'neutral700'
|
|
791
|
+
}
|
|
736
792
|
>
|
|
737
793
|
{day.label}
|
|
738
794
|
</Typography>
|
|
@@ -744,8 +800,13 @@ const TriggerConfigField = forwardRef<HTMLDivElement, TriggerConfigFieldProps>(
|
|
|
744
800
|
)}
|
|
745
801
|
|
|
746
802
|
{config.scheduleType === 'cron' && (
|
|
747
|
-
<Typography
|
|
748
|
-
|
|
803
|
+
<Typography
|
|
804
|
+
variant="pi"
|
|
805
|
+
textColor="neutral500"
|
|
806
|
+
style={{ marginTop: 8, display: 'block' }}
|
|
807
|
+
>
|
|
808
|
+
Format: minute hour day month weekday (e.g., "0 12 * * *" = daily at 12:00
|
|
809
|
+
UTC)
|
|
749
810
|
</Typography>
|
|
750
811
|
)}
|
|
751
812
|
</Box>
|