@ykurilov/agent-chat-flows 0.75.0 → 0.76.0
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/CHANGELOG.md +15 -0
- package/README.md +4 -0
- package/dist/react.js +69 -61
- package/dist/react.js.map +1 -1
- package/dist/types/react/editor/board-space.d.ts +1 -0
- package/dist/types/react/flow-editor-skin.d.ts +5 -1
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @ykurilov/agent-chat-flows
|
|
2
2
|
|
|
3
|
+
## 0.76.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 6a50705: Общие переходы `anyState` перенесены из служебной ноды в отдельную панель настроек сценария. Шапка, меню телефона и обзор дают явный доступ; правила показывают условие и цель, сохраняют порядок, исключения и все настройки. Холст и мини-карта содержат только реальные состояния; старый `layout["@any"]` сохраняется, но не влияет на место или масштаб. Замечания проверки ведут к разделу и фокусируют правило; `readOnly` оставляет просмотр без изменений.
|
|
8
|
+
|
|
9
|
+
### Как обновить приложение
|
|
10
|
+
|
|
11
|
+
Обновите используемые пакеты SDK одной версией. `FlowEditor`/`FlowTestChat` с `tandemFlowEditorSkin` не требуют новых пропсов. JSON и runtime не меняются, удалять legacy-раскладку не требуется. Собственный скин может обработать необязательные `FlowHeaderProps.onOpenAnyState` и `FlowExitCardProps.summary`, а существующий слот обзора `sections` должен отображаться. Старый экспорт `FlowAnyStateNode` сохранён, доска его не вызывает. Проверьте компактную шапку, переход из замечаний при закрытом инспекторе и сохранение правил.
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- @ykurilov/agent-chat-core@0.76.0
|
|
16
|
+
- @ykurilov/agent-chat-react@0.76.0
|
|
17
|
+
|
|
3
18
|
## 0.75.0
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -123,3 +123,7 @@ checks })`. Поля приложения для карточки и попут
|
|
|
123
123
|
|
|
124
124
|
С 0.55 к версии 2 добавился таймер «наступил день N программы» (`{ "type": "timer", "from": "program_day", "day": 3 }`):
|
|
125
125
|
выход в начале дня N, когда бы человек ни пришёл в ноду. SDK до 0.55 такой сценарий не откроет.
|
|
126
|
+
|
|
127
|
+
### Общие переходы в редакторе
|
|
128
|
+
|
|
129
|
+
С 0.76.0 `anyState` редактируется в панели «Общие переходы» рядом с холстом, а не отдельной нодой. В компактной шапке и на телефоне вход доступен через действия редактора. Порядок, условия, цели и исключения сохраняются в прежнем JSON; runtime не меняется. `readOnly` оставляет просмотр. Собственному скину доступны необязательные `FlowHeaderProps.onOpenAnyState` и `FlowExitCardProps.summary`; старый экспорт `FlowAnyStateNode` сохранён, но доской не используется.
|
package/dist/react.js
CHANGED
|
@@ -722,7 +722,7 @@ function useFlowLabels() {
|
|
|
722
722
|
}
|
|
723
723
|
|
|
724
724
|
// src/react/editor/flow-editor.tsx
|
|
725
|
-
import { useMemo as useMemo4, useState as useState4 } from "react";
|
|
725
|
+
import { useEffect as useEffect3, useMemo as useMemo4, useRef as useRef3, useState as useState4 } from "react";
|
|
726
726
|
|
|
727
727
|
// src/react/editor/editor-model.ts
|
|
728
728
|
function freeId(prefix, taken) {
|
|
@@ -884,7 +884,7 @@ function removeField(flow, list, fieldId) {
|
|
|
884
884
|
};
|
|
885
885
|
}
|
|
886
886
|
function freeSpot(flow) {
|
|
887
|
-
const points =
|
|
887
|
+
const points = flow.states.flatMap((state) => flow.layout[state.id] ? [flow.layout[state.id]] : []);
|
|
888
888
|
if (points.length === 0) return { x: 80, y: 80 };
|
|
889
889
|
return { x: Math.min(...points.map((point) => point.x)), y: Math.max(...points.map((point) => point.y)) + 240 };
|
|
890
890
|
}
|
|
@@ -1036,6 +1036,10 @@ function useBoardSpace(props, editor) {
|
|
|
1036
1036
|
toggleMinimap: () => remember("minimap", !minimapOpen),
|
|
1037
1037
|
inspectorOpen,
|
|
1038
1038
|
inspectorToggleable: !needed,
|
|
1039
|
+
showInspector: () => {
|
|
1040
|
+
if (inspector === "collapsible") setFollowed(true);
|
|
1041
|
+
else remember("inspector", true);
|
|
1042
|
+
},
|
|
1039
1043
|
toggleInspector: () => {
|
|
1040
1044
|
if (needed) return;
|
|
1041
1045
|
if (inspector === "collapsible") setFollowed(!inspectorOpen);
|
|
@@ -1476,25 +1480,17 @@ function StateNodeView({ data }) {
|
|
|
1476
1480
|
data.draggable ? /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Right, id: NEW_EXIT_HANDLE, className: "flow-board__new-exit" }) : null
|
|
1477
1481
|
] });
|
|
1478
1482
|
}
|
|
1479
|
-
function AnyNodeView({ data }) {
|
|
1480
|
-
const skin = useSkin();
|
|
1481
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1482
|
-
/* @__PURE__ */ jsx(skin.FlowAnyStateNode, { ...data.view, renderExitHandle: (exitId) => exitHandle(exitId, data.draggable) }),
|
|
1483
|
-
data.draggable ? /* @__PURE__ */ jsx(Handle, { type: "source", position: Position.Right, id: NEW_EXIT_HANDLE, className: "flow-board__new-exit" }) : null
|
|
1484
|
-
] });
|
|
1485
|
-
}
|
|
1486
1483
|
function EdgeView({ id, sourceX, sourceY, targetX, targetY, sourcePosition, targetPosition, data }) {
|
|
1487
1484
|
const skin = useSkin();
|
|
1488
1485
|
const [path, labelX, labelY] = getBezierPath({ sourceX, sourceY, sourcePosition, targetX, targetY, targetPosition });
|
|
1489
1486
|
if (!data) return null;
|
|
1490
1487
|
return /* @__PURE__ */ jsx(skin.FlowEdge, { ...data, edgeId: id, path, labelX, labelY });
|
|
1491
1488
|
}
|
|
1492
|
-
var nodeTypes = { state: StateNodeView
|
|
1489
|
+
var nodeTypes = { state: StateNodeView };
|
|
1493
1490
|
var edgeTypes = { flow: EdgeView };
|
|
1494
1491
|
function nodePosition(flow, nodeId, index) {
|
|
1495
1492
|
const saved = flow.layout[nodeId];
|
|
1496
1493
|
if (saved) return saved;
|
|
1497
|
-
if (nodeId === ANY_STATE_LAYOUT_KEY) return { x: 40, y: -220 };
|
|
1498
1494
|
return { x: 40 + index % 4 * 330, y: 40 + Math.floor(index / 4) * 260 };
|
|
1499
1495
|
}
|
|
1500
1496
|
function countFor(issues, match) {
|
|
@@ -1554,27 +1550,7 @@ function useBoardModel(editor) {
|
|
|
1554
1550
|
}
|
|
1555
1551
|
}
|
|
1556
1552
|
}));
|
|
1557
|
-
if (flow.anyState.exits.length > 0 || flow.anyState.except.length > 0 || flow.layout[ANY_STATE_LAYOUT_KEY]) {
|
|
1558
|
-
nodes.push({
|
|
1559
|
-
id: ANY_STATE_LAYOUT_KEY,
|
|
1560
|
-
type: "any",
|
|
1561
|
-
position: nodePosition(flow, ANY_STATE_LAYOUT_KEY, 0),
|
|
1562
|
-
draggable: editable,
|
|
1563
|
-
data: {
|
|
1564
|
-
draggable: editable,
|
|
1565
|
-
view: {
|
|
1566
|
-
except: flow.anyState.except.map((id) => stateById(flow, id)?.title ?? id),
|
|
1567
|
-
exits: exitRows(flow, catalog, flow.anyState.exits, issues, labels),
|
|
1568
|
-
selected: selection.kind === "any",
|
|
1569
|
-
dimmed: marks !== null,
|
|
1570
|
-
issues: countFor(issues, (issue) => !issue.place.stateId && flow.anyState.exits.some((exit) => exit.id === issue.place.exitId)),
|
|
1571
|
-
onSelect: () => selectable && select({ kind: "any" })
|
|
1572
|
-
}
|
|
1573
|
-
}
|
|
1574
|
-
});
|
|
1575
|
-
}
|
|
1576
1553
|
const owners = [
|
|
1577
|
-
{ nodeId: ANY_STATE_LAYOUT_KEY, exits: flow.anyState.exits },
|
|
1578
1554
|
...flow.states.map((state) => ({ nodeId: state.id, exits: state.exits }))
|
|
1579
1555
|
];
|
|
1580
1556
|
const edges = owners.flatMap(
|
|
@@ -1930,7 +1906,8 @@ function useFlowEditor(options) {
|
|
|
1930
1906
|
);
|
|
1931
1907
|
const goToIssue = useCallback3((issue) => {
|
|
1932
1908
|
const { stateId, exitId, fieldId, sideTaskId } = issue.place;
|
|
1933
|
-
if (
|
|
1909
|
+
if (issue.code === "unknown_except_state") setSelection({ kind: "any" });
|
|
1910
|
+
else if (stateId && flow.states.some((state) => state.id === stateId)) setSelection({ kind: "state", stateId, ...exitId ? { exitId } : {} });
|
|
1934
1911
|
else if (exitId && flow.anyState.exits.some((exit) => exit.id === exitId)) setSelection({ kind: "any", exitId });
|
|
1935
1912
|
else if (sideTaskId) setSelection({ kind: "overview", sideTaskId });
|
|
1936
1913
|
else if (fieldId) setSelection({ kind: "card" });
|
|
@@ -2098,6 +2075,10 @@ function FlowEditor({ skin, className, style, header: headerMode, legend, minima
|
|
|
2098
2075
|
issues: editor.issueCount,
|
|
2099
2076
|
onAddState: () => editor.addState(freeSpot(flow)),
|
|
2100
2077
|
onOpenCard: () => editor.select({ kind: "card" }),
|
|
2078
|
+
onOpenAnyState: () => {
|
|
2079
|
+
editor.select({ kind: "any" });
|
|
2080
|
+
space.showInspector();
|
|
2081
|
+
},
|
|
2101
2082
|
onOpenJson: editor.openJson,
|
|
2102
2083
|
...options.onSave && !editor.readOnly ? { onSave: () => void editor.save() } : {},
|
|
2103
2084
|
saving: editor.saving,
|
|
@@ -2121,7 +2102,7 @@ function FlowEditor({ skin, className, style, header: headerMode, legend, minima
|
|
|
2121
2102
|
{
|
|
2122
2103
|
header,
|
|
2123
2104
|
board: /* @__PURE__ */ jsx2(FlowBoard, { editor, skin, space }),
|
|
2124
|
-
panel: space.inspectorOpen ? /* @__PURE__ */ jsx2(EditorPanel, { editor, skin, labels }) : null,
|
|
2105
|
+
panel: space.inspectorOpen ? /* @__PURE__ */ jsx2(EditorPanel, { editor, skin, labels, onNavigate: space.showInspector }) : null,
|
|
2125
2106
|
dialog: /* @__PURE__ */ jsx2(EditorDialog, { editor, skin }),
|
|
2126
2107
|
...space.header === "compact" ? { compact: true } : {},
|
|
2127
2108
|
...space.fullscreen ? { style: { height: "100%", minHeight: 0 } } : { ...className !== void 0 ? { className } : {}, ...style !== void 0 ? { style } : {} }
|
|
@@ -2171,10 +2152,12 @@ function ExitCards({ editor, skin, labels, owner }) {
|
|
|
2171
2152
|
const targets = targetOptions(flow, labels, owner !== null);
|
|
2172
2153
|
return /* @__PURE__ */ jsx2(Fragment2, { children: exits.map((exit, index) => {
|
|
2173
2154
|
const fieldType = exit.when.type === "data" ? fieldById(flow, exit.when.field)?.field.type : void 0;
|
|
2174
|
-
|
|
2155
|
+
const summary = `${conditionText(flow, exit.when, labels, editor.catalog)} \u2192 ${targetTitle(flow, exit.to, labels) ?? labels.board.noTarget}`;
|
|
2156
|
+
return /* @__PURE__ */ jsx2(ExitFocus, { label: summary, exitId: exit.id, selection: editor.selection, owner, children: /* @__PURE__ */ jsx2(
|
|
2175
2157
|
skin.FlowExitCard,
|
|
2176
2158
|
{
|
|
2177
2159
|
exitId: exit.id,
|
|
2160
|
+
...owner === null ? { summary } : {},
|
|
2178
2161
|
when: exit.when,
|
|
2179
2162
|
to: exit.to,
|
|
2180
2163
|
fields,
|
|
@@ -2189,11 +2172,20 @@ function ExitCards({ editor, skin, labels, owner }) {
|
|
|
2189
2172
|
onMoveUp: () => editor.edit((current) => moveExit(current, owner, exit.id, -1)),
|
|
2190
2173
|
onMoveDown: () => editor.edit((current) => moveExit(current, owner, exit.id, 1)),
|
|
2191
2174
|
onDelete: () => editor.edit((current) => removeExit(current, owner, exit.id))
|
|
2192
|
-
}
|
|
2193
|
-
|
|
2194
|
-
);
|
|
2175
|
+
}
|
|
2176
|
+
) }, exit.id);
|
|
2195
2177
|
}) });
|
|
2196
2178
|
}
|
|
2179
|
+
function ExitFocus({ label, exitId, selection, owner, children }) {
|
|
2180
|
+
const ref = useRef3(null);
|
|
2181
|
+
const focused = (selection.kind === "any" && owner === null || selection.kind === "state" && selection.stateId === owner) && selection.exitId === exitId;
|
|
2182
|
+
useEffect3(() => {
|
|
2183
|
+
if (!focused || !ref.current) return;
|
|
2184
|
+
ref.current.scrollIntoView?.({ block: "nearest" });
|
|
2185
|
+
ref.current.focus({ preventScroll: true });
|
|
2186
|
+
}, [focused, selection]);
|
|
2187
|
+
return /* @__PURE__ */ jsx2("div", { ref, role: "group", "aria-label": label, tabIndex: focused ? -1 : void 0, "data-flow-exit-focus": exitId, children });
|
|
2188
|
+
}
|
|
2197
2189
|
function FieldRows({ editor, skin, list }) {
|
|
2198
2190
|
const fields = editor.flow[list];
|
|
2199
2191
|
return /* @__PURE__ */ jsx2(Fragment2, { children: fields.map((field, index) => /* @__PURE__ */ jsx2(
|
|
@@ -2212,15 +2204,18 @@ function FieldRows({ editor, skin, list }) {
|
|
|
2212
2204
|
field.id
|
|
2213
2205
|
)) });
|
|
2214
2206
|
}
|
|
2215
|
-
function EditorPanel({ editor, skin, labels }) {
|
|
2216
|
-
const panel = /* @__PURE__ */ jsx2(EditablePanel, { editor, skin, labels });
|
|
2207
|
+
function EditorPanel({ editor, skin, labels, onNavigate }) {
|
|
2208
|
+
const panel = /* @__PURE__ */ jsx2(EditablePanel, { editor, skin, labels, onNavigate });
|
|
2217
2209
|
if (!editor.readOnly || editor.mode !== "edit") return panel;
|
|
2218
2210
|
return /* @__PURE__ */ jsx2("fieldset", { disabled: true, "data-flow-read-only": "", className: "m-0 flex min-h-0 min-w-0 flex-1 flex-col border-0 p-0", children: panel });
|
|
2219
2211
|
}
|
|
2220
|
-
function EditablePanel({ editor, skin, labels }) {
|
|
2212
|
+
function EditablePanel({ editor, skin, labels, onNavigate }) {
|
|
2221
2213
|
const { flow, selection } = editor;
|
|
2222
2214
|
if (editor.mode === "check") {
|
|
2223
|
-
return /* @__PURE__ */ jsx2(skin.FlowCheckPanel, { issues: editor.issues.map((issue) => ({ ...issue, onGo: () =>
|
|
2215
|
+
return /* @__PURE__ */ jsx2(skin.FlowCheckPanel, { issues: editor.issues.map((issue) => ({ ...issue, onGo: () => {
|
|
2216
|
+
editor.goToIssue(issue);
|
|
2217
|
+
onNavigate();
|
|
2218
|
+
} })) });
|
|
2224
2219
|
}
|
|
2225
2220
|
if (editor.mode === "run" && editor.simulation) return /* @__PURE__ */ jsx2(RunPanel, { editor, skin, labels });
|
|
2226
2221
|
if (selection.kind === "state") {
|
|
@@ -2261,18 +2256,7 @@ function EditablePanel({ editor, skin, labels }) {
|
|
|
2261
2256
|
state.id
|
|
2262
2257
|
);
|
|
2263
2258
|
}
|
|
2264
|
-
if (selection.kind === "any") {
|
|
2265
|
-
return /* @__PURE__ */ jsx2(
|
|
2266
|
-
skin.FlowAnyStatePanel,
|
|
2267
|
-
{
|
|
2268
|
-
except: flow.anyState.except,
|
|
2269
|
-
states: stateLinks(editor),
|
|
2270
|
-
onExceptChange: (except) => editor.edit((current) => setExcept(current, except)),
|
|
2271
|
-
exits: /* @__PURE__ */ jsx2(ExitCards, { editor, skin, labels, owner: null }),
|
|
2272
|
-
onAddExit: (kind) => editor.edit((current) => addExit(current, null, kind).flow)
|
|
2273
|
-
}
|
|
2274
|
-
);
|
|
2275
|
-
}
|
|
2259
|
+
if (selection.kind === "any") return /* @__PURE__ */ jsx2(AnyStateSettings, { editor, skin, labels });
|
|
2276
2260
|
if (selection.kind === "card") {
|
|
2277
2261
|
return /* @__PURE__ */ jsx2(
|
|
2278
2262
|
skin.FlowCardPanel,
|
|
@@ -2305,12 +2289,25 @@ function EditablePanel({ editor, skin, labels }) {
|
|
|
2305
2289
|
states: stateLinks(editor),
|
|
2306
2290
|
issues: editor.issueCount,
|
|
2307
2291
|
sections: /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
2292
|
+
/* @__PURE__ */ jsx2("div", { style: { flex: "none" }, children: /* @__PURE__ */ jsx2(AnyStateSettings, { editor, skin, labels }) }),
|
|
2308
2293
|
/* @__PURE__ */ jsx2(ScheduleSection, { editor, skin, labels }),
|
|
2309
2294
|
/* @__PURE__ */ jsx2(SideTasksSection, { editor, skin, focused: selection.kind === "overview" ? selection.sideTaskId : void 0 })
|
|
2310
2295
|
] })
|
|
2311
2296
|
}
|
|
2312
2297
|
);
|
|
2313
2298
|
}
|
|
2299
|
+
function AnyStateSettings({ editor, skin, labels }) {
|
|
2300
|
+
return /* @__PURE__ */ jsx2(
|
|
2301
|
+
skin.FlowAnyStatePanel,
|
|
2302
|
+
{
|
|
2303
|
+
except: editor.flow.anyState.except,
|
|
2304
|
+
states: stateLinks(editor),
|
|
2305
|
+
onExceptChange: (except) => editor.edit((current) => setExcept(current, except)),
|
|
2306
|
+
exits: /* @__PURE__ */ jsx2(ExitCards, { editor, skin, labels, owner: null }),
|
|
2307
|
+
onAddExit: (kind) => editor.edit((current) => addExit(current, null, kind).flow)
|
|
2308
|
+
}
|
|
2309
|
+
);
|
|
2310
|
+
}
|
|
2314
2311
|
var SCHEDULE_ISSUES = /* @__PURE__ */ new Set(["night_before_day_start", "unknown_deadline_state", "day_frame_soft_after_hard"]);
|
|
2315
2312
|
var isScheduleIssue = (issue) => SCHEDULE_ISSUES.has(issue.code) || issue.code === "empty_nudges" && !issue.place.stateId;
|
|
2316
2313
|
function NudgesEditor({ skin, nudges, optional, onChange }) {
|
|
@@ -2502,15 +2499,15 @@ function EditorDialog({ editor, skin }) {
|
|
|
2502
2499
|
}
|
|
2503
2500
|
|
|
2504
2501
|
// src/react/client-card/use-client-card.ts
|
|
2505
|
-
import { useCallback as useCallback4, useEffect as
|
|
2502
|
+
import { useCallback as useCallback4, useEffect as useEffect4, useRef as useRef4, useState as useState5 } from "react";
|
|
2506
2503
|
function useClientCard(options) {
|
|
2507
|
-
const latest =
|
|
2504
|
+
const latest = useRef4(options);
|
|
2508
2505
|
latest.current = options;
|
|
2509
2506
|
const [state, setState] = useState5("loading");
|
|
2510
2507
|
const [entries, setEntries] = useState5([]);
|
|
2511
2508
|
const [busy, setBusy] = useState5(/* @__PURE__ */ new Set());
|
|
2512
2509
|
const [forgettingAll, setForgettingAll] = useState5(false);
|
|
2513
|
-
const alive =
|
|
2510
|
+
const alive = useRef4(true);
|
|
2514
2511
|
const load = useCallback4(async () => {
|
|
2515
2512
|
setState("loading");
|
|
2516
2513
|
try {
|
|
@@ -2522,7 +2519,7 @@ function useClientCard(options) {
|
|
|
2522
2519
|
if (alive.current) setState("failed");
|
|
2523
2520
|
}
|
|
2524
2521
|
}, []);
|
|
2525
|
-
|
|
2522
|
+
useEffect4(() => {
|
|
2526
2523
|
alive.current = true;
|
|
2527
2524
|
void load();
|
|
2528
2525
|
return () => {
|
|
@@ -2667,7 +2664,7 @@ function durationText2(ms, labels) {
|
|
|
2667
2664
|
}
|
|
2668
2665
|
|
|
2669
2666
|
// src/react/test-chat/use-flow-test-chat.ts
|
|
2670
|
-
import { useCallback as useCallback5, useEffect as
|
|
2667
|
+
import { useCallback as useCallback5, useEffect as useEffect5, useRef as useRef5, useState as useState6 } from "react";
|
|
2671
2668
|
var RUN_POLL_MS = 1e3;
|
|
2672
2669
|
function runOf(run) {
|
|
2673
2670
|
if (!run || typeof run.state !== "string") return null;
|
|
@@ -2685,7 +2682,7 @@ function useFlowTestChat(connection, flow) {
|
|
|
2685
2682
|
const [failed, setFailed] = useState6(false);
|
|
2686
2683
|
const [nothingScheduled, setNothingScheduled] = useState6(false);
|
|
2687
2684
|
const [run, setRun] = useState6(null);
|
|
2688
|
-
const latest =
|
|
2685
|
+
const latest = useRef5({ connection, flow, chatId });
|
|
2689
2686
|
latest.current = { connection, flow, chatId };
|
|
2690
2687
|
const refresh = useCallback5(async (id) => {
|
|
2691
2688
|
try {
|
|
@@ -2695,7 +2692,7 @@ function useFlowTestChat(connection, flow) {
|
|
|
2695
2692
|
console.error("[flow] test chat: run not read", error);
|
|
2696
2693
|
}
|
|
2697
2694
|
}, []);
|
|
2698
|
-
|
|
2695
|
+
useEffect5(() => {
|
|
2699
2696
|
if (!opened || chatId === null) return;
|
|
2700
2697
|
void refresh(chatId);
|
|
2701
2698
|
const timer = setInterval(() => void refresh(chatId), RUN_POLL_MS);
|
|
@@ -2793,7 +2790,18 @@ function useTestChatView() {
|
|
|
2793
2790
|
function withTestChat(skin) {
|
|
2794
2791
|
function Header(props) {
|
|
2795
2792
|
const { controller } = useTestChatView();
|
|
2796
|
-
|
|
2793
|
+
const openAnyState = props.onOpenAnyState;
|
|
2794
|
+
return /* @__PURE__ */ jsx4(
|
|
2795
|
+
skin.FlowHeader,
|
|
2796
|
+
{
|
|
2797
|
+
...props,
|
|
2798
|
+
onOpenTestChat: controller.open,
|
|
2799
|
+
...openAnyState ? { onOpenAnyState: () => {
|
|
2800
|
+
controller.close();
|
|
2801
|
+
openAnyState();
|
|
2802
|
+
} } : {}
|
|
2803
|
+
}
|
|
2804
|
+
);
|
|
2797
2805
|
}
|
|
2798
2806
|
function Frame(props) {
|
|
2799
2807
|
const { panel } = useTestChatView();
|