@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
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef, useState, useEffect, useMemo } from "react";
|
|
3
|
-
import { Field, Flex, Box, Typography, Button, Card, CardContent, TextInput, Tooltip, IconButton } from "@strapi/design-system";
|
|
4
|
-
import { Plus, ArrowUp, ArrowDown, Trash, Link } from "@strapi/icons";
|
|
3
|
+
import { Field, Flex, Box, Typography, Button, Card, CardContent, SingleSelect, SingleSelectOption, TextInput, Tooltip, IconButton } from "@strapi/design-system";
|
|
4
|
+
import { Plus, ArrowUp, ArrowDown, Trash, Layout, Link } from "@strapi/icons";
|
|
5
5
|
import { useTheme } from "styled-components";
|
|
6
6
|
import { m as generateId } from "./utils-BHneBJ7U.mjs";
|
|
7
|
+
const mapRawButton = (b) => ({
|
|
8
|
+
id: typeof b?.id === "string" ? b.id : generateId(),
|
|
9
|
+
text: typeof b?.text === "string" ? b.text : "",
|
|
10
|
+
url: typeof b?.url === "string" ? b.url : "",
|
|
11
|
+
row: typeof b?.row === "number" ? b.row : 0,
|
|
12
|
+
type: b?.type === "screen" ? "screen" : "url",
|
|
13
|
+
screenSlug: typeof b?.screenSlug === "string" ? b.screenSlug : ""
|
|
14
|
+
});
|
|
7
15
|
const parseButtons = (value) => {
|
|
8
16
|
if (!value) return [];
|
|
9
17
|
if (Array.isArray(value)) {
|
|
10
|
-
return value.map(
|
|
11
|
-
id: typeof b?.id === "string" ? b.id : generateId(),
|
|
12
|
-
text: typeof b?.text === "string" ? b.text : "",
|
|
13
|
-
url: typeof b?.url === "string" ? b.url : "",
|
|
14
|
-
row: typeof b?.row === "number" ? b.row : 0
|
|
15
|
-
}));
|
|
18
|
+
return value.map(mapRawButton);
|
|
16
19
|
}
|
|
17
20
|
if (typeof value === "string") {
|
|
18
21
|
try {
|
|
19
22
|
const parsed = JSON.parse(value);
|
|
20
23
|
if (!Array.isArray(parsed)) return [];
|
|
21
|
-
return parsed.map(
|
|
22
|
-
id: typeof b?.id === "string" ? b.id : generateId(),
|
|
23
|
-
text: typeof b?.text === "string" ? b.text : "",
|
|
24
|
-
url: typeof b?.url === "string" ? b.url : "",
|
|
25
|
-
row: typeof b?.row === "number" ? b.row : 0
|
|
26
|
-
}));
|
|
24
|
+
return parsed.map(mapRawButton);
|
|
27
25
|
} catch {
|
|
28
26
|
return [];
|
|
29
27
|
}
|
|
@@ -59,37 +57,38 @@ const useThemeColors = () => {
|
|
|
59
57
|
}
|
|
60
58
|
}), [isDark]);
|
|
61
59
|
};
|
|
62
|
-
const TelegramButtonPreview = ({ text,
|
|
63
|
-
"
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
);
|
|
60
|
+
const TelegramButtonPreview = ({ text, btnType }) => {
|
|
61
|
+
const isScreen = btnType === "screen";
|
|
62
|
+
const bgColor = isScreen ? "#7c3aed" : "#3390ec";
|
|
63
|
+
const bgHover = isScreen ? "#6d28d9" : "#2b7ed8";
|
|
64
|
+
return /* @__PURE__ */ jsxs(
|
|
65
|
+
"span",
|
|
66
|
+
{
|
|
67
|
+
style: {
|
|
68
|
+
display: "inline-flex",
|
|
69
|
+
alignItems: "center",
|
|
70
|
+
justifyContent: "center",
|
|
71
|
+
gap: "6px",
|
|
72
|
+
padding: "8px 16px",
|
|
73
|
+
backgroundColor: bgColor,
|
|
74
|
+
color: "#ffffff",
|
|
75
|
+
borderRadius: "8px",
|
|
76
|
+
textDecoration: "none",
|
|
77
|
+
fontSize: "14px",
|
|
78
|
+
fontWeight: 500,
|
|
79
|
+
cursor: "default",
|
|
80
|
+
transition: "background-color 0.15s ease",
|
|
81
|
+
minWidth: "80px"
|
|
82
|
+
},
|
|
83
|
+
onMouseEnter: (e) => e.currentTarget.style.backgroundColor = bgHover,
|
|
84
|
+
onMouseLeave: (e) => e.currentTarget.style.backgroundColor = bgColor,
|
|
85
|
+
children: [
|
|
86
|
+
isScreen ? /* @__PURE__ */ jsx(Layout, { width: 14, height: 14, style: { opacity: 0.9 } }) : /* @__PURE__ */ jsx(Link, { width: 14, height: 14, style: { opacity: 0.9 } }),
|
|
87
|
+
/* @__PURE__ */ jsx("span", { children: text || "(empty)" })
|
|
88
|
+
]
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
};
|
|
93
92
|
const ButtonsBuilder = forwardRef(
|
|
94
93
|
({ name, value, onChange, intlLabel, disabled, error, required, hint }, ref) => {
|
|
95
94
|
const [buttons, setButtons] = useState(() => parseButtons(value));
|
|
@@ -104,7 +103,7 @@ const ButtonsBuilder = forwardRef(
|
|
|
104
103
|
const addButton = () => {
|
|
105
104
|
update([
|
|
106
105
|
...buttons,
|
|
107
|
-
{ id: generateId(), text: "Button", url: "https://cases.gg", row: 0 }
|
|
106
|
+
{ id: generateId(), text: "Button", url: "https://cases.gg", row: 0, type: "url", screenSlug: "" }
|
|
108
107
|
]);
|
|
109
108
|
};
|
|
110
109
|
const updateButton = (id, patch) => {
|
|
@@ -162,7 +161,8 @@ const ButtonsBuilder = forwardRef(
|
|
|
162
161
|
]
|
|
163
162
|
}
|
|
164
163
|
) : /* @__PURE__ */ jsx(Flex, { direction: "column", gap: 2, children: buttons.map((btn, idx) => {
|
|
165
|
-
const
|
|
164
|
+
const isScreen = btn.type === "screen";
|
|
165
|
+
const urlOk = isScreen || (btn.url ?? "").length === 0 || isValidUrl(btn.url ?? "");
|
|
166
166
|
return /* @__PURE__ */ jsx(
|
|
167
167
|
Card,
|
|
168
168
|
{
|
|
@@ -189,6 +189,22 @@ const ButtonsBuilder = forwardRef(
|
|
|
189
189
|
children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "primary600", children: idx + 1 })
|
|
190
190
|
}
|
|
191
191
|
),
|
|
192
|
+
/* @__PURE__ */ jsx(Box, { style: { width: 100, flexShrink: 0 }, children: /* @__PURE__ */ jsxs(
|
|
193
|
+
SingleSelect,
|
|
194
|
+
{
|
|
195
|
+
value: btn.type || "url",
|
|
196
|
+
onChange: (val) => updateButton(btn.id, {
|
|
197
|
+
type: val,
|
|
198
|
+
...val === "url" ? { screenSlug: "" } : { url: "" }
|
|
199
|
+
}),
|
|
200
|
+
disabled,
|
|
201
|
+
size: "S",
|
|
202
|
+
children: [
|
|
203
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "url", children: "URL" }),
|
|
204
|
+
/* @__PURE__ */ jsx(SingleSelectOption, { value: "screen", children: "Screen" })
|
|
205
|
+
]
|
|
206
|
+
}
|
|
207
|
+
) }),
|
|
192
208
|
/* @__PURE__ */ jsx(Box, { style: { flex: 1, minWidth: 120 }, children: /* @__PURE__ */ jsx(
|
|
193
209
|
TextInput,
|
|
194
210
|
{
|
|
@@ -199,11 +215,20 @@ const ButtonsBuilder = forwardRef(
|
|
|
199
215
|
size: "S"
|
|
200
216
|
}
|
|
201
217
|
) }),
|
|
202
|
-
/* @__PURE__ */ jsx(Box, { style: { flex: 2, minWidth: 180 }, children: /* @__PURE__ */ jsx(
|
|
218
|
+
isScreen ? /* @__PURE__ */ jsx(Box, { style: { flex: 2, minWidth: 180 }, children: /* @__PURE__ */ jsx(
|
|
219
|
+
TextInput,
|
|
220
|
+
{
|
|
221
|
+
placeholder: "screen-slug",
|
|
222
|
+
value: btn.screenSlug ?? "",
|
|
223
|
+
onChange: (e) => updateButton(btn.id, { screenSlug: e.target.value }),
|
|
224
|
+
disabled,
|
|
225
|
+
size: "S"
|
|
226
|
+
}
|
|
227
|
+
) }) : /* @__PURE__ */ jsx(Box, { style: { flex: 2, minWidth: 180 }, children: /* @__PURE__ */ jsx(
|
|
203
228
|
TextInput,
|
|
204
229
|
{
|
|
205
230
|
placeholder: "https://...",
|
|
206
|
-
value: btn.url,
|
|
231
|
+
value: btn.url ?? "",
|
|
207
232
|
onChange: (e) => updateButton(btn.id, { url: e.target.value }),
|
|
208
233
|
disabled,
|
|
209
234
|
size: "S",
|
|
@@ -282,7 +307,7 @@ const ButtonsBuilder = forwardRef(
|
|
|
282
307
|
children: "PREVIEW"
|
|
283
308
|
}
|
|
284
309
|
),
|
|
285
|
-
/* @__PURE__ */ jsx(Flex, { direction: "column", gap: 2, alignItems: "center", children: previewRows.map((row) => /* @__PURE__ */ jsx(Flex, { gap: 2, wrap: "wrap", justifyContent: "center", children: row.items.map((b) => /* @__PURE__ */ jsx(TelegramButtonPreview, { text: b.text,
|
|
310
|
+
/* @__PURE__ */ jsx(Flex, { direction: "column", gap: 2, alignItems: "center", children: previewRows.map((row) => /* @__PURE__ */ jsx(Flex, { gap: 2, wrap: "wrap", justifyContent: "center", children: row.items.map((b) => /* @__PURE__ */ jsx(TelegramButtonPreview, { text: b.text, btnType: b.type }, b.id)) }, row.row)) })
|
|
286
311
|
]
|
|
287
312
|
}
|
|
288
313
|
),
|
package/dist/admin/index.js
CHANGED
|
@@ -107,7 +107,7 @@ const index = {
|
|
|
107
107
|
components: {
|
|
108
108
|
Input: async () => Promise.resolve().then(() => require(
|
|
109
109
|
/* webpackChunkName: "crm-telegram-buttons" */
|
|
110
|
-
"../_chunks/index-
|
|
110
|
+
"../_chunks/index-CapXG1AZ.js"
|
|
111
111
|
))
|
|
112
112
|
},
|
|
113
113
|
options: {
|
|
@@ -155,7 +155,7 @@ const index = {
|
|
|
155
155
|
components: {
|
|
156
156
|
Input: async () => Promise.resolve().then(() => require(
|
|
157
157
|
/* webpackChunkName: "crm-trigger-params" */
|
|
158
|
-
"../_chunks/index-
|
|
158
|
+
"../_chunks/index-BqcFfrh8.js"
|
|
159
159
|
))
|
|
160
160
|
},
|
|
161
161
|
options: {
|
package/dist/admin/index.mjs
CHANGED
|
@@ -106,7 +106,7 @@ const index = {
|
|
|
106
106
|
components: {
|
|
107
107
|
Input: async () => import(
|
|
108
108
|
/* webpackChunkName: "crm-telegram-buttons" */
|
|
109
|
-
"../_chunks/index-
|
|
109
|
+
"../_chunks/index-ClbsgJmF.mjs"
|
|
110
110
|
)
|
|
111
111
|
},
|
|
112
112
|
options: {
|
|
@@ -154,7 +154,7 @@ const index = {
|
|
|
154
154
|
components: {
|
|
155
155
|
Input: async () => import(
|
|
156
156
|
/* webpackChunkName: "crm-trigger-params" */
|
|
157
|
-
"../_chunks/index-
|
|
157
|
+
"../_chunks/index-CKr1VvX0.mjs"
|
|
158
158
|
)
|
|
159
159
|
},
|
|
160
160
|
options: {
|
package/package.json
CHANGED
|
@@ -1,304 +0,0 @@
|
|
|
1
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { forwardRef, useRef, useState, useMemo } from "react";
|
|
3
|
-
import { Field, Flex, Box, Typography, Card, CardContent, NumberInput, Tooltip, IconButton, SingleSelect, SingleSelectOption, Button } from "@strapi/design-system";
|
|
4
|
-
import { Trash, Plus } from "@strapi/icons";
|
|
5
|
-
import { useTheme } from "styled-components";
|
|
6
|
-
const TRIGGER_PARAMS = [
|
|
7
|
-
{
|
|
8
|
-
key: "delaySeconds",
|
|
9
|
-
label: "Задержка",
|
|
10
|
-
description: "Задержка перед показом после срабатывания триггера",
|
|
11
|
-
unit: "сек",
|
|
12
|
-
min: 0,
|
|
13
|
-
placeholder: "7",
|
|
14
|
-
stageTypes: ["side_hint", "modal", "retry"]
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
key: "timeOnSiteSeconds",
|
|
18
|
-
label: "Время на сайте",
|
|
19
|
-
description: "Мин. время на сайте для срабатывания",
|
|
20
|
-
unit: "сек",
|
|
21
|
-
min: 0,
|
|
22
|
-
placeholder: "120",
|
|
23
|
-
stageTypes: ["exit_intent", "side_hint", "modal"]
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
key: "scrollThresholdPx",
|
|
27
|
-
label: "Порог скролла",
|
|
28
|
-
description: "Скролл в пикселях для срабатывания",
|
|
29
|
-
unit: "px",
|
|
30
|
-
min: 0,
|
|
31
|
-
placeholder: "200",
|
|
32
|
-
stageTypes: ["side_hint"]
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
key: "idleSeconds",
|
|
36
|
-
label: "Бездействие",
|
|
37
|
-
description: "Время без кликов/скролла",
|
|
38
|
-
unit: "сек",
|
|
39
|
-
min: 0,
|
|
40
|
-
placeholder: "15",
|
|
41
|
-
stageTypes: ["side_hint"]
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
key: "caseViewSeconds",
|
|
45
|
-
label: "Просмотр кейса",
|
|
46
|
-
description: "Время на странице кейса",
|
|
47
|
-
unit: "сек",
|
|
48
|
-
min: 0,
|
|
49
|
-
placeholder: "12",
|
|
50
|
-
stageTypes: ["modal", "side_hint"]
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
key: "activePlayMinutes",
|
|
54
|
-
label: "Активная игра",
|
|
55
|
-
description: "Время активной игры",
|
|
56
|
-
unit: "мин",
|
|
57
|
-
min: 0,
|
|
58
|
-
placeholder: "10",
|
|
59
|
-
stageTypes: ["modal"]
|
|
60
|
-
},
|
|
61
|
-
{
|
|
62
|
-
key: "actionCountThreshold",
|
|
63
|
-
label: "Порог действий",
|
|
64
|
-
description: "Кол-во значимых действий + низкий баланс",
|
|
65
|
-
unit: "",
|
|
66
|
-
min: 0,
|
|
67
|
-
placeholder: "2",
|
|
68
|
-
stageTypes: ["modal"]
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
key: "balanceThresholdMultiplier",
|
|
72
|
-
label: "Множитель баланса",
|
|
73
|
-
description: 'Множитель мин. цены кейса для "низкого баланса"',
|
|
74
|
-
unit: "×",
|
|
75
|
-
min: 0,
|
|
76
|
-
placeholder: "1.5",
|
|
77
|
-
stageTypes: ["modal", "side_hint"]
|
|
78
|
-
},
|
|
79
|
-
{
|
|
80
|
-
key: "abandonedTimeoutMinutes",
|
|
81
|
-
label: "Таймаут заброшенного депозита",
|
|
82
|
-
description: "Через сколько минут депозит считается заброшенным",
|
|
83
|
-
unit: "мин",
|
|
84
|
-
min: 1,
|
|
85
|
-
placeholder: "10",
|
|
86
|
-
stageTypes: ["retry"]
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
key: "minDepositAmount",
|
|
90
|
-
label: "Мин. сумма депозита",
|
|
91
|
-
description: "Подстановка в {{min_deposit}} в текстах",
|
|
92
|
-
unit: "₽",
|
|
93
|
-
min: 0,
|
|
94
|
-
placeholder: "250",
|
|
95
|
-
stageTypes: ["modal", "side_hint", "retry"]
|
|
96
|
-
}
|
|
97
|
-
];
|
|
98
|
-
const STAGE_TYPE_LABELS = {
|
|
99
|
-
side_hint: "Side-hint",
|
|
100
|
-
modal: "Modal",
|
|
101
|
-
exit_intent: "Exit intent",
|
|
102
|
-
retry: "Retry"
|
|
103
|
-
};
|
|
104
|
-
const parseValue = (value) => {
|
|
105
|
-
if (!value) return {};
|
|
106
|
-
if (typeof value === "object" && !Array.isArray(value)) return value;
|
|
107
|
-
if (typeof value === "string") {
|
|
108
|
-
try {
|
|
109
|
-
const parsed = JSON.parse(value);
|
|
110
|
-
if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) return parsed;
|
|
111
|
-
} catch {
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return {};
|
|
115
|
-
};
|
|
116
|
-
const serialize = (params) => {
|
|
117
|
-
const out = {};
|
|
118
|
-
for (const [key, val] of Object.entries(params)) {
|
|
119
|
-
out[key] = typeof val === "number" ? val : null;
|
|
120
|
-
}
|
|
121
|
-
return JSON.stringify(out);
|
|
122
|
-
};
|
|
123
|
-
const useThemeColors = () => {
|
|
124
|
-
const theme = useTheme();
|
|
125
|
-
const isDark = theme?.colors?.neutral0 === "#212134";
|
|
126
|
-
return useMemo(
|
|
127
|
-
() => ({
|
|
128
|
-
isDark,
|
|
129
|
-
emptyBorder: isDark ? "#32324d" : "#dcdce4",
|
|
130
|
-
cardBorder: isDark ? "#32324d" : "#eaeaef",
|
|
131
|
-
tagBg: isDark ? "#2d2d4a" : "#f0f0ff"
|
|
132
|
-
}),
|
|
133
|
-
[isDark]
|
|
134
|
-
);
|
|
135
|
-
};
|
|
136
|
-
const TriggerParamsField = forwardRef(
|
|
137
|
-
({ name, value, onChange, intlLabel, disabled, error, required, hint }, ref) => {
|
|
138
|
-
const initialRef = useRef(value);
|
|
139
|
-
const [params, setParams] = useState(() => parseValue(initialRef.current));
|
|
140
|
-
const colors = useThemeColors();
|
|
141
|
-
const update = (next) => {
|
|
142
|
-
setParams(next);
|
|
143
|
-
onChange({ target: { name, value: serialize(next) } });
|
|
144
|
-
};
|
|
145
|
-
const activeKeys = Object.keys(params);
|
|
146
|
-
const availableParams = TRIGGER_PARAMS.filter((p) => !activeKeys.includes(p.key));
|
|
147
|
-
const addParam = (key) => {
|
|
148
|
-
const def = TRIGGER_PARAMS.find((p) => p.key === key);
|
|
149
|
-
if (!def) return;
|
|
150
|
-
update({ ...params, [key]: null });
|
|
151
|
-
};
|
|
152
|
-
const removeParam = (key) => {
|
|
153
|
-
const next = { ...params };
|
|
154
|
-
delete next[key];
|
|
155
|
-
update(next);
|
|
156
|
-
};
|
|
157
|
-
const setParamValue = (key, val) => {
|
|
158
|
-
update({ ...params, [key]: val ?? null });
|
|
159
|
-
};
|
|
160
|
-
const getParamDef = (key) => TRIGGER_PARAMS.find((p) => p.key === key);
|
|
161
|
-
return /* @__PURE__ */ jsx(Field.Root, { name, error, required, hint, ref, children: /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, children: [
|
|
162
|
-
/* @__PURE__ */ jsx(Flex, { justifyContent: "space-between", alignItems: "center", children: /* @__PURE__ */ jsxs(Box, { children: [
|
|
163
|
-
/* @__PURE__ */ jsx(Field.Label, { children: intlLabel?.defaultMessage || "Trigger Params" }),
|
|
164
|
-
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral500", children: "Настройте параметры срабатывания для этого этапа" })
|
|
165
|
-
] }) }),
|
|
166
|
-
activeKeys.length === 0 ? /* @__PURE__ */ jsxs(
|
|
167
|
-
Box,
|
|
168
|
-
{
|
|
169
|
-
padding: 5,
|
|
170
|
-
background: "neutral100",
|
|
171
|
-
hasRadius: true,
|
|
172
|
-
style: {
|
|
173
|
-
border: `2px dashed ${colors.emptyBorder}`,
|
|
174
|
-
textAlign: "center"
|
|
175
|
-
},
|
|
176
|
-
children: [
|
|
177
|
-
/* @__PURE__ */ jsx(Typography, { variant: "omega", textColor: "neutral500", children: "Параметры не настроены" }),
|
|
178
|
-
/* @__PURE__ */ jsx(
|
|
179
|
-
Typography,
|
|
180
|
-
{
|
|
181
|
-
variant: "pi",
|
|
182
|
-
textColor: "neutral400",
|
|
183
|
-
style: { display: "block", marginTop: 4 },
|
|
184
|
-
children: "Добавьте параметры триггера, чтобы управлять условиями показа этапа"
|
|
185
|
-
}
|
|
186
|
-
)
|
|
187
|
-
]
|
|
188
|
-
}
|
|
189
|
-
) : /* @__PURE__ */ jsx(Flex, { direction: "column", gap: 2, children: activeKeys.map((key) => {
|
|
190
|
-
const def = getParamDef(key);
|
|
191
|
-
if (!def) return null;
|
|
192
|
-
return /* @__PURE__ */ jsx(
|
|
193
|
-
Card,
|
|
194
|
-
{
|
|
195
|
-
background: "neutral0",
|
|
196
|
-
style: {
|
|
197
|
-
border: `1px solid ${colors.cardBorder}`
|
|
198
|
-
},
|
|
199
|
-
children: /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsxs(Flex, { gap: 3, alignItems: "center", padding: 3, children: [
|
|
200
|
-
/* @__PURE__ */ jsxs(Box, { style: { flex: 1, minWidth: 0 }, children: [
|
|
201
|
-
/* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "center", marginBottom: 1, children: [
|
|
202
|
-
/* @__PURE__ */ jsx(Typography, { variant: "omega", fontWeight: "semiBold", children: def.label }),
|
|
203
|
-
def.unit && /* @__PURE__ */ jsxs(Typography, { variant: "pi", textColor: "neutral500", children: [
|
|
204
|
-
"(",
|
|
205
|
-
def.unit,
|
|
206
|
-
")"
|
|
207
|
-
] })
|
|
208
|
-
] }),
|
|
209
|
-
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral500", children: def.description }),
|
|
210
|
-
/* @__PURE__ */ jsx(Flex, { gap: 1, marginTop: 1, wrap: "wrap", children: def.stageTypes.map((st) => /* @__PURE__ */ jsx(
|
|
211
|
-
Box,
|
|
212
|
-
{
|
|
213
|
-
style: {
|
|
214
|
-
padding: "1px 6px",
|
|
215
|
-
borderRadius: "4px",
|
|
216
|
-
backgroundColor: colors.tagBg,
|
|
217
|
-
fontSize: "11px"
|
|
218
|
-
},
|
|
219
|
-
children: /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "primary600", children: STAGE_TYPE_LABELS[st] || st })
|
|
220
|
-
},
|
|
221
|
-
st
|
|
222
|
-
)) })
|
|
223
|
-
] }),
|
|
224
|
-
/* @__PURE__ */ jsx(Box, { style: { width: 120, flexShrink: 0 }, children: /* @__PURE__ */ jsx(
|
|
225
|
-
NumberInput,
|
|
226
|
-
{
|
|
227
|
-
placeholder: def.placeholder,
|
|
228
|
-
value: params[key] ?? "",
|
|
229
|
-
onValueChange: (val) => setParamValue(key, val),
|
|
230
|
-
disabled,
|
|
231
|
-
size: "S",
|
|
232
|
-
step: key === "balanceThresholdMultiplier" ? 0.1 : 1
|
|
233
|
-
}
|
|
234
|
-
) }),
|
|
235
|
-
/* @__PURE__ */ jsx(Tooltip, { label: "Удалить параметр", children: /* @__PURE__ */ jsx(
|
|
236
|
-
IconButton,
|
|
237
|
-
{
|
|
238
|
-
onClick: () => removeParam(key),
|
|
239
|
-
label: "Delete",
|
|
240
|
-
variant: "ghost",
|
|
241
|
-
size: "S",
|
|
242
|
-
disabled,
|
|
243
|
-
style: { color: "#d02b20", flexShrink: 0 },
|
|
244
|
-
children: /* @__PURE__ */ jsx(Trash, { width: 16, height: 16 })
|
|
245
|
-
}
|
|
246
|
-
) })
|
|
247
|
-
] }) })
|
|
248
|
-
},
|
|
249
|
-
key
|
|
250
|
-
);
|
|
251
|
-
}) }),
|
|
252
|
-
availableParams.length > 0 && /* @__PURE__ */ jsx(
|
|
253
|
-
AddParamSelect,
|
|
254
|
-
{
|
|
255
|
-
available: availableParams,
|
|
256
|
-
onAdd: addParam,
|
|
257
|
-
disabled
|
|
258
|
-
}
|
|
259
|
-
),
|
|
260
|
-
error && /* @__PURE__ */ jsx(Field.Error, {}),
|
|
261
|
-
hint && /* @__PURE__ */ jsx(Field.Hint, {})
|
|
262
|
-
] }) });
|
|
263
|
-
}
|
|
264
|
-
);
|
|
265
|
-
TriggerParamsField.displayName = "TriggerParamsField";
|
|
266
|
-
const AddParamSelect = ({ available, onAdd, disabled }) => {
|
|
267
|
-
const [selected, setSelected] = useState(null);
|
|
268
|
-
return /* @__PURE__ */ jsxs(Flex, { gap: 2, alignItems: "flex-end", children: [
|
|
269
|
-
/* @__PURE__ */ jsx(Box, { style: { flex: 1 }, children: /* @__PURE__ */ jsx(
|
|
270
|
-
SingleSelect,
|
|
271
|
-
{
|
|
272
|
-
placeholder: "Выберите параметр...",
|
|
273
|
-
value: selected,
|
|
274
|
-
onChange: (val) => setSelected(val),
|
|
275
|
-
disabled,
|
|
276
|
-
size: "S",
|
|
277
|
-
children: available.map((p) => /* @__PURE__ */ jsxs(SingleSelectOption, { value: p.key, children: [
|
|
278
|
-
p.label,
|
|
279
|
-
" — ",
|
|
280
|
-
p.description
|
|
281
|
-
] }, p.key))
|
|
282
|
-
}
|
|
283
|
-
) }),
|
|
284
|
-
/* @__PURE__ */ jsx(
|
|
285
|
-
Button,
|
|
286
|
-
{
|
|
287
|
-
startIcon: /* @__PURE__ */ jsx(Plus, {}),
|
|
288
|
-
onClick: () => {
|
|
289
|
-
if (selected) {
|
|
290
|
-
onAdd(selected);
|
|
291
|
-
setSelected(null);
|
|
292
|
-
}
|
|
293
|
-
},
|
|
294
|
-
disabled: disabled || !selected,
|
|
295
|
-
variant: "secondary",
|
|
296
|
-
size: "S",
|
|
297
|
-
children: "Добавить"
|
|
298
|
-
}
|
|
299
|
-
)
|
|
300
|
-
] });
|
|
301
|
-
};
|
|
302
|
-
export {
|
|
303
|
-
TriggerParamsField as default
|
|
304
|
-
};
|