@inspirer-dev/crm-dashboard 1.0.84 → 1.0.86
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/ButtonsBuilder/index.tsx +97 -58
- package/admin/src/components/TriggerParamsField/index.tsx +331 -109
- package/admin/src/types/crm.ts +3 -1
- package/dist/_chunks/index-BqcFfrh8.js +478 -0
- package/dist/_chunks/index-CKr1VvX0.mjs +476 -0
- package/dist/_chunks/{index-Cg0G_bTE.js → index-CapXG1AZ.js} +73 -48
- package/dist/_chunks/{index-BKfFI_Jo.mjs → index-ClbsgJmF.mjs} +75 -50
- package/dist/admin/index.js +2 -2
- package/dist/admin/index.mjs +2 -2
- package/package.json +1 -1
- package/dist/_chunks/index-Bot_XlI2.mjs +0 -304
- package/dist/_chunks/index-Cmo9If32.js +0 -304
|
@@ -10,16 +10,20 @@ import {
|
|
|
10
10
|
Tooltip,
|
|
11
11
|
Card,
|
|
12
12
|
CardContent,
|
|
13
|
+
SingleSelect,
|
|
14
|
+
SingleSelectOption,
|
|
13
15
|
} from '@strapi/design-system';
|
|
14
|
-
import { Plus, Trash, ArrowUp, ArrowDown, Link as LinkIcon } from '@strapi/icons';
|
|
16
|
+
import { Plus, Trash, ArrowUp, ArrowDown, Link as LinkIcon, Layout } from '@strapi/icons';
|
|
15
17
|
import { useTheme } from 'styled-components';
|
|
16
18
|
import { generateId } from '../RulesBuilder/utils';
|
|
17
19
|
|
|
18
20
|
type TelegramButton = {
|
|
19
21
|
id: string;
|
|
20
22
|
text: string;
|
|
21
|
-
url
|
|
23
|
+
url?: string;
|
|
22
24
|
row?: number;
|
|
25
|
+
type?: 'url' | 'screen';
|
|
26
|
+
screenSlug?: string;
|
|
23
27
|
};
|
|
24
28
|
|
|
25
29
|
interface ButtonsBuilderProps {
|
|
@@ -37,26 +41,25 @@ interface ButtonsBuilderProps {
|
|
|
37
41
|
hint?: string;
|
|
38
42
|
}
|
|
39
43
|
|
|
44
|
+
const mapRawButton = (b: any): TelegramButton => ({
|
|
45
|
+
id: typeof b?.id === 'string' ? b.id : generateId(),
|
|
46
|
+
text: typeof b?.text === 'string' ? b.text : '',
|
|
47
|
+
url: typeof b?.url === 'string' ? b.url : '',
|
|
48
|
+
row: typeof b?.row === 'number' ? b.row : 0,
|
|
49
|
+
type: b?.type === 'screen' ? 'screen' : 'url',
|
|
50
|
+
screenSlug: typeof b?.screenSlug === 'string' ? b.screenSlug : '',
|
|
51
|
+
});
|
|
52
|
+
|
|
40
53
|
const parseButtons = (value: string | TelegramButton[] | null | undefined): TelegramButton[] => {
|
|
41
54
|
if (!value) return [];
|
|
42
55
|
if (Array.isArray(value)) {
|
|
43
|
-
return value.map(
|
|
44
|
-
id: typeof b?.id === 'string' ? b.id : generateId(),
|
|
45
|
-
text: typeof b?.text === 'string' ? b.text : '',
|
|
46
|
-
url: typeof b?.url === 'string' ? b.url : '',
|
|
47
|
-
row: typeof b?.row === 'number' ? b.row : 0,
|
|
48
|
-
}));
|
|
56
|
+
return value.map(mapRawButton);
|
|
49
57
|
}
|
|
50
58
|
if (typeof value === 'string') {
|
|
51
59
|
try {
|
|
52
60
|
const parsed = JSON.parse(value);
|
|
53
61
|
if (!Array.isArray(parsed)) return [];
|
|
54
|
-
return parsed.map(
|
|
55
|
-
id: typeof b?.id === 'string' ? b.id : generateId(),
|
|
56
|
-
text: typeof b?.text === 'string' ? b.text : '',
|
|
57
|
-
url: typeof b?.url === 'string' ? b.url : '',
|
|
58
|
-
row: typeof b?.row === 'number' ? b.row : 0,
|
|
59
|
-
}));
|
|
62
|
+
return parsed.map(mapRawButton);
|
|
60
63
|
} catch {
|
|
61
64
|
return [];
|
|
62
65
|
}
|
|
@@ -103,35 +106,39 @@ const useThemeColors = () => {
|
|
|
103
106
|
}), [isDark]);
|
|
104
107
|
};
|
|
105
108
|
|
|
106
|
-
const TelegramButtonPreview: React.FC<{ text: string; url
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
109
|
+
const TelegramButtonPreview: React.FC<{ text: string; btnType?: 'url' | 'screen' }> = ({ text, btnType }) => {
|
|
110
|
+
const isScreen = btnType === 'screen';
|
|
111
|
+
const bgColor = isScreen ? '#7c3aed' : '#3390ec';
|
|
112
|
+
const bgHover = isScreen ? '#6d28d9' : '#2b7ed8';
|
|
113
|
+
return (
|
|
114
|
+
<span
|
|
115
|
+
style={{
|
|
116
|
+
display: 'inline-flex',
|
|
117
|
+
alignItems: 'center',
|
|
118
|
+
justifyContent: 'center',
|
|
119
|
+
gap: '6px',
|
|
120
|
+
padding: '8px 16px',
|
|
121
|
+
backgroundColor: bgColor,
|
|
122
|
+
color: '#ffffff',
|
|
123
|
+
borderRadius: '8px',
|
|
124
|
+
textDecoration: 'none',
|
|
125
|
+
fontSize: '14px',
|
|
126
|
+
fontWeight: 500,
|
|
127
|
+
cursor: 'default',
|
|
128
|
+
transition: 'background-color 0.15s ease',
|
|
129
|
+
minWidth: '80px',
|
|
130
|
+
}}
|
|
131
|
+
onMouseEnter={(e) => (e.currentTarget.style.backgroundColor = bgHover)}
|
|
132
|
+
onMouseLeave={(e) => (e.currentTarget.style.backgroundColor = bgColor)}
|
|
133
|
+
>
|
|
134
|
+
{isScreen
|
|
135
|
+
? <Layout width={14} height={14} style={{ opacity: 0.9 }} />
|
|
136
|
+
: <LinkIcon width={14} height={14} style={{ opacity: 0.9 }} />
|
|
137
|
+
}
|
|
138
|
+
<span>{text || '(empty)'}</span>
|
|
139
|
+
</span>
|
|
140
|
+
);
|
|
141
|
+
};
|
|
135
142
|
|
|
136
143
|
const ButtonsBuilder = forwardRef<HTMLDivElement, ButtonsBuilderProps>(
|
|
137
144
|
({ name, value, onChange, intlLabel, disabled, error, required, hint }, ref) => {
|
|
@@ -150,7 +157,7 @@ const ButtonsBuilder = forwardRef<HTMLDivElement, ButtonsBuilderProps>(
|
|
|
150
157
|
const addButton = () => {
|
|
151
158
|
update([
|
|
152
159
|
...buttons,
|
|
153
|
-
{ id: generateId(), text: 'Button', url: 'https://cases.gg', row: 0 },
|
|
160
|
+
{ id: generateId(), text: 'Button', url: 'https://cases.gg', row: 0, type: 'url', screenSlug: '' },
|
|
154
161
|
]);
|
|
155
162
|
};
|
|
156
163
|
|
|
@@ -222,7 +229,8 @@ const ButtonsBuilder = forwardRef<HTMLDivElement, ButtonsBuilderProps>(
|
|
|
222
229
|
) : (
|
|
223
230
|
<Flex direction="column" gap={2}>
|
|
224
231
|
{buttons.map((btn, idx) => {
|
|
225
|
-
const
|
|
232
|
+
const isScreen = btn.type === 'screen';
|
|
233
|
+
const urlOk = isScreen || (btn.url ?? '').length === 0 || isValidUrl(btn.url ?? '');
|
|
226
234
|
return (
|
|
227
235
|
<Card
|
|
228
236
|
key={btn.id}
|
|
@@ -251,31 +259,62 @@ const ButtonsBuilder = forwardRef<HTMLDivElement, ButtonsBuilderProps>(
|
|
|
251
259
|
</Typography>
|
|
252
260
|
</Box>
|
|
253
261
|
|
|
254
|
-
<Box style={{
|
|
255
|
-
<
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
262
|
+
<Box style={{ width: 100, flexShrink: 0 }}>
|
|
263
|
+
<SingleSelect
|
|
264
|
+
value={btn.type || 'url'}
|
|
265
|
+
onChange={(val: string) =>
|
|
266
|
+
updateButton(btn.id, {
|
|
267
|
+
type: val as 'url' | 'screen',
|
|
268
|
+
...(val === 'url' ? { screenSlug: '' } : { url: '' }),
|
|
269
|
+
})
|
|
260
270
|
}
|
|
261
271
|
disabled={disabled}
|
|
262
272
|
size="S"
|
|
263
|
-
|
|
273
|
+
>
|
|
274
|
+
<SingleSelectOption value="url">URL</SingleSelectOption>
|
|
275
|
+
<SingleSelectOption value="screen">Screen</SingleSelectOption>
|
|
276
|
+
</SingleSelect>
|
|
264
277
|
</Box>
|
|
265
278
|
|
|
266
|
-
<Box style={{ flex:
|
|
279
|
+
<Box style={{ flex: 1, minWidth: 120 }}>
|
|
267
280
|
<TextInput
|
|
268
|
-
placeholder="
|
|
269
|
-
value={btn.
|
|
281
|
+
placeholder="Button text"
|
|
282
|
+
value={btn.text}
|
|
270
283
|
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
|
271
|
-
updateButton(btn.id, {
|
|
284
|
+
updateButton(btn.id, { text: e.target.value })
|
|
272
285
|
}
|
|
273
286
|
disabled={disabled}
|
|
274
287
|
size="S"
|
|
275
|
-
hasError={!urlOk}
|
|
276
288
|
/>
|
|
277
289
|
</Box>
|
|
278
290
|
|
|
291
|
+
{isScreen ? (
|
|
292
|
+
<Box style={{ flex: 2, minWidth: 180 }}>
|
|
293
|
+
<TextInput
|
|
294
|
+
placeholder="screen-slug"
|
|
295
|
+
value={btn.screenSlug ?? ''}
|
|
296
|
+
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
|
297
|
+
updateButton(btn.id, { screenSlug: e.target.value })
|
|
298
|
+
}
|
|
299
|
+
disabled={disabled}
|
|
300
|
+
size="S"
|
|
301
|
+
/>
|
|
302
|
+
</Box>
|
|
303
|
+
) : (
|
|
304
|
+
<Box style={{ flex: 2, minWidth: 180 }}>
|
|
305
|
+
<TextInput
|
|
306
|
+
placeholder="https://..."
|
|
307
|
+
value={btn.url ?? ''}
|
|
308
|
+
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
|
309
|
+
updateButton(btn.id, { url: e.target.value })
|
|
310
|
+
}
|
|
311
|
+
disabled={disabled}
|
|
312
|
+
size="S"
|
|
313
|
+
hasError={!urlOk}
|
|
314
|
+
/>
|
|
315
|
+
</Box>
|
|
316
|
+
)}
|
|
317
|
+
|
|
279
318
|
<Box style={{ width: 60 }}>
|
|
280
319
|
<TextInput
|
|
281
320
|
type="number"
|
|
@@ -359,7 +398,7 @@ const ButtonsBuilder = forwardRef<HTMLDivElement, ButtonsBuilderProps>(
|
|
|
359
398
|
{previewRows.map((row) => (
|
|
360
399
|
<Flex key={row.row} gap={2} wrap="wrap" justifyContent="center">
|
|
361
400
|
{row.items.map((b) => (
|
|
362
|
-
<TelegramButtonPreview key={b.id} text={b.text}
|
|
401
|
+
<TelegramButtonPreview key={b.id} text={b.text} btnType={b.type} />
|
|
363
402
|
))}
|
|
364
403
|
</Flex>
|
|
365
404
|
))}
|