@cadraos/sdk 0.3.9 → 0.3.10
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/dist/chat/index.cjs +0 -4
- package/dist/chat/index.cjs.map +1 -1
- package/dist/chat/index.js +0 -4
- package/dist/chat/index.js.map +1 -1
- package/dist/index.cjs +0 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +0 -4
- package/dist/index.js.map +1 -1
- package/dist/kanban/engine/index.cjs +0 -6
- package/dist/kanban/engine/index.cjs.map +1 -1
- package/dist/kanban/engine/index.js +0 -6
- package/dist/kanban/engine/index.js.map +1 -1
- package/dist/kanban/index.cjs +265 -35
- package/dist/kanban/index.cjs.map +1 -1
- package/dist/kanban/index.d.cts +110 -5
- package/dist/kanban/index.d.ts +110 -5
- package/dist/kanban/index.js +265 -35
- package/dist/kanban/index.js.map +1 -1
- package/dist/teams/index.cjs +0 -4
- package/dist/teams/index.cjs.map +1 -1
- package/dist/teams/index.js +0 -4
- package/dist/teams/index.js.map +1 -1
- package/package.json +1 -1
package/dist/kanban/index.cjs
CHANGED
|
@@ -305,7 +305,7 @@ function useKanbanBoard(options) {
|
|
|
305
305
|
try {
|
|
306
306
|
const full = await adapter.getCard(cardId);
|
|
307
307
|
setSelectedCard(
|
|
308
|
-
(prev) => prev
|
|
308
|
+
(prev) => prev == null || prev.id === cardId ? full : prev
|
|
309
309
|
);
|
|
310
310
|
} catch (err) {
|
|
311
311
|
if (!known) fail(err, "Failed to open card");
|
|
@@ -414,6 +414,27 @@ function useKanbanBoard(options) {
|
|
|
414
414
|
},
|
|
415
415
|
[refresh]
|
|
416
416
|
);
|
|
417
|
+
const deleteCard = react.useCallback(
|
|
418
|
+
async (cardId) => {
|
|
419
|
+
if (!adapter.deleteCard) return false;
|
|
420
|
+
setError(null);
|
|
421
|
+
const prevCards = cards;
|
|
422
|
+
const prevSelected = selectedCard;
|
|
423
|
+
setCards((prev) => prev.filter((c) => c.id !== cardId));
|
|
424
|
+
setSelectedCard((prev) => prev && prev.id === cardId ? null : prev);
|
|
425
|
+
try {
|
|
426
|
+
await adapter.deleteCard(cardId);
|
|
427
|
+
void silentRefresh();
|
|
428
|
+
return true;
|
|
429
|
+
} catch (err) {
|
|
430
|
+
setCards(prevCards);
|
|
431
|
+
setSelectedCard(prevSelected);
|
|
432
|
+
fail(err, "Failed to delete card");
|
|
433
|
+
return false;
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
[adapter, cards, selectedCard, silentRefresh, fail]
|
|
437
|
+
);
|
|
417
438
|
return {
|
|
418
439
|
board,
|
|
419
440
|
lanes: board?.lanes ?? [],
|
|
@@ -429,6 +450,7 @@ function useKanbanBoard(options) {
|
|
|
429
450
|
createCard,
|
|
430
451
|
updateCard,
|
|
431
452
|
transitionCard,
|
|
453
|
+
deleteCard,
|
|
432
454
|
handleRunTerminal
|
|
433
455
|
};
|
|
434
456
|
}
|
|
@@ -2722,6 +2744,9 @@ function KanbanCard({
|
|
|
2722
2744
|
onClick,
|
|
2723
2745
|
selected,
|
|
2724
2746
|
dueState,
|
|
2747
|
+
draggable,
|
|
2748
|
+
onDragStart,
|
|
2749
|
+
onDragEnd,
|
|
2725
2750
|
className
|
|
2726
2751
|
}) {
|
|
2727
2752
|
const runStatus = card.run?.status;
|
|
@@ -2750,10 +2775,20 @@ function KanbanCard({
|
|
|
2750
2775
|
onClick: () => onClick?.(card),
|
|
2751
2776
|
"aria-pressed": selected,
|
|
2752
2777
|
"aria-busy": isWorking,
|
|
2778
|
+
draggable,
|
|
2779
|
+
onDragStart: draggable ? (e) => {
|
|
2780
|
+
e.dataTransfer.effectAllowed = "move";
|
|
2781
|
+
e.dataTransfer.setData("text/plain", card.id);
|
|
2782
|
+
onDragStart?.(card);
|
|
2783
|
+
} : void 0,
|
|
2784
|
+
onDragEnd: draggable ? () => onDragEnd?.() : void 0,
|
|
2753
2785
|
className: cn9(
|
|
2754
|
-
|
|
2786
|
+
// Solid card: fill + border + a faint token top-sheen (adapts to theme),
|
|
2787
|
+
// matching the host's cockpit cards (work-shell v2 visual pass).
|
|
2788
|
+
"relative w-full text-left rounded-xl border bg-card bg-gradient-to-b from-foreground/[0.03] to-transparent p-3 shadow-sm motion-safe:transition-shadow",
|
|
2755
2789
|
"hover:shadow-md hover:border-primary/40",
|
|
2756
2790
|
"focus:outline-none focus:ring-2 focus:ring-ring/50",
|
|
2791
|
+
draggable && "cursor-grab active:cursor-grabbing",
|
|
2757
2792
|
// The working card carries the SINGLE focal motion on the board (F11).
|
|
2758
2793
|
isWorking ? "border-info/60 ring-2 ring-info/40 animate-pulse" : selected ? "border-primary/60 ring-2 ring-primary/30" : "border-border",
|
|
2759
2794
|
className
|
|
@@ -2830,6 +2865,11 @@ function CapMeter({ count, cap, className }) {
|
|
|
2830
2865
|
}
|
|
2831
2866
|
);
|
|
2832
2867
|
}
|
|
2868
|
+
var AGENT_GROUPS = [
|
|
2869
|
+
{ kind: "cadra", label: "Cadra agents" },
|
|
2870
|
+
{ kind: "remote", label: "Your own agents" },
|
|
2871
|
+
{ kind: "human", label: "Teammates" }
|
|
2872
|
+
];
|
|
2833
2873
|
function AgentKindIcon({ kind }) {
|
|
2834
2874
|
const common = {
|
|
2835
2875
|
viewBox: "0 0 24 24",
|
|
@@ -2872,17 +2912,55 @@ function OnlineDot({ online }) {
|
|
|
2872
2912
|
}
|
|
2873
2913
|
);
|
|
2874
2914
|
}
|
|
2915
|
+
function RemoteBadge() {
|
|
2916
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 rounded-full border border-accent/40 bg-accent/15 px-1.5 py-px text-[10px] font-semibold leading-4 text-accent", children: "Remote" });
|
|
2917
|
+
}
|
|
2875
2918
|
function LaneAgentPicker({
|
|
2876
2919
|
selected,
|
|
2877
2920
|
options,
|
|
2878
2921
|
onSelect,
|
|
2879
2922
|
canEdit = true,
|
|
2880
2923
|
lockedReason,
|
|
2924
|
+
onEditAgent,
|
|
2881
2925
|
className
|
|
2882
2926
|
}) {
|
|
2883
2927
|
const [open, setOpen] = react.useState(false);
|
|
2928
|
+
const [placement, setPlacement] = react.useState(null);
|
|
2884
2929
|
const rootRef = react.useRef(null);
|
|
2930
|
+
const triggerRef = react.useRef(null);
|
|
2885
2931
|
const editable = canEdit && !!onSelect && (options?.length ?? 0) > 0;
|
|
2932
|
+
const openMenu = () => {
|
|
2933
|
+
const el = triggerRef.current;
|
|
2934
|
+
if (el && typeof window !== "undefined") {
|
|
2935
|
+
const rect = el.getBoundingClientRect();
|
|
2936
|
+
const vw = window.innerWidth || 0;
|
|
2937
|
+
const vh = window.innerHeight || 0;
|
|
2938
|
+
const margin = 8;
|
|
2939
|
+
const gap = 4;
|
|
2940
|
+
const desired = 288;
|
|
2941
|
+
const width = Math.max(
|
|
2942
|
+
Math.min(rect.width || 224, Math.max(vw - margin * 2, 160)),
|
|
2943
|
+
160
|
|
2944
|
+
);
|
|
2945
|
+
const left = Math.min(
|
|
2946
|
+
Math.max(rect.left, margin),
|
|
2947
|
+
Math.max(vw - width - margin, margin)
|
|
2948
|
+
);
|
|
2949
|
+
const spaceBelow = vh - rect.bottom - gap - margin;
|
|
2950
|
+
const spaceAbove = rect.top - gap - margin;
|
|
2951
|
+
const flipUp = spaceBelow < desired && spaceAbove > spaceBelow;
|
|
2952
|
+
const maxHeight = Math.max(
|
|
2953
|
+
Math.min(desired, flipUp ? spaceAbove : spaceBelow),
|
|
2954
|
+
120
|
|
2955
|
+
);
|
|
2956
|
+
setPlacement(
|
|
2957
|
+
flipUp ? { bottom: Math.max(vh - rect.top + gap, margin), left, width, maxHeight } : { top: rect.bottom + gap, left, width, maxHeight }
|
|
2958
|
+
);
|
|
2959
|
+
} else {
|
|
2960
|
+
setPlacement(null);
|
|
2961
|
+
}
|
|
2962
|
+
setOpen(true);
|
|
2963
|
+
};
|
|
2886
2964
|
react.useEffect(() => {
|
|
2887
2965
|
if (!open) return;
|
|
2888
2966
|
const onDocDown = (e) => {
|
|
@@ -2916,14 +2994,28 @@ function LaneAgentPicker({
|
|
|
2916
2994
|
}
|
|
2917
2995
|
),
|
|
2918
2996
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: displayLabel }),
|
|
2997
|
+
kind === "remote" && /* @__PURE__ */ jsxRuntime.jsx(RemoteBadge, {}),
|
|
2919
2998
|
/* @__PURE__ */ jsxRuntime.jsx(OnlineDot, { online: selected?.online })
|
|
2920
2999
|
] });
|
|
3000
|
+
const grouped = AGENT_GROUPS.map((group) => ({
|
|
3001
|
+
...group,
|
|
3002
|
+
items: (options ?? []).filter((opt) => (opt.kind ?? "cadra") === group.kind)
|
|
3003
|
+
})).filter((group) => group.items.length > 0);
|
|
3004
|
+
const menuStyle = placement ? {
|
|
3005
|
+
position: "fixed",
|
|
3006
|
+
top: placement.top,
|
|
3007
|
+
bottom: placement.bottom,
|
|
3008
|
+
left: placement.left,
|
|
3009
|
+
width: placement.width,
|
|
3010
|
+
maxHeight: placement.maxHeight
|
|
3011
|
+
} : void 0;
|
|
2921
3012
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: rootRef, className: cn9("relative mt-2 w-full", className), children: [
|
|
2922
3013
|
editable ? /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2923
3014
|
"button",
|
|
2924
3015
|
{
|
|
3016
|
+
ref: triggerRef,
|
|
2925
3017
|
type: "button",
|
|
2926
|
-
onClick: () => setOpen(
|
|
3018
|
+
onClick: () => open ? setOpen(false) : openMenu(),
|
|
2927
3019
|
"aria-haspopup": "listbox",
|
|
2928
3020
|
"aria-expanded": open,
|
|
2929
3021
|
"aria-label": `Assigned agent: ${displayLabel}. Change`,
|
|
@@ -3001,47 +3093,106 @@ function LaneAgentPicker({
|
|
|
3001
3093
|
),
|
|
3002
3094
|
/* @__PURE__ */ jsxRuntime.jsx("span", { children: lockedReason })
|
|
3003
3095
|
] }),
|
|
3004
|
-
editable && open && /* @__PURE__ */ jsxRuntime.
|
|
3005
|
-
"
|
|
3096
|
+
editable && open && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3097
|
+
"div",
|
|
3006
3098
|
{
|
|
3007
|
-
|
|
3008
|
-
"aria-label": "Assign an agent",
|
|
3099
|
+
style: menuStyle,
|
|
3009
3100
|
className: cn9(
|
|
3010
|
-
"
|
|
3011
|
-
"
|
|
3101
|
+
"flex flex-col overflow-hidden rounded-lg border border-border bg-popover shadow-lg",
|
|
3102
|
+
menuStyle ? "z-50" : "absolute z-20 mt-1 max-h-64 w-full"
|
|
3012
3103
|
),
|
|
3013
|
-
children:
|
|
3014
|
-
|
|
3015
|
-
|
|
3104
|
+
children: [
|
|
3105
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3106
|
+
"ul",
|
|
3107
|
+
{
|
|
3108
|
+
role: "listbox",
|
|
3109
|
+
"aria-label": "Assign an agent",
|
|
3110
|
+
className: "min-h-0 flex-1 overflow-y-auto p-1",
|
|
3111
|
+
children: grouped.map((group) => /* @__PURE__ */ jsxRuntime.jsxs("li", { role: "presentation", children: [
|
|
3112
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-2 pb-1 pt-2 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: group.label }),
|
|
3113
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { role: "group", "aria-label": group.label, children: group.items.map((opt) => {
|
|
3114
|
+
const isSelected = opt.id === selected?.id;
|
|
3115
|
+
const optKind = opt.kind ?? "cadra";
|
|
3116
|
+
return /* @__PURE__ */ jsxRuntime.jsx("li", { role: "option", "aria-selected": isSelected, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3117
|
+
"button",
|
|
3118
|
+
{
|
|
3119
|
+
type: "button",
|
|
3120
|
+
onClick: () => {
|
|
3121
|
+
onSelect(opt.id);
|
|
3122
|
+
setOpen(false);
|
|
3123
|
+
},
|
|
3124
|
+
className: cn9(
|
|
3125
|
+
"flex min-h-11 w-full items-center gap-1.5 rounded-md px-2 text-left text-xs font-medium",
|
|
3126
|
+
"hover:bg-muted focus:outline-none focus:ring-2 focus:ring-ring/50",
|
|
3127
|
+
isSelected ? "text-primary" : "text-foreground"
|
|
3128
|
+
),
|
|
3129
|
+
children: [
|
|
3130
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3131
|
+
"span",
|
|
3132
|
+
{
|
|
3133
|
+
className: cn9(
|
|
3134
|
+
"grid h-5 w-5 shrink-0 place-items-center rounded-full",
|
|
3135
|
+
optKind === "cadra" ? "bg-primary/15 text-primary" : "bg-secondary text-foreground"
|
|
3136
|
+
),
|
|
3137
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(AgentKindIcon, { kind: optKind })
|
|
3138
|
+
}
|
|
3139
|
+
),
|
|
3140
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "min-w-0 flex-1 truncate", children: opt.label }),
|
|
3141
|
+
optKind === "remote" && /* @__PURE__ */ jsxRuntime.jsx(RemoteBadge, {}),
|
|
3142
|
+
/* @__PURE__ */ jsxRuntime.jsx(OnlineDot, { online: opt.online }),
|
|
3143
|
+
isSelected && /* @__PURE__ */ jsxRuntime.jsx(
|
|
3144
|
+
"svg",
|
|
3145
|
+
{
|
|
3146
|
+
viewBox: "0 0 24 24",
|
|
3147
|
+
fill: "none",
|
|
3148
|
+
stroke: "currentColor",
|
|
3149
|
+
strokeWidth: 2,
|
|
3150
|
+
strokeLinecap: "round",
|
|
3151
|
+
strokeLinejoin: "round",
|
|
3152
|
+
"aria-hidden": true,
|
|
3153
|
+
className: "h-3.5 w-3.5 shrink-0",
|
|
3154
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6L9 17l-5-5" })
|
|
3155
|
+
}
|
|
3156
|
+
)
|
|
3157
|
+
]
|
|
3158
|
+
}
|
|
3159
|
+
) }, opt.id);
|
|
3160
|
+
}) })
|
|
3161
|
+
] }, group.kind))
|
|
3162
|
+
}
|
|
3163
|
+
),
|
|
3164
|
+
onEditAgent && selected && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "border-t border-border p-1", children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3016
3165
|
"button",
|
|
3017
3166
|
{
|
|
3018
3167
|
type: "button",
|
|
3019
3168
|
onClick: () => {
|
|
3020
|
-
|
|
3169
|
+
onEditAgent(selected.id);
|
|
3021
3170
|
setOpen(false);
|
|
3022
3171
|
},
|
|
3023
3172
|
className: cn9(
|
|
3024
|
-
"flex min-h-11 w-full items-center gap-1.5 rounded-md px-2 text-left text-xs font-medium",
|
|
3025
|
-
"hover:bg-muted focus:outline-none focus:ring-2 focus:ring-ring/50"
|
|
3026
|
-
isSelected ? "text-primary" : "text-foreground"
|
|
3173
|
+
"flex min-h-11 w-full items-center gap-1.5 rounded-md px-2 text-left text-xs font-medium text-foreground",
|
|
3174
|
+
"hover:bg-muted focus:outline-none focus:ring-2 focus:ring-ring/50"
|
|
3027
3175
|
),
|
|
3028
3176
|
children: [
|
|
3029
3177
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3030
|
-
"
|
|
3178
|
+
"svg",
|
|
3031
3179
|
{
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3180
|
+
viewBox: "0 0 24 24",
|
|
3181
|
+
fill: "none",
|
|
3182
|
+
stroke: "currentColor",
|
|
3183
|
+
strokeWidth: 2,
|
|
3184
|
+
strokeLinecap: "round",
|
|
3185
|
+
strokeLinejoin: "round",
|
|
3186
|
+
"aria-hidden": true,
|
|
3187
|
+
className: "h-3.5 w-3.5 shrink-0 text-muted-foreground",
|
|
3188
|
+
children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" })
|
|
3037
3189
|
}
|
|
3038
3190
|
),
|
|
3039
|
-
|
|
3040
|
-
/* @__PURE__ */ jsxRuntime.jsx(OnlineDot, { online: opt.online })
|
|
3191
|
+
"Edit this agent"
|
|
3041
3192
|
]
|
|
3042
3193
|
}
|
|
3043
|
-
) }
|
|
3044
|
-
|
|
3194
|
+
) })
|
|
3195
|
+
]
|
|
3045
3196
|
}
|
|
3046
3197
|
)
|
|
3047
3198
|
] });
|
|
@@ -3066,6 +3217,12 @@ function KanbanColumn({
|
|
|
3066
3217
|
count,
|
|
3067
3218
|
agentPicker,
|
|
3068
3219
|
canEditHandlers,
|
|
3220
|
+
draggableCards,
|
|
3221
|
+
dragActive,
|
|
3222
|
+
dropAllowed,
|
|
3223
|
+
onCardDragStart,
|
|
3224
|
+
onCardDragEnd,
|
|
3225
|
+
onLaneDrop,
|
|
3069
3226
|
className
|
|
3070
3227
|
}) {
|
|
3071
3228
|
const headerCount = count ?? cards.length;
|
|
@@ -3076,9 +3233,21 @@ function KanbanColumn({
|
|
|
3076
3233
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3077
3234
|
"div",
|
|
3078
3235
|
{
|
|
3236
|
+
onDragOver: dropAllowed ? (e) => {
|
|
3237
|
+
e.preventDefault();
|
|
3238
|
+
e.dataTransfer.dropEffect = "move";
|
|
3239
|
+
} : void 0,
|
|
3240
|
+
onDrop: dropAllowed && onLaneDrop ? (e) => {
|
|
3241
|
+
e.preventDefault();
|
|
3242
|
+
onLaneDrop(lane);
|
|
3243
|
+
} : void 0,
|
|
3079
3244
|
className: cn9(
|
|
3080
|
-
"flex w-[85vw] max-w-sm snap-start shrink-0 flex-col rounded-xl bg-muted/40 border border-border sm:w-72 sm:max-w-none",
|
|
3245
|
+
"flex w-[85vw] max-w-sm snap-start shrink-0 flex-col rounded-xl bg-muted/40 border border-border transition sm:w-72 sm:max-w-none",
|
|
3081
3246
|
isScheduled && "border-border",
|
|
3247
|
+
// MV4 drag affordance: allowed targets glow; other lanes dim so the
|
|
3248
|
+
// valid drop zones read at a glance.
|
|
3249
|
+
dragActive && dropAllowed && "border-primary/60 ring-2 ring-primary/40 bg-primary/5",
|
|
3250
|
+
dragActive && !dropAllowed && "opacity-55",
|
|
3082
3251
|
className
|
|
3083
3252
|
),
|
|
3084
3253
|
children: [
|
|
@@ -3147,7 +3316,10 @@ function KanbanColumn({
|
|
|
3147
3316
|
card,
|
|
3148
3317
|
onClick: onCardClick,
|
|
3149
3318
|
selected: card.id === selectedCardId,
|
|
3150
|
-
dueState: dueStateFor(card, lane, now)
|
|
3319
|
+
dueState: dueStateFor(card, lane, now),
|
|
3320
|
+
draggable: draggableCards,
|
|
3321
|
+
onDragStart: onCardDragStart,
|
|
3322
|
+
onDragEnd: onCardDragEnd
|
|
3151
3323
|
},
|
|
3152
3324
|
card.id
|
|
3153
3325
|
)),
|
|
@@ -3307,6 +3479,8 @@ function KanbanBoard({
|
|
|
3307
3479
|
laneAgentPicker,
|
|
3308
3480
|
scheduleStatus,
|
|
3309
3481
|
focusCardId,
|
|
3482
|
+
renderCardDrawer,
|
|
3483
|
+
enableDrag,
|
|
3310
3484
|
className
|
|
3311
3485
|
}) {
|
|
3312
3486
|
const {
|
|
@@ -3321,6 +3495,7 @@ function KanbanBoard({
|
|
|
3321
3495
|
createCard,
|
|
3322
3496
|
updateCard,
|
|
3323
3497
|
transitionCard,
|
|
3498
|
+
deleteCard,
|
|
3324
3499
|
handleRunTerminal
|
|
3325
3500
|
} = useKanbanBoard({ adapter, onError, onCardCreated, pollIntervalMs });
|
|
3326
3501
|
const lastFocusedRef = react.useRef(void 0);
|
|
@@ -3365,6 +3540,44 @@ function KanbanBoard({
|
|
|
3365
3540
|
(cardId, toLane) => transitionCard({ cardId, targetLane: toLane }),
|
|
3366
3541
|
[transitionCard]
|
|
3367
3542
|
);
|
|
3543
|
+
const [dragging, setDragging] = react.useState(null);
|
|
3544
|
+
const draggingRef = react.useRef(null);
|
|
3545
|
+
const dropInFlightRef = react.useRef(null);
|
|
3546
|
+
const allowedDropLanes = react.useMemo(() => {
|
|
3547
|
+
if (!dragging || !board?.transitions) return /* @__PURE__ */ new Set();
|
|
3548
|
+
return new Set(
|
|
3549
|
+
board.transitions.filter((t) => t.fromLane === dragging.lane && t.manualAllowed).map((t) => t.toLane)
|
|
3550
|
+
);
|
|
3551
|
+
}, [dragging, board?.transitions]);
|
|
3552
|
+
const handleCardDragStart = react.useCallback((card) => {
|
|
3553
|
+
const d = { id: card.id, lane: card.lane };
|
|
3554
|
+
draggingRef.current = d;
|
|
3555
|
+
setDragging(d);
|
|
3556
|
+
}, []);
|
|
3557
|
+
const handleCardDragEnd = react.useCallback(() => {
|
|
3558
|
+
draggingRef.current = null;
|
|
3559
|
+
setDragging(null);
|
|
3560
|
+
}, []);
|
|
3561
|
+
const handleLaneDrop = react.useCallback(
|
|
3562
|
+
(lane) => {
|
|
3563
|
+
const cur = draggingRef.current;
|
|
3564
|
+
draggingRef.current = null;
|
|
3565
|
+
setDragging(null);
|
|
3566
|
+
if (!cur || lane.key === cur.lane) return;
|
|
3567
|
+
if (dropInFlightRef.current === cur.id) return;
|
|
3568
|
+
const allowed = (board?.transitions ?? []).some(
|
|
3569
|
+
(t) => t.fromLane === cur.lane && t.toLane === lane.key && t.manualAllowed
|
|
3570
|
+
);
|
|
3571
|
+
if (!allowed) return;
|
|
3572
|
+
dropInFlightRef.current = cur.id;
|
|
3573
|
+
void Promise.resolve(transitionCard({ cardId: cur.id, targetLane: lane.key })).finally(
|
|
3574
|
+
() => {
|
|
3575
|
+
if (dropInFlightRef.current === cur.id) dropInFlightRef.current = null;
|
|
3576
|
+
}
|
|
3577
|
+
);
|
|
3578
|
+
},
|
|
3579
|
+
[board?.transitions, transitionCard]
|
|
3580
|
+
);
|
|
3368
3581
|
const initialLaneKey = lanes.find((l) => !l.terminal)?.key ?? lanes[0]?.key;
|
|
3369
3582
|
const selectedLane = selectedCard ? lanes.find((l) => l.key === selectedCard.lane) : void 0;
|
|
3370
3583
|
const canAdvanceSelected = !!selectedLane && !selectedLane.terminal;
|
|
@@ -3385,12 +3598,32 @@ function KanbanBoard({
|
|
|
3385
3598
|
showCreate: enableCreate && lane.key === initialLaneKey,
|
|
3386
3599
|
count: laneCounts?.[lane.key],
|
|
3387
3600
|
agentPicker: laneAgentPicker?.(lane),
|
|
3388
|
-
canEditHandlers
|
|
3601
|
+
canEditHandlers,
|
|
3602
|
+
draggableCards: enableDrag && enableAdvance,
|
|
3603
|
+
dragActive: !!dragging,
|
|
3604
|
+
dropAllowed: !!dragging && dragging.lane !== lane.key && allowedDropLanes.has(lane.key),
|
|
3605
|
+
onCardDragStart: handleCardDragStart,
|
|
3606
|
+
onCardDragEnd: handleCardDragEnd,
|
|
3607
|
+
onLaneDrop: handleLaneDrop
|
|
3389
3608
|
},
|
|
3390
3609
|
lane.id ?? lane.key
|
|
3391
3610
|
))
|
|
3392
3611
|
] }),
|
|
3393
|
-
selectedCard &&
|
|
3612
|
+
selectedCard && (renderCardDrawer ? renderCardDrawer({
|
|
3613
|
+
card: selectedCard,
|
|
3614
|
+
adapter,
|
|
3615
|
+
lanes,
|
|
3616
|
+
transitions: enableAdvance ? board?.transitions : void 0,
|
|
3617
|
+
canAdvance: canAdvanceSelected,
|
|
3618
|
+
onClose: closeCard,
|
|
3619
|
+
onRetry: onRetryCard ? handleRetry : void 0,
|
|
3620
|
+
onUpdate: enableEdit ? handleUpdate : void 0,
|
|
3621
|
+
onAdvance: enableAdvance ? handleAdvance : void 0,
|
|
3622
|
+
onTransition: enableAdvance ? handleTransition : void 0,
|
|
3623
|
+
onDelete: adapter.deleteCard ? deleteCard : void 0,
|
|
3624
|
+
onRunTerminal: handleRunTerminal,
|
|
3625
|
+
onError
|
|
3626
|
+
}) : /* @__PURE__ */ jsxRuntime.jsx(
|
|
3394
3627
|
CardDrawer,
|
|
3395
3628
|
{
|
|
3396
3629
|
card: selectedCard,
|
|
@@ -3406,7 +3639,7 @@ function KanbanBoard({
|
|
|
3406
3639
|
onRunTerminal: handleRunTerminal,
|
|
3407
3640
|
onError
|
|
3408
3641
|
}
|
|
3409
|
-
)
|
|
3642
|
+
))
|
|
3410
3643
|
] })
|
|
3411
3644
|
] });
|
|
3412
3645
|
}
|
|
@@ -3431,6 +3664,7 @@ function composeAdapter(source, boardConfigUuid, version, cardSource) {
|
|
|
3431
3664
|
transitionCard(input) {
|
|
3432
3665
|
return cardSource.transitionCard(input);
|
|
3433
3666
|
},
|
|
3667
|
+
...cardSource.deleteCard ? { deleteCard: (id) => cardSource.deleteCard(id) } : {},
|
|
3434
3668
|
...cardSource.createRunStream ? { createRunStream: (id) => cardSource.createRunStream(id) } : {}
|
|
3435
3669
|
};
|
|
3436
3670
|
}
|
|
@@ -4804,7 +5038,6 @@ var AgentsAPI = class extends BaseResourceAPI {
|
|
|
4804
5038
|
super(http, "/api/v1/agents");
|
|
4805
5039
|
this.getStreamConfig = getStreamConfig;
|
|
4806
5040
|
}
|
|
4807
|
-
getStreamConfig;
|
|
4808
5041
|
// ===== LIST Operations =====
|
|
4809
5042
|
/**
|
|
4810
5043
|
* List all agents in the organization
|
|
@@ -5710,7 +5943,6 @@ var SessionsAPI = class extends BaseResourceAPI {
|
|
|
5710
5943
|
super(http, "/api/v1/sessions");
|
|
5711
5944
|
this.getStreamConfig = getStreamConfig;
|
|
5712
5945
|
}
|
|
5713
|
-
getStreamConfig;
|
|
5714
5946
|
// ===== LIST Operations =====
|
|
5715
5947
|
/**
|
|
5716
5948
|
* List all sessions in the organization
|
|
@@ -6030,7 +6262,6 @@ var KanbanAPI = class extends BaseResourceAPI {
|
|
|
6030
6262
|
super(http, "/api/v1/kanban");
|
|
6031
6263
|
this.getStreamConfig = getStreamConfig;
|
|
6032
6264
|
}
|
|
6033
|
-
getStreamConfig;
|
|
6034
6265
|
// ===== BOARD =====
|
|
6035
6266
|
/**
|
|
6036
6267
|
* Get the current org's board (lanes in declared order). Auto-provisions
|
|
@@ -6232,7 +6463,6 @@ var RemoteAgentsAPI = class extends BaseResourceAPI {
|
|
|
6232
6463
|
super(http, "/api/v1/remote-agents");
|
|
6233
6464
|
this.getStreamConfig = getStreamConfig;
|
|
6234
6465
|
}
|
|
6235
|
-
getStreamConfig;
|
|
6236
6466
|
/**
|
|
6237
6467
|
* List all remote agents in the organization
|
|
6238
6468
|
*
|