@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.js
CHANGED
|
@@ -298,7 +298,7 @@ function useKanbanBoard(options) {
|
|
|
298
298
|
try {
|
|
299
299
|
const full = await adapter.getCard(cardId);
|
|
300
300
|
setSelectedCard(
|
|
301
|
-
(prev) => prev
|
|
301
|
+
(prev) => prev == null || prev.id === cardId ? full : prev
|
|
302
302
|
);
|
|
303
303
|
} catch (err) {
|
|
304
304
|
if (!known) fail(err, "Failed to open card");
|
|
@@ -407,6 +407,27 @@ function useKanbanBoard(options) {
|
|
|
407
407
|
},
|
|
408
408
|
[refresh]
|
|
409
409
|
);
|
|
410
|
+
const deleteCard = useCallback(
|
|
411
|
+
async (cardId) => {
|
|
412
|
+
if (!adapter.deleteCard) return false;
|
|
413
|
+
setError(null);
|
|
414
|
+
const prevCards = cards;
|
|
415
|
+
const prevSelected = selectedCard;
|
|
416
|
+
setCards((prev) => prev.filter((c) => c.id !== cardId));
|
|
417
|
+
setSelectedCard((prev) => prev && prev.id === cardId ? null : prev);
|
|
418
|
+
try {
|
|
419
|
+
await adapter.deleteCard(cardId);
|
|
420
|
+
void silentRefresh();
|
|
421
|
+
return true;
|
|
422
|
+
} catch (err) {
|
|
423
|
+
setCards(prevCards);
|
|
424
|
+
setSelectedCard(prevSelected);
|
|
425
|
+
fail(err, "Failed to delete card");
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
},
|
|
429
|
+
[adapter, cards, selectedCard, silentRefresh, fail]
|
|
430
|
+
);
|
|
410
431
|
return {
|
|
411
432
|
board,
|
|
412
433
|
lanes: board?.lanes ?? [],
|
|
@@ -422,6 +443,7 @@ function useKanbanBoard(options) {
|
|
|
422
443
|
createCard,
|
|
423
444
|
updateCard,
|
|
424
445
|
transitionCard,
|
|
446
|
+
deleteCard,
|
|
425
447
|
handleRunTerminal
|
|
426
448
|
};
|
|
427
449
|
}
|
|
@@ -2715,6 +2737,9 @@ function KanbanCard({
|
|
|
2715
2737
|
onClick,
|
|
2716
2738
|
selected,
|
|
2717
2739
|
dueState,
|
|
2740
|
+
draggable,
|
|
2741
|
+
onDragStart,
|
|
2742
|
+
onDragEnd,
|
|
2718
2743
|
className
|
|
2719
2744
|
}) {
|
|
2720
2745
|
const runStatus = card.run?.status;
|
|
@@ -2743,10 +2768,20 @@ function KanbanCard({
|
|
|
2743
2768
|
onClick: () => onClick?.(card),
|
|
2744
2769
|
"aria-pressed": selected,
|
|
2745
2770
|
"aria-busy": isWorking,
|
|
2771
|
+
draggable,
|
|
2772
|
+
onDragStart: draggable ? (e) => {
|
|
2773
|
+
e.dataTransfer.effectAllowed = "move";
|
|
2774
|
+
e.dataTransfer.setData("text/plain", card.id);
|
|
2775
|
+
onDragStart?.(card);
|
|
2776
|
+
} : void 0,
|
|
2777
|
+
onDragEnd: draggable ? () => onDragEnd?.() : void 0,
|
|
2746
2778
|
className: cn9(
|
|
2747
|
-
|
|
2779
|
+
// Solid card: fill + border + a faint token top-sheen (adapts to theme),
|
|
2780
|
+
// matching the host's cockpit cards (work-shell v2 visual pass).
|
|
2781
|
+
"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",
|
|
2748
2782
|
"hover:shadow-md hover:border-primary/40",
|
|
2749
2783
|
"focus:outline-none focus:ring-2 focus:ring-ring/50",
|
|
2784
|
+
draggable && "cursor-grab active:cursor-grabbing",
|
|
2750
2785
|
// The working card carries the SINGLE focal motion on the board (F11).
|
|
2751
2786
|
isWorking ? "border-info/60 ring-2 ring-info/40 animate-pulse" : selected ? "border-primary/60 ring-2 ring-primary/30" : "border-border",
|
|
2752
2787
|
className
|
|
@@ -2823,6 +2858,11 @@ function CapMeter({ count, cap, className }) {
|
|
|
2823
2858
|
}
|
|
2824
2859
|
);
|
|
2825
2860
|
}
|
|
2861
|
+
var AGENT_GROUPS = [
|
|
2862
|
+
{ kind: "cadra", label: "Cadra agents" },
|
|
2863
|
+
{ kind: "remote", label: "Your own agents" },
|
|
2864
|
+
{ kind: "human", label: "Teammates" }
|
|
2865
|
+
];
|
|
2826
2866
|
function AgentKindIcon({ kind }) {
|
|
2827
2867
|
const common = {
|
|
2828
2868
|
viewBox: "0 0 24 24",
|
|
@@ -2865,17 +2905,55 @@ function OnlineDot({ online }) {
|
|
|
2865
2905
|
}
|
|
2866
2906
|
);
|
|
2867
2907
|
}
|
|
2908
|
+
function RemoteBadge() {
|
|
2909
|
+
return /* @__PURE__ */ 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" });
|
|
2910
|
+
}
|
|
2868
2911
|
function LaneAgentPicker({
|
|
2869
2912
|
selected,
|
|
2870
2913
|
options,
|
|
2871
2914
|
onSelect,
|
|
2872
2915
|
canEdit = true,
|
|
2873
2916
|
lockedReason,
|
|
2917
|
+
onEditAgent,
|
|
2874
2918
|
className
|
|
2875
2919
|
}) {
|
|
2876
2920
|
const [open, setOpen] = useState(false);
|
|
2921
|
+
const [placement, setPlacement] = useState(null);
|
|
2877
2922
|
const rootRef = useRef(null);
|
|
2923
|
+
const triggerRef = useRef(null);
|
|
2878
2924
|
const editable = canEdit && !!onSelect && (options?.length ?? 0) > 0;
|
|
2925
|
+
const openMenu = () => {
|
|
2926
|
+
const el = triggerRef.current;
|
|
2927
|
+
if (el && typeof window !== "undefined") {
|
|
2928
|
+
const rect = el.getBoundingClientRect();
|
|
2929
|
+
const vw = window.innerWidth || 0;
|
|
2930
|
+
const vh = window.innerHeight || 0;
|
|
2931
|
+
const margin = 8;
|
|
2932
|
+
const gap = 4;
|
|
2933
|
+
const desired = 288;
|
|
2934
|
+
const width = Math.max(
|
|
2935
|
+
Math.min(rect.width || 224, Math.max(vw - margin * 2, 160)),
|
|
2936
|
+
160
|
|
2937
|
+
);
|
|
2938
|
+
const left = Math.min(
|
|
2939
|
+
Math.max(rect.left, margin),
|
|
2940
|
+
Math.max(vw - width - margin, margin)
|
|
2941
|
+
);
|
|
2942
|
+
const spaceBelow = vh - rect.bottom - gap - margin;
|
|
2943
|
+
const spaceAbove = rect.top - gap - margin;
|
|
2944
|
+
const flipUp = spaceBelow < desired && spaceAbove > spaceBelow;
|
|
2945
|
+
const maxHeight = Math.max(
|
|
2946
|
+
Math.min(desired, flipUp ? spaceAbove : spaceBelow),
|
|
2947
|
+
120
|
|
2948
|
+
);
|
|
2949
|
+
setPlacement(
|
|
2950
|
+
flipUp ? { bottom: Math.max(vh - rect.top + gap, margin), left, width, maxHeight } : { top: rect.bottom + gap, left, width, maxHeight }
|
|
2951
|
+
);
|
|
2952
|
+
} else {
|
|
2953
|
+
setPlacement(null);
|
|
2954
|
+
}
|
|
2955
|
+
setOpen(true);
|
|
2956
|
+
};
|
|
2879
2957
|
useEffect(() => {
|
|
2880
2958
|
if (!open) return;
|
|
2881
2959
|
const onDocDown = (e) => {
|
|
@@ -2909,14 +2987,28 @@ function LaneAgentPicker({
|
|
|
2909
2987
|
}
|
|
2910
2988
|
),
|
|
2911
2989
|
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate text-left", children: displayLabel }),
|
|
2990
|
+
kind === "remote" && /* @__PURE__ */ jsx(RemoteBadge, {}),
|
|
2912
2991
|
/* @__PURE__ */ jsx(OnlineDot, { online: selected?.online })
|
|
2913
2992
|
] });
|
|
2993
|
+
const grouped = AGENT_GROUPS.map((group) => ({
|
|
2994
|
+
...group,
|
|
2995
|
+
items: (options ?? []).filter((opt) => (opt.kind ?? "cadra") === group.kind)
|
|
2996
|
+
})).filter((group) => group.items.length > 0);
|
|
2997
|
+
const menuStyle = placement ? {
|
|
2998
|
+
position: "fixed",
|
|
2999
|
+
top: placement.top,
|
|
3000
|
+
bottom: placement.bottom,
|
|
3001
|
+
left: placement.left,
|
|
3002
|
+
width: placement.width,
|
|
3003
|
+
maxHeight: placement.maxHeight
|
|
3004
|
+
} : void 0;
|
|
2914
3005
|
return /* @__PURE__ */ jsxs("div", { ref: rootRef, className: cn9("relative mt-2 w-full", className), children: [
|
|
2915
3006
|
editable ? /* @__PURE__ */ jsxs(
|
|
2916
3007
|
"button",
|
|
2917
3008
|
{
|
|
3009
|
+
ref: triggerRef,
|
|
2918
3010
|
type: "button",
|
|
2919
|
-
onClick: () => setOpen(
|
|
3011
|
+
onClick: () => open ? setOpen(false) : openMenu(),
|
|
2920
3012
|
"aria-haspopup": "listbox",
|
|
2921
3013
|
"aria-expanded": open,
|
|
2922
3014
|
"aria-label": `Assigned agent: ${displayLabel}. Change`,
|
|
@@ -2994,47 +3086,106 @@ function LaneAgentPicker({
|
|
|
2994
3086
|
),
|
|
2995
3087
|
/* @__PURE__ */ jsx("span", { children: lockedReason })
|
|
2996
3088
|
] }),
|
|
2997
|
-
editable && open && /* @__PURE__ */
|
|
2998
|
-
"
|
|
3089
|
+
editable && open && /* @__PURE__ */ jsxs(
|
|
3090
|
+
"div",
|
|
2999
3091
|
{
|
|
3000
|
-
|
|
3001
|
-
"aria-label": "Assign an agent",
|
|
3092
|
+
style: menuStyle,
|
|
3002
3093
|
className: cn9(
|
|
3003
|
-
"
|
|
3004
|
-
"
|
|
3094
|
+
"flex flex-col overflow-hidden rounded-lg border border-border bg-popover shadow-lg",
|
|
3095
|
+
menuStyle ? "z-50" : "absolute z-20 mt-1 max-h-64 w-full"
|
|
3005
3096
|
),
|
|
3006
|
-
children:
|
|
3007
|
-
|
|
3008
|
-
|
|
3097
|
+
children: [
|
|
3098
|
+
/* @__PURE__ */ jsx(
|
|
3099
|
+
"ul",
|
|
3100
|
+
{
|
|
3101
|
+
role: "listbox",
|
|
3102
|
+
"aria-label": "Assign an agent",
|
|
3103
|
+
className: "min-h-0 flex-1 overflow-y-auto p-1",
|
|
3104
|
+
children: grouped.map((group) => /* @__PURE__ */ jsxs("li", { role: "presentation", children: [
|
|
3105
|
+
/* @__PURE__ */ jsx("div", { className: "px-2 pb-1 pt-2 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: group.label }),
|
|
3106
|
+
/* @__PURE__ */ jsx("ul", { role: "group", "aria-label": group.label, children: group.items.map((opt) => {
|
|
3107
|
+
const isSelected = opt.id === selected?.id;
|
|
3108
|
+
const optKind = opt.kind ?? "cadra";
|
|
3109
|
+
return /* @__PURE__ */ jsx("li", { role: "option", "aria-selected": isSelected, children: /* @__PURE__ */ jsxs(
|
|
3110
|
+
"button",
|
|
3111
|
+
{
|
|
3112
|
+
type: "button",
|
|
3113
|
+
onClick: () => {
|
|
3114
|
+
onSelect(opt.id);
|
|
3115
|
+
setOpen(false);
|
|
3116
|
+
},
|
|
3117
|
+
className: cn9(
|
|
3118
|
+
"flex min-h-11 w-full items-center gap-1.5 rounded-md px-2 text-left text-xs font-medium",
|
|
3119
|
+
"hover:bg-muted focus:outline-none focus:ring-2 focus:ring-ring/50",
|
|
3120
|
+
isSelected ? "text-primary" : "text-foreground"
|
|
3121
|
+
),
|
|
3122
|
+
children: [
|
|
3123
|
+
/* @__PURE__ */ jsx(
|
|
3124
|
+
"span",
|
|
3125
|
+
{
|
|
3126
|
+
className: cn9(
|
|
3127
|
+
"grid h-5 w-5 shrink-0 place-items-center rounded-full",
|
|
3128
|
+
optKind === "cadra" ? "bg-primary/15 text-primary" : "bg-secondary text-foreground"
|
|
3129
|
+
),
|
|
3130
|
+
children: /* @__PURE__ */ jsx(AgentKindIcon, { kind: optKind })
|
|
3131
|
+
}
|
|
3132
|
+
),
|
|
3133
|
+
/* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", children: opt.label }),
|
|
3134
|
+
optKind === "remote" && /* @__PURE__ */ jsx(RemoteBadge, {}),
|
|
3135
|
+
/* @__PURE__ */ jsx(OnlineDot, { online: opt.online }),
|
|
3136
|
+
isSelected && /* @__PURE__ */ jsx(
|
|
3137
|
+
"svg",
|
|
3138
|
+
{
|
|
3139
|
+
viewBox: "0 0 24 24",
|
|
3140
|
+
fill: "none",
|
|
3141
|
+
stroke: "currentColor",
|
|
3142
|
+
strokeWidth: 2,
|
|
3143
|
+
strokeLinecap: "round",
|
|
3144
|
+
strokeLinejoin: "round",
|
|
3145
|
+
"aria-hidden": true,
|
|
3146
|
+
className: "h-3.5 w-3.5 shrink-0",
|
|
3147
|
+
children: /* @__PURE__ */ jsx("path", { d: "M20 6L9 17l-5-5" })
|
|
3148
|
+
}
|
|
3149
|
+
)
|
|
3150
|
+
]
|
|
3151
|
+
}
|
|
3152
|
+
) }, opt.id);
|
|
3153
|
+
}) })
|
|
3154
|
+
] }, group.kind))
|
|
3155
|
+
}
|
|
3156
|
+
),
|
|
3157
|
+
onEditAgent && selected && /* @__PURE__ */ jsx("div", { className: "border-t border-border p-1", children: /* @__PURE__ */ jsxs(
|
|
3009
3158
|
"button",
|
|
3010
3159
|
{
|
|
3011
3160
|
type: "button",
|
|
3012
3161
|
onClick: () => {
|
|
3013
|
-
|
|
3162
|
+
onEditAgent(selected.id);
|
|
3014
3163
|
setOpen(false);
|
|
3015
3164
|
},
|
|
3016
3165
|
className: cn9(
|
|
3017
|
-
"flex min-h-11 w-full items-center gap-1.5 rounded-md px-2 text-left text-xs font-medium",
|
|
3018
|
-
"hover:bg-muted focus:outline-none focus:ring-2 focus:ring-ring/50"
|
|
3019
|
-
isSelected ? "text-primary" : "text-foreground"
|
|
3166
|
+
"flex min-h-11 w-full items-center gap-1.5 rounded-md px-2 text-left text-xs font-medium text-foreground",
|
|
3167
|
+
"hover:bg-muted focus:outline-none focus:ring-2 focus:ring-ring/50"
|
|
3020
3168
|
),
|
|
3021
3169
|
children: [
|
|
3022
3170
|
/* @__PURE__ */ jsx(
|
|
3023
|
-
"
|
|
3171
|
+
"svg",
|
|
3024
3172
|
{
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3173
|
+
viewBox: "0 0 24 24",
|
|
3174
|
+
fill: "none",
|
|
3175
|
+
stroke: "currentColor",
|
|
3176
|
+
strokeWidth: 2,
|
|
3177
|
+
strokeLinecap: "round",
|
|
3178
|
+
strokeLinejoin: "round",
|
|
3179
|
+
"aria-hidden": true,
|
|
3180
|
+
className: "h-3.5 w-3.5 shrink-0 text-muted-foreground",
|
|
3181
|
+
children: /* @__PURE__ */ jsx("path", { d: "M17 3a2.85 2.83 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5Z" })
|
|
3030
3182
|
}
|
|
3031
3183
|
),
|
|
3032
|
-
|
|
3033
|
-
/* @__PURE__ */ jsx(OnlineDot, { online: opt.online })
|
|
3184
|
+
"Edit this agent"
|
|
3034
3185
|
]
|
|
3035
3186
|
}
|
|
3036
|
-
) }
|
|
3037
|
-
|
|
3187
|
+
) })
|
|
3188
|
+
]
|
|
3038
3189
|
}
|
|
3039
3190
|
)
|
|
3040
3191
|
] });
|
|
@@ -3059,6 +3210,12 @@ function KanbanColumn({
|
|
|
3059
3210
|
count,
|
|
3060
3211
|
agentPicker,
|
|
3061
3212
|
canEditHandlers,
|
|
3213
|
+
draggableCards,
|
|
3214
|
+
dragActive,
|
|
3215
|
+
dropAllowed,
|
|
3216
|
+
onCardDragStart,
|
|
3217
|
+
onCardDragEnd,
|
|
3218
|
+
onLaneDrop,
|
|
3062
3219
|
className
|
|
3063
3220
|
}) {
|
|
3064
3221
|
const headerCount = count ?? cards.length;
|
|
@@ -3069,9 +3226,21 @@ function KanbanColumn({
|
|
|
3069
3226
|
return /* @__PURE__ */ jsxs(
|
|
3070
3227
|
"div",
|
|
3071
3228
|
{
|
|
3229
|
+
onDragOver: dropAllowed ? (e) => {
|
|
3230
|
+
e.preventDefault();
|
|
3231
|
+
e.dataTransfer.dropEffect = "move";
|
|
3232
|
+
} : void 0,
|
|
3233
|
+
onDrop: dropAllowed && onLaneDrop ? (e) => {
|
|
3234
|
+
e.preventDefault();
|
|
3235
|
+
onLaneDrop(lane);
|
|
3236
|
+
} : void 0,
|
|
3072
3237
|
className: cn9(
|
|
3073
|
-
"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",
|
|
3238
|
+
"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",
|
|
3074
3239
|
isScheduled && "border-border",
|
|
3240
|
+
// MV4 drag affordance: allowed targets glow; other lanes dim so the
|
|
3241
|
+
// valid drop zones read at a glance.
|
|
3242
|
+
dragActive && dropAllowed && "border-primary/60 ring-2 ring-primary/40 bg-primary/5",
|
|
3243
|
+
dragActive && !dropAllowed && "opacity-55",
|
|
3075
3244
|
className
|
|
3076
3245
|
),
|
|
3077
3246
|
children: [
|
|
@@ -3140,7 +3309,10 @@ function KanbanColumn({
|
|
|
3140
3309
|
card,
|
|
3141
3310
|
onClick: onCardClick,
|
|
3142
3311
|
selected: card.id === selectedCardId,
|
|
3143
|
-
dueState: dueStateFor(card, lane, now)
|
|
3312
|
+
dueState: dueStateFor(card, lane, now),
|
|
3313
|
+
draggable: draggableCards,
|
|
3314
|
+
onDragStart: onCardDragStart,
|
|
3315
|
+
onDragEnd: onCardDragEnd
|
|
3144
3316
|
},
|
|
3145
3317
|
card.id
|
|
3146
3318
|
)),
|
|
@@ -3300,6 +3472,8 @@ function KanbanBoard({
|
|
|
3300
3472
|
laneAgentPicker,
|
|
3301
3473
|
scheduleStatus,
|
|
3302
3474
|
focusCardId,
|
|
3475
|
+
renderCardDrawer,
|
|
3476
|
+
enableDrag,
|
|
3303
3477
|
className
|
|
3304
3478
|
}) {
|
|
3305
3479
|
const {
|
|
@@ -3314,6 +3488,7 @@ function KanbanBoard({
|
|
|
3314
3488
|
createCard,
|
|
3315
3489
|
updateCard,
|
|
3316
3490
|
transitionCard,
|
|
3491
|
+
deleteCard,
|
|
3317
3492
|
handleRunTerminal
|
|
3318
3493
|
} = useKanbanBoard({ adapter, onError, onCardCreated, pollIntervalMs });
|
|
3319
3494
|
const lastFocusedRef = useRef(void 0);
|
|
@@ -3358,6 +3533,44 @@ function KanbanBoard({
|
|
|
3358
3533
|
(cardId, toLane) => transitionCard({ cardId, targetLane: toLane }),
|
|
3359
3534
|
[transitionCard]
|
|
3360
3535
|
);
|
|
3536
|
+
const [dragging, setDragging] = useState(null);
|
|
3537
|
+
const draggingRef = useRef(null);
|
|
3538
|
+
const dropInFlightRef = useRef(null);
|
|
3539
|
+
const allowedDropLanes = useMemo(() => {
|
|
3540
|
+
if (!dragging || !board?.transitions) return /* @__PURE__ */ new Set();
|
|
3541
|
+
return new Set(
|
|
3542
|
+
board.transitions.filter((t) => t.fromLane === dragging.lane && t.manualAllowed).map((t) => t.toLane)
|
|
3543
|
+
);
|
|
3544
|
+
}, [dragging, board?.transitions]);
|
|
3545
|
+
const handleCardDragStart = useCallback((card) => {
|
|
3546
|
+
const d = { id: card.id, lane: card.lane };
|
|
3547
|
+
draggingRef.current = d;
|
|
3548
|
+
setDragging(d);
|
|
3549
|
+
}, []);
|
|
3550
|
+
const handleCardDragEnd = useCallback(() => {
|
|
3551
|
+
draggingRef.current = null;
|
|
3552
|
+
setDragging(null);
|
|
3553
|
+
}, []);
|
|
3554
|
+
const handleLaneDrop = useCallback(
|
|
3555
|
+
(lane) => {
|
|
3556
|
+
const cur = draggingRef.current;
|
|
3557
|
+
draggingRef.current = null;
|
|
3558
|
+
setDragging(null);
|
|
3559
|
+
if (!cur || lane.key === cur.lane) return;
|
|
3560
|
+
if (dropInFlightRef.current === cur.id) return;
|
|
3561
|
+
const allowed = (board?.transitions ?? []).some(
|
|
3562
|
+
(t) => t.fromLane === cur.lane && t.toLane === lane.key && t.manualAllowed
|
|
3563
|
+
);
|
|
3564
|
+
if (!allowed) return;
|
|
3565
|
+
dropInFlightRef.current = cur.id;
|
|
3566
|
+
void Promise.resolve(transitionCard({ cardId: cur.id, targetLane: lane.key })).finally(
|
|
3567
|
+
() => {
|
|
3568
|
+
if (dropInFlightRef.current === cur.id) dropInFlightRef.current = null;
|
|
3569
|
+
}
|
|
3570
|
+
);
|
|
3571
|
+
},
|
|
3572
|
+
[board?.transitions, transitionCard]
|
|
3573
|
+
);
|
|
3361
3574
|
const initialLaneKey = lanes.find((l) => !l.terminal)?.key ?? lanes[0]?.key;
|
|
3362
3575
|
const selectedLane = selectedCard ? lanes.find((l) => l.key === selectedCard.lane) : void 0;
|
|
3363
3576
|
const canAdvanceSelected = !!selectedLane && !selectedLane.terminal;
|
|
@@ -3378,12 +3591,32 @@ function KanbanBoard({
|
|
|
3378
3591
|
showCreate: enableCreate && lane.key === initialLaneKey,
|
|
3379
3592
|
count: laneCounts?.[lane.key],
|
|
3380
3593
|
agentPicker: laneAgentPicker?.(lane),
|
|
3381
|
-
canEditHandlers
|
|
3594
|
+
canEditHandlers,
|
|
3595
|
+
draggableCards: enableDrag && enableAdvance,
|
|
3596
|
+
dragActive: !!dragging,
|
|
3597
|
+
dropAllowed: !!dragging && dragging.lane !== lane.key && allowedDropLanes.has(lane.key),
|
|
3598
|
+
onCardDragStart: handleCardDragStart,
|
|
3599
|
+
onCardDragEnd: handleCardDragEnd,
|
|
3600
|
+
onLaneDrop: handleLaneDrop
|
|
3382
3601
|
},
|
|
3383
3602
|
lane.id ?? lane.key
|
|
3384
3603
|
))
|
|
3385
3604
|
] }),
|
|
3386
|
-
selectedCard &&
|
|
3605
|
+
selectedCard && (renderCardDrawer ? renderCardDrawer({
|
|
3606
|
+
card: selectedCard,
|
|
3607
|
+
adapter,
|
|
3608
|
+
lanes,
|
|
3609
|
+
transitions: enableAdvance ? board?.transitions : void 0,
|
|
3610
|
+
canAdvance: canAdvanceSelected,
|
|
3611
|
+
onClose: closeCard,
|
|
3612
|
+
onRetry: onRetryCard ? handleRetry : void 0,
|
|
3613
|
+
onUpdate: enableEdit ? handleUpdate : void 0,
|
|
3614
|
+
onAdvance: enableAdvance ? handleAdvance : void 0,
|
|
3615
|
+
onTransition: enableAdvance ? handleTransition : void 0,
|
|
3616
|
+
onDelete: adapter.deleteCard ? deleteCard : void 0,
|
|
3617
|
+
onRunTerminal: handleRunTerminal,
|
|
3618
|
+
onError
|
|
3619
|
+
}) : /* @__PURE__ */ jsx(
|
|
3387
3620
|
CardDrawer,
|
|
3388
3621
|
{
|
|
3389
3622
|
card: selectedCard,
|
|
@@ -3399,7 +3632,7 @@ function KanbanBoard({
|
|
|
3399
3632
|
onRunTerminal: handleRunTerminal,
|
|
3400
3633
|
onError
|
|
3401
3634
|
}
|
|
3402
|
-
)
|
|
3635
|
+
))
|
|
3403
3636
|
] })
|
|
3404
3637
|
] });
|
|
3405
3638
|
}
|
|
@@ -3424,6 +3657,7 @@ function composeAdapter(source, boardConfigUuid, version, cardSource) {
|
|
|
3424
3657
|
transitionCard(input) {
|
|
3425
3658
|
return cardSource.transitionCard(input);
|
|
3426
3659
|
},
|
|
3660
|
+
...cardSource.deleteCard ? { deleteCard: (id) => cardSource.deleteCard(id) } : {},
|
|
3427
3661
|
...cardSource.createRunStream ? { createRunStream: (id) => cardSource.createRunStream(id) } : {}
|
|
3428
3662
|
};
|
|
3429
3663
|
}
|
|
@@ -4797,7 +5031,6 @@ var AgentsAPI = class extends BaseResourceAPI {
|
|
|
4797
5031
|
super(http, "/api/v1/agents");
|
|
4798
5032
|
this.getStreamConfig = getStreamConfig;
|
|
4799
5033
|
}
|
|
4800
|
-
getStreamConfig;
|
|
4801
5034
|
// ===== LIST Operations =====
|
|
4802
5035
|
/**
|
|
4803
5036
|
* List all agents in the organization
|
|
@@ -5703,7 +5936,6 @@ var SessionsAPI = class extends BaseResourceAPI {
|
|
|
5703
5936
|
super(http, "/api/v1/sessions");
|
|
5704
5937
|
this.getStreamConfig = getStreamConfig;
|
|
5705
5938
|
}
|
|
5706
|
-
getStreamConfig;
|
|
5707
5939
|
// ===== LIST Operations =====
|
|
5708
5940
|
/**
|
|
5709
5941
|
* List all sessions in the organization
|
|
@@ -6023,7 +6255,6 @@ var KanbanAPI = class extends BaseResourceAPI {
|
|
|
6023
6255
|
super(http, "/api/v1/kanban");
|
|
6024
6256
|
this.getStreamConfig = getStreamConfig;
|
|
6025
6257
|
}
|
|
6026
|
-
getStreamConfig;
|
|
6027
6258
|
// ===== BOARD =====
|
|
6028
6259
|
/**
|
|
6029
6260
|
* Get the current org's board (lanes in declared order). Auto-provisions
|
|
@@ -6225,7 +6456,6 @@ var RemoteAgentsAPI = class extends BaseResourceAPI {
|
|
|
6225
6456
|
super(http, "/api/v1/remote-agents");
|
|
6226
6457
|
this.getStreamConfig = getStreamConfig;
|
|
6227
6458
|
}
|
|
6228
|
-
getStreamConfig;
|
|
6229
6459
|
/**
|
|
6230
6460
|
* List all remote agents in the organization
|
|
6231
6461
|
*
|