@mndrk/agx 2.4.2 → 2.4.4
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/cloud-runtime/standalone/apps/local/.next/BUILD_ID +1 -1
- package/cloud-runtime/standalone/apps/local/.next/app-path-routes-manifest.json +5 -0
- package/cloud-runtime/standalone/apps/local/.next/build-manifest.json +2 -2
- package/cloud-runtime/standalone/apps/local/.next/prerender-manifest.json +3 -3
- package/cloud-runtime/standalone/apps/local/.next/routes-manifest.json +41 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents/[id]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents/[id]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.rsc +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/_full.segment.rsc +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/agents/__PAGE__.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/agents.segments/agents.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/agent-specs/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/agents/[id]/profile/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/agents/export/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/chat/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/file-search/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/participants/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/projects/[id]/objectives/[objectiveId]/scheduled-tasks/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/projects/[id]/objectives/[objectiveId]/worker/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/projects/[id]/search/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/projects/[id]/teams/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/prompt-jobs/poll/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/providers/check/[id]/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/providers/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/queue/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/schedules/debug/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/schedules/poll/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/skills/assign/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/skills/available/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/skills/detail/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/skills/history/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/skills/learn/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/skills/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/skills/unlearn/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/status/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/summarize/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/tasks/[id]/comments/[commentId]/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/tasks/[id]/comments/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/tasks/[id]/nodes/[nodeId]/comments/route.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/tasks/[id]/nodes/[nodeId]/comments/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/tasks/[id]/nodes/[nodeId]/verify/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/tasks/[id]/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/tasks/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/threads/knowledge/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/threads/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/auth/route.js +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/auth/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/callback/route.js +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/callback/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/groups/route.js +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/groups/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/items/[id]/activity/route.js +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/items/[id]/activity/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/items/[id]/recap/route.js +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/items/[id]/recap/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/items/[id]/route.js +4 -4
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/items/[id]/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/items/route.js +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/items/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/labels/[id]/route/app-paths-manifest.json +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/labels/[id]/route/build-manifest.json +11 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/labels/[id]/route/server-reference-manifest.json +4 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/labels/[id]/route.js +7 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/labels/[id]/route.js.map +5 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/labels/[id]/route.js.nft.json +1 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/labels/[id]/route_client-reference-manifest.js +2 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/labels/route/app-paths-manifest.json +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/labels/route/build-manifest.json +11 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/labels/route/server-reference-manifest.json +4 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/labels/route.js +7 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/labels/route.js.map +5 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/labels/route.js.nft.json +1 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/labels/route_client-reference-manifest.js +2 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/mcp-setup/route.js +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/mcp-setup/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/metadata/bulk/route/app-paths-manifest.json +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/metadata/bulk/route/build-manifest.json +11 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/metadata/bulk/route/server-reference-manifest.json +4 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/metadata/bulk/route.js +7 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/metadata/bulk/route.js.map +5 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/metadata/bulk/route.js.nft.json +1 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/metadata/bulk/route_client-reference-manifest.js +2 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/metadata/route/app-paths-manifest.json +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/metadata/route/build-manifest.json +11 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/metadata/route/server-reference-manifest.json +4 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/metadata/route.js +7 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/metadata/route.js.map +5 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/metadata/route.js.nft.json +1 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/metadata/route_client-reference-manifest.js +2 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/options/route.js +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/options/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/runs/[id]/route.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/runs/[id]/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/runs/route.js +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/runs/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/runs/scripted/route.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/runs/scripted/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/stats/route/app-paths-manifest.json +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/stats/route/build-manifest.json +11 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/stats/route/server-reference-manifest.json +4 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/stats/route.js +7 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/stats/route.js.map +5 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/stats/route.js.nft.json +1 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/stats/route_client-reference-manifest.js +2 -0
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/status/route.js +4 -4
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/status/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/token/route.js +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/token/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/token-receive/route.js +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/token-receive/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/worker/route.js +6 -6
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/[tracker]/worker/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/connections/route.js +7 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/trackers/connections/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/api/update-check/route.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.segments/_full.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/automations/page/react-loadable-manifest.json +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/automations/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/automations/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/env-vars/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/env-vars/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/folders/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/folders/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/graph/[taskId]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/graph/[taskId]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/objectives/[objectiveId]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/objectives/[objectiveId]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/objectives/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/objectives/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/[teamId]/agents/[agentId]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/[teamId]/agents/[agentId]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/[teamId]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/[teamId]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/adopt/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/adopt/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/new/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/new/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/replace/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/teams/replace/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/terminal/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/terminal/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/thread/[threadId]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/thread/[threadId]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/[tracker]/page/react-loadable-manifest.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/[tracker]/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/[tracker]/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/connect/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/connect/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/page/react-loadable-manifest.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/page.js.nft.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/[slug]/tracking/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/_full.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/projects/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/projects.segments/projects.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/_full.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/setup/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/setup.segments/setup.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/status/page_client-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/_full.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/_head.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/_index.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/_tree.segment.rsc +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/status/__PAGE__.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app/status.segments/status.segment.rsc +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/app-paths-manifest.json +5 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/083c9_next-internal_server_app_api_trackers_[tracker]_metadata_route_actions_c83fcc1a.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/30bdd_server_app_api_trackers_[tracker]_labels_[id]_route_actions_2646388d.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/30bdd_server_app_api_trackers_[tracker]_metadata_bulk_route_actions_f43e6831.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__0e04eca4._.js +40 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__0fbbaf2d._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__10a90219._.js +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__1d970ad0._.js +40 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/{[root-of-the-server]__2ab23e45._.js → [root-of-the-server]__2eb13697._.js} +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__3a038592._.js +3 -3
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__3b27260f._.js +23 -8
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__498d8b2d._.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__580ddcca._.js +40 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__5da8d281._.js +129 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__68b692c4._.js +9 -9
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__76030d44._.js +40 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__7db7c421._.js +20 -5
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__7fcbb0c2._.js +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__ba72d342._.js +5 -5
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__d8cc43c7._.js +22 -7
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__f598d976._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__f7a936d9._.js +21 -6
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/apps_local_1a4cb196._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/apps_local_5e5f36c4._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/apps_local_8f9f647d._.js +28 -13
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/apps_local_9f0fd451._.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/apps_local_d256aa32._.js +28 -25
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/apps_local_e1f4d9ad._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/apps_local_f8b3abae._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/apps_local_lib_orchestrator_chat-processor_ts_46384f36._.js +12 -12
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/apps_local_lib_tracker_tracker-run-store_ts_5aa9592e._.js +22 -7
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ebff2__next-internal_server_app_api_trackers_[tracker]_labels_route_actions_8ba41152.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ebff2__next-internal_server_app_api_trackers_[tracker]_stats_route_actions_7da4ccde.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/{[root-of-the-server]__799f4d13._.js → [root-of-the-server]__2af44092._.js} +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__452cb0f0._.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__489568b4._.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__4ec098a0._.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__53bd50df._.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__7774a40c._.js +3 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__b8484b0e._.js +7 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/{[root-of-the-server]__51edc9b6._.js → [root-of-the-server]__bd05ee09._.js} +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/_8c4beba9._.js +7 -0
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_5eebb5cb._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/{apps_local_35d90b5d._.js → apps_local_bbb7b83b._.js} +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_components_TrackerBoard_tsx_98970bab._.js +6 -6
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_components_chat-ui_f0554cb4._.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/apps_local_components_projects_ProjectObjectivesWorkspace_tsx_751ab3d3._.js +7 -7
- package/cloud-runtime/standalone/apps/local/.next/server/functions-config-manifest.json +5 -0
- package/cloud-runtime/standalone/apps/local/.next/server/middleware-manifest.json +5 -5
- package/cloud-runtime/standalone/apps/local/.next/server/pages/404.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/pages/500.html +2 -2
- package/cloud-runtime/standalone/apps/local/.next/server/server-reference-manifest.js +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/server-reference-manifest.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/0243e7d015db440d.js +5 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/42a62b80b32a97f7.js +9 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/5d047fc7267a8f53.js +16 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/7148feb61274d431.css +1 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/716e1716d526ded9.js +46 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/{77cea126364aab3c.js → 7353a3a1fcd5825c.js} +1 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/8b91e7692a899f00.js +20 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/9acdd370e9daca0d.js +16 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/{6c777fe66e042eec.js → 9df45611d6c84e02.js} +1 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/{6c278ae4535b6d5c.js → 9e2208153f276f8c.js} +1 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/a084c6475513e6fe.js +16 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/aa6db7c91c1ccd5f.js +16 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/d5607ac80145f3b7.js +1 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/d590384ce3045a12.js +5 -0
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/{d5b14e14665024a9.js → d5c307b52fd87861.js} +1 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/f4acf76cb6c82c73.js +16 -0
- package/cloud-runtime/standalone/apps/local/app/api/trackers/[tracker]/labels/[id]/route.ts +23 -0
- package/cloud-runtime/standalone/apps/local/app/api/trackers/[tracker]/labels/route.ts +41 -0
- package/cloud-runtime/standalone/apps/local/app/api/trackers/[tracker]/metadata/bulk/route.ts +68 -0
- package/cloud-runtime/standalone/apps/local/app/api/trackers/[tracker]/metadata/route.ts +31 -0
- package/cloud-runtime/standalone/apps/local/app/api/trackers/[tracker]/options/route.ts +1 -0
- package/cloud-runtime/standalone/apps/local/app/api/trackers/[tracker]/stats/route.ts +20 -0
- package/cloud-runtime/standalone/apps/local/app/api/trackers/connections/route.ts +46 -2
- package/cloud-runtime/standalone/apps/local/app/projects/[slug]/tracking/connect/page.tsx +41 -11
- package/cloud-runtime/standalone/apps/local/components/TrackerBoard.tsx +609 -85
- package/cloud-runtime/standalone/apps/local/components/projects/ProjectObjectivesWorkspace.tsx +204 -49
- package/cloud-runtime/standalone/apps/local/components/tracker/FibonacciPicker.tsx +41 -0
- package/cloud-runtime/standalone/apps/local/components/tracker/FolderRow.tsx +1 -1
- package/cloud-runtime/standalone/apps/local/components/tracker/LabelPicker.tsx +118 -0
- package/cloud-runtime/standalone/apps/local/components/tracker/LabelSettings.tsx +104 -0
- package/cloud-runtime/standalone/apps/local/components/tracker/PromptPopover.tsx +64 -0
- package/cloud-runtime/standalone/apps/local/components/tracker/SelectionBar.tsx +276 -23
- package/cloud-runtime/standalone/apps/local/components/tracker/StatusGroupRow.tsx +50 -0
- package/cloud-runtime/standalone/apps/local/components/tracker/TicketPanel.tsx +14 -2
- package/cloud-runtime/standalone/apps/local/components/tracker/TicketRow.tsx +147 -7
- package/cloud-runtime/standalone/apps/local/components/tracker/TrackerSettingsModal.tsx +14 -2
- package/cloud-runtime/standalone/apps/local/components/ui/ResizeHandle.tsx +15 -22
- package/cloud-runtime/standalone/apps/local/hooks/useTrackerConnections.ts +29 -1
- package/cloud-runtime/standalone/apps/local/hooks/useTrackerIssueStats.ts +52 -0
- package/cloud-runtime/standalone/apps/local/hooks/useTrackerItemMetadata.ts +67 -0
- package/cloud-runtime/standalone/apps/local/hooks/useTrackerItemsMetadata.ts +51 -0
- package/cloud-runtime/standalone/apps/local/hooks/useTrackerLabels.ts +74 -0
- package/cloud-runtime/standalone/apps/local/hooks/useTrackerRuns.ts +5 -0
- package/cloud-runtime/standalone/apps/local/lib/agent-process-registry.ts +8 -2
- package/cloud-runtime/standalone/apps/local/lib/tracker/adapters/jira/adapter.tsx +1 -0
- package/cloud-runtime/standalone/apps/local/lib/tracker/adapters/jira/issues.ts +1 -0
- package/cloud-runtime/standalone/apps/local/lib/tracker/adapters/linear/adapter.tsx +1 -0
- package/cloud-runtime/standalone/apps/local/lib/tracker/adapters/linear/client.ts +5 -0
- package/cloud-runtime/standalone/apps/local/lib/tracker/adapters/linear/issues.ts +1 -0
- package/cloud-runtime/standalone/apps/local/lib/tracker/connections.ts +46 -15
- package/cloud-runtime/standalone/apps/local/lib/tracker/tracker-adapter.ts +2 -0
- package/cloud-runtime/standalone/apps/local/lib/tracker/tracker-item-metadata-store.ts +262 -0
- package/cloud-runtime/standalone/apps/local/lib/tracker/tracker-item-store.ts +10 -3
- package/cloud-runtime/standalone/apps/local/lib/tracker/tracker-run-store.ts +42 -0
- package/cloud-runtime/standalone/apps/local/src/prompt-scheduler/objective-worker.ts +7 -0
- package/cloud-runtime/standalone/apps/local/src/prompt-scheduler/task-worker.ts +7 -0
- package/cloud-runtime/standalone/apps/local/state/trackerBoardFilters.ts +4 -0
- package/cloud-runtime/standalone/apps/local/worker/index.js +6 -2
- package/package.json +1 -1
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/[root-of-the-server]__847236fb._.js +0 -3
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/apps_local_80b34b78._.js +0 -3
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__30bf097e._.js +0 -3
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__46ae9d33._.js +0 -3
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__50fd8680._.js +0 -3
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__8059a285._.js +0 -3
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__886953ec._.js +0 -7
- package/cloud-runtime/standalone/apps/local/.next/server/chunks/ssr/[root-of-the-server]__97160565._.js +0 -3
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/0876dfd6ce07abaf.js +0 -9
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/1ec83777a9abd420.js +0 -16
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/286758b0fd546c68.js +0 -16
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/a72ed5cb3feb0d51.js +0 -5
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/b02c180ad1d968eb.js +0 -16
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/b048a4812b51f97a.js +0 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/c63d97c917d96f47.js +0 -46
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/d3bf70e2fbdc0ae5.js +0 -5
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/dd5a56eea2d4c067.js +0 -16
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/dd7d7c382389b8b9.js +0 -16
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/e72724fd8225ec39.js +0 -20
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/ec92e3bd6c2db6e6.css +0 -1
- package/cloud-runtime/standalone/apps/local/.next/static/chunks/ffcc32453866d0c2.js +0 -1
- /package/cloud-runtime/standalone/apps/local/.next/static/{QEldoF1LdgJqO0PgpmUmx → 3-6VaSnGGXdV-2eV44RDK}/_buildManifest.js +0 -0
- /package/cloud-runtime/standalone/apps/local/.next/static/{QEldoF1LdgJqO0PgpmUmx → 3-6VaSnGGXdV-2eV44RDK}/_clientMiddlewareManifest.json +0 -0
- /package/cloud-runtime/standalone/apps/local/.next/static/{QEldoF1LdgJqO0PgpmUmx → 3-6VaSnGGXdV-2eV44RDK}/_ssgManifest.js +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
import React, { useCallback, useDeferredValue, useEffect, useMemo, useRef, useState } from "react";
|
|
4
4
|
import dynamic from "next/dynamic";
|
|
5
|
-
import { ArrowDown, ArrowUp, ChevronLeft, Clock, FileText, Play, Plus, RefreshCw, Search, Settings, User, X } from "lucide-react";
|
|
5
|
+
import { ArrowDown, ArrowUp, ChevronDown, ChevronLeft, ChevronRight, Clock, FileText, Play, Plus, RefreshCw, Search, Settings, User, X } from "lucide-react";
|
|
6
6
|
import { useUrlSelection } from "@/hooks/useUrlSelection";
|
|
7
7
|
import { useTrackerItems } from "@/hooks/useTrackerItems";
|
|
8
8
|
import type { TrackerItem, TrackerStatusCategory } from "@/lib/tracker/types";
|
|
@@ -56,12 +56,16 @@ import { TicketRow } from "@/components/tracker/TicketRow";
|
|
|
56
56
|
import { TicketPanel } from "@/components/tracker/TicketPanel";
|
|
57
57
|
import { useTrackerParticipants } from "@/hooks/useTrackerParticipants";
|
|
58
58
|
import { useTrackerActiveAgents } from "@/hooks/useTrackerActiveAgents";
|
|
59
|
+
import { useTrackerIssueStats } from "@/hooks/useTrackerIssueStats";
|
|
59
60
|
import { agentAvatarUrl } from "@/lib/tracker-board-utils";
|
|
60
61
|
import { useTaskGroups, type TaskGroup } from "@/hooks/useTaskGroups";
|
|
61
62
|
import { FolderRow } from "@/components/tracker/FolderRow";
|
|
62
63
|
import { GroupPanel } from "@/components/tracker/GroupPanel";
|
|
63
64
|
import { GroupNamePrompt, PENDING_GROUP_DROP_ID } from "@/components/tracker/GroupNamePrompt";
|
|
65
|
+
import { StatusGroupRow, STATUS_GROUP_PREFIX } from "@/components/tracker/StatusGroupRow";
|
|
64
66
|
import { SelectionBar } from "@/components/tracker/SelectionBar";
|
|
67
|
+
import { useTrackerItemsMetadata } from "@/hooks/useTrackerItemsMetadata";
|
|
68
|
+
import { useTrackerLabels } from "@/hooks/useTrackerLabels";
|
|
65
69
|
import {
|
|
66
70
|
DndContext,
|
|
67
71
|
DragOverlay,
|
|
@@ -89,6 +93,13 @@ function formatRunTime(iso: string): string {
|
|
|
89
93
|
});
|
|
90
94
|
}
|
|
91
95
|
|
|
96
|
+
const STATUS_CATEGORY_COLORS: Record<string, string> = {
|
|
97
|
+
todo: "bg-zinc-400",
|
|
98
|
+
in_progress: "bg-amber-400",
|
|
99
|
+
done: "bg-emerald-400",
|
|
100
|
+
cancelled: "bg-red-400",
|
|
101
|
+
};
|
|
102
|
+
|
|
92
103
|
interface GroupOption {
|
|
93
104
|
id: string;
|
|
94
105
|
name: string;
|
|
@@ -405,16 +416,20 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
405
416
|
const [selectedAssigneeIds, setSelectedAssigneeIds] = useState<string[]>([]);
|
|
406
417
|
const [selectedStatusCategories, setSelectedStatusCategories] = useState<string[]>([]);
|
|
407
418
|
const [groups, setGroups] = useState<GroupOption[]>([]);
|
|
419
|
+
const [groupLabel, setGroupLabel] = useState("Group");
|
|
408
420
|
const [selectedGroupId, setSelectedGroupId] = useState("");
|
|
409
421
|
const [selectedWorkspaceId, setSelectedWorkspaceId] = useState("");
|
|
410
422
|
const [sortBy, setSortBy] = useState<"activity" | "identifier" | "status" | "created">("activity");
|
|
411
423
|
const [sortDir, setSortDir] = useState<"asc" | "desc">("desc");
|
|
412
|
-
const [
|
|
424
|
+
const [selectedLabelNames, setSelectedLabelNames] = useState<string[]>([]);
|
|
413
425
|
const [pinnedItemIds, setPinnedItemIds] = useState<Set<string>>(() => loadPinnedTrackerItemIds(trackerType, projectSlug));
|
|
414
426
|
const [selectedItemFallback, setSelectedItemFallback] = useState<TrackerItem | null>(null);
|
|
415
427
|
const [updatingItemId, setUpdatingItemId] = useState<string | null>(null);
|
|
428
|
+
const [collapsedStatusGroups, setCollapsedStatusGroups] = useState<Set<string>>(new Set());
|
|
429
|
+
const groupByStatus = true;
|
|
416
430
|
const { participants } = useTrackerParticipants(trackerType, projectId);
|
|
417
431
|
const { issueActiveAgents } = useTrackerActiveAgents(trackerType, projectId);
|
|
432
|
+
const { issueStats } = useTrackerIssueStats(trackerType, projectId);
|
|
418
433
|
const [pickerItem, setPickerItem] = useState<TrackerItem | null>(null);
|
|
419
434
|
const [pickerAnchor, setPickerAnchor] = useState<{ top: number; left: number } | null>(null);
|
|
420
435
|
const [touchPanelTab, setTouchPanelTab] = useState<"runs" | "ticket">("runs");
|
|
@@ -480,6 +495,10 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
480
495
|
// hoisting issues (sortedItems is declared further down).
|
|
481
496
|
const sortedItemsRef = useRef<TrackerItem[]>([]);
|
|
482
497
|
|
|
498
|
+
// Ref to handleItemStatusChange so handleDragEnd can access it without
|
|
499
|
+
// hoisting issues (handleItemStatusChange is declared further down).
|
|
500
|
+
const handleItemStatusChangeRef = useRef<((item: TrackerItem, status: string, statusCategory?: TrackerStatusCategory) => Promise<void>) | null>(null);
|
|
501
|
+
|
|
483
502
|
const handleMultiSelectGroup = useCallback(() => {
|
|
484
503
|
const ids = Array.from(multiSelectedItemIds);
|
|
485
504
|
// Find the topmost selected item in the sorted list to position the prompt
|
|
@@ -550,6 +569,25 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
550
569
|
if (!over || active.id === over.id) return;
|
|
551
570
|
const overId = over.id as string;
|
|
552
571
|
|
|
572
|
+
// Dropped on a status group header → change status upstream
|
|
573
|
+
if (overId.startsWith(STATUS_GROUP_PREFIX)) {
|
|
574
|
+
const targetStatus = overId.slice(STATUS_GROUP_PREFIX.length);
|
|
575
|
+
const activeItem = sortedItemsRef.current.find((i) => i.id === activeItemId);
|
|
576
|
+
const targetCategory = sortedItemsRef.current.find((i) => i.status === targetStatus)?.statusCategory;
|
|
577
|
+
if (activeItem && activeItem.status !== targetStatus) {
|
|
578
|
+
await handleItemStatusChangeRef.current?.(activeItem, targetStatus, targetCategory);
|
|
579
|
+
}
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
// Dropped on a ticket in a different status group → change status
|
|
584
|
+
const activeItem = sortedItemsRef.current.find((i) => i.id === activeItemId);
|
|
585
|
+
const overItem = sortedItemsRef.current.find((i) => i.id === overId);
|
|
586
|
+
if (activeItem && overItem && activeItem.status !== overItem.status) {
|
|
587
|
+
await handleItemStatusChangeRef.current?.(activeItem, overItem.status, overItem.statusCategory);
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
|
|
553
591
|
// Check if dropping on a folder
|
|
554
592
|
const targetGroup = taskGroups.find((g) => g.id === overId);
|
|
555
593
|
if (targetGroup) {
|
|
@@ -616,7 +654,7 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
616
654
|
setSelectedGroupId(storedFilters.groupIds?.[0] ?? "");
|
|
617
655
|
setSortBy(storedFilters.sortBy);
|
|
618
656
|
setSortDir(storedFilters.sortDir);
|
|
619
|
-
|
|
657
|
+
setSelectedLabelNames(storedFilters.labelNames ?? []);
|
|
620
658
|
setPinnedItemIds(loadPinnedTrackerItemIds(trackerType, projectSlug));
|
|
621
659
|
}, [trackerType, projectSlug]);
|
|
622
660
|
|
|
@@ -631,11 +669,12 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
631
669
|
assigneeIds: selectedAssigneeIds,
|
|
632
670
|
statusCategories: selectedStatusCategories,
|
|
633
671
|
groupIds: selectedGroupId ? [selectedGroupId] : [],
|
|
672
|
+
labelNames: selectedLabelNames,
|
|
634
673
|
sortBy,
|
|
635
674
|
sortDir,
|
|
636
|
-
hasActivity,
|
|
675
|
+
hasActivity: false,
|
|
637
676
|
});
|
|
638
|
-
}, [trackerType, projectSlug, search, selectedAssigneeIds, selectedStatusCategories, selectedWorkspaceId, selectedGroupId, sortBy, sortDir
|
|
677
|
+
}, [trackerType, projectSlug, search, selectedAssigneeIds, selectedStatusCategories, selectedWorkspaceId, selectedGroupId, selectedLabelNames, sortBy, sortDir]);
|
|
639
678
|
|
|
640
679
|
// Fetch filter options when connected
|
|
641
680
|
useEffect(() => {
|
|
@@ -657,7 +696,8 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
657
696
|
setAssignees(Array.isArray(data.assignees) ? data.assignees : []);
|
|
658
697
|
setStatusCategories(Array.isArray(data.statuses) ? data.statuses.map((s: { name: string; category: string }) => ({ value: s.name, label: s.name })) : []);
|
|
659
698
|
setWorkspaces(Array.isArray(data.teams) ? data.teams : []);
|
|
660
|
-
setGroups(Array.isArray(data.
|
|
699
|
+
setGroups(Array.isArray(data.groups) ? data.groups : []);
|
|
700
|
+
if (data.groupLabel) setGroupLabel(data.groupLabel);
|
|
661
701
|
setFilterOptionsLoaded(true);
|
|
662
702
|
})
|
|
663
703
|
.catch(() => {
|
|
@@ -731,9 +771,8 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
731
771
|
groupIds: selectedGroupId ? [selectedGroupId] : undefined,
|
|
732
772
|
sortBy,
|
|
733
773
|
sortDir,
|
|
734
|
-
hasActivity: hasActivity || undefined,
|
|
735
774
|
}),
|
|
736
|
-
[debouncedSearch, selectedAssigneeIds, selectedGroupId, selectedStatusCategories, statusCategories.length, sortBy, sortDir
|
|
775
|
+
[debouncedSearch, selectedAssigneeIds, selectedGroupId, selectedStatusCategories, statusCategories.length, sortBy, sortDir]
|
|
737
776
|
);
|
|
738
777
|
|
|
739
778
|
const {
|
|
@@ -746,6 +785,22 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
746
785
|
} = useTrackerItems(trackerType, filters, connected && filterOptionsLoaded && Boolean(projectId), {
|
|
747
786
|
projectId: projectId ?? "",
|
|
748
787
|
});
|
|
788
|
+
|
|
789
|
+
// Bulk metadata for visible items
|
|
790
|
+
const visibleIssueIds = useMemo(() => items.map((item) => item.id), [items]);
|
|
791
|
+
const {
|
|
792
|
+
metadataMap,
|
|
793
|
+
refresh: refreshMetadata,
|
|
794
|
+
} = useTrackerItemsMetadata(trackerType, projectId, visibleIssueIds);
|
|
795
|
+
|
|
796
|
+
// Labels
|
|
797
|
+
const {
|
|
798
|
+
labels: allLabels,
|
|
799
|
+
definitions: labelDefinitions,
|
|
800
|
+
refresh: refreshLabels,
|
|
801
|
+
createDefinition: createLabelDefinition,
|
|
802
|
+
} = useTrackerLabels(trackerType, projectId);
|
|
803
|
+
|
|
749
804
|
const selectedItemFromList = useMemo(
|
|
750
805
|
() => (selectedItemId ? items.find((item) => item.id === selectedItemId) ?? null : null),
|
|
751
806
|
[items, selectedItemId],
|
|
@@ -769,9 +824,45 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
769
824
|
}, [items, pinnedItemIds]);
|
|
770
825
|
sortedItemsRef.current = sortedItems;
|
|
771
826
|
|
|
827
|
+
const deferredLabelNames = useDeferredValue(selectedLabelNames);
|
|
828
|
+
const labelFilteredItems = useMemo(() => {
|
|
829
|
+
if (deferredLabelNames.length === 0) return sortedItems;
|
|
830
|
+
const filterSet = new Set(deferredLabelNames);
|
|
831
|
+
const result: TrackerItem[] = [];
|
|
832
|
+
for (const item of sortedItems) {
|
|
833
|
+
const labels = metadataMap.get(item.id)?.labels;
|
|
834
|
+
if (!labels) continue;
|
|
835
|
+
for (const l of labels) {
|
|
836
|
+
if (filterSet.has(l)) {
|
|
837
|
+
result.push(item);
|
|
838
|
+
break;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
return result;
|
|
843
|
+
}, [sortedItems, deferredLabelNames, metadataMap]);
|
|
844
|
+
|
|
845
|
+
const statusGroups = useMemo(() => {
|
|
846
|
+
if (!groupByStatus) return [];
|
|
847
|
+
const map = new Map<string, { status: string; category: TrackerStatusCategory; items: TrackerItem[] }>();
|
|
848
|
+
for (const item of labelFilteredItems) {
|
|
849
|
+
let group = map.get(item.status);
|
|
850
|
+
if (!group) {
|
|
851
|
+
group = { status: item.status, category: item.statusCategory, items: [] };
|
|
852
|
+
map.set(item.status, group);
|
|
853
|
+
}
|
|
854
|
+
group.items.push(item);
|
|
855
|
+
}
|
|
856
|
+
const categoryOrder: Record<string, number> = { in_progress: 0, todo: 1, done: 2, cancelled: 3 };
|
|
857
|
+
return [...map.values()].sort(
|
|
858
|
+
(a, b) => (categoryOrder[a.category] ?? 1) - (categoryOrder[b.category] ?? 1)
|
|
859
|
+
);
|
|
860
|
+
}, [groupByStatus, labelFilteredItems]);
|
|
861
|
+
|
|
772
862
|
const {
|
|
773
863
|
runs,
|
|
774
864
|
loading: runsLoading,
|
|
865
|
+
loadedForIssueId: runsLoadedForIssueId,
|
|
775
866
|
createRun,
|
|
776
867
|
updateRun,
|
|
777
868
|
} = useTrackerRuns(trackerType, selectedItem?.id ?? null, projectId ?? null);
|
|
@@ -815,26 +906,64 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
815
906
|
);
|
|
816
907
|
const groupOptions = useMemo<FilterOption[]>(
|
|
817
908
|
() => [
|
|
818
|
-
{ value: "", label:
|
|
909
|
+
{ value: "", label: groupLabel },
|
|
819
910
|
...groups.map((group) => ({
|
|
820
911
|
value: group.id,
|
|
821
912
|
label: group.name,
|
|
822
913
|
})),
|
|
823
914
|
],
|
|
824
|
-
[groups]
|
|
915
|
+
[groups, groupLabel]
|
|
825
916
|
);
|
|
826
917
|
const showStatusFilter = statusOptions.length > 0;
|
|
827
918
|
const showGroupFilter = groupOptions.length > 1;
|
|
828
919
|
const showWorkspaceFilter = workspaceOptions.length > 2;
|
|
829
920
|
const activeSessionScriptLabel = activeScript?.name ?? "AGX default";
|
|
830
921
|
|
|
922
|
+
const labelFilterOptions = useMemo<FilterOption[]>(
|
|
923
|
+
() => allLabels.map((l) => ({ value: l.name, label: l.name })),
|
|
924
|
+
[allLabels]
|
|
925
|
+
);
|
|
926
|
+
|
|
927
|
+
const handleItemToggleLabel = useCallback(async (itemId: string, label: string) => {
|
|
928
|
+
if (!projectId) return;
|
|
929
|
+
const current = metadataMap.get(itemId)?.labels ?? [];
|
|
930
|
+
const has = current.includes(label);
|
|
931
|
+
const next = has ? current.filter((l) => l !== label) : [...current, label];
|
|
932
|
+
try {
|
|
933
|
+
await fetch(`/api/trackers/${trackerType}/metadata?projectId=${encodeURIComponent(projectId)}&issueId=${encodeURIComponent(itemId)}`, {
|
|
934
|
+
method: "PATCH",
|
|
935
|
+
headers: { "Content-Type": "application/json" },
|
|
936
|
+
body: JSON.stringify({ labels: next }),
|
|
937
|
+
});
|
|
938
|
+
void refreshMetadata();
|
|
939
|
+
void refreshLabels();
|
|
940
|
+
} catch {}
|
|
941
|
+
}, [projectId, trackerType, metadataMap, refreshMetadata, refreshLabels]);
|
|
942
|
+
|
|
943
|
+
const handleItemAddLabel = useCallback(async (name: string) => {
|
|
944
|
+
if (!projectId) return;
|
|
945
|
+
await createLabelDefinition(name);
|
|
946
|
+
}, [projectId, createLabelDefinition]);
|
|
947
|
+
|
|
831
948
|
const handleItemStatusChange = useCallback(
|
|
832
|
-
async (item: TrackerItem, status: string) => {
|
|
949
|
+
async (item: TrackerItem, status: string, statusCategory?: TrackerStatusCategory) => {
|
|
833
950
|
const nextStatus = status.trim();
|
|
834
951
|
if (!nextStatus || nextStatus === item.status || !projectId) {
|
|
835
952
|
return;
|
|
836
953
|
}
|
|
837
954
|
|
|
955
|
+
// Optimistic update — move the ticket to the new status immediately so
|
|
956
|
+
// the UI reflects the drop before the PATCH round-trip completes.
|
|
957
|
+
const optimisticItem: TrackerItem = {
|
|
958
|
+
...item,
|
|
959
|
+
status: nextStatus,
|
|
960
|
+
statusCategory: statusCategory ?? item.statusCategory,
|
|
961
|
+
};
|
|
962
|
+
updateItem(optimisticItem);
|
|
963
|
+
if (selectedItemId === item.id) {
|
|
964
|
+
setSelectedItemFallback(optimisticItem);
|
|
965
|
+
}
|
|
966
|
+
|
|
838
967
|
setUpdatingItemId(item.id);
|
|
839
968
|
try {
|
|
840
969
|
const response = await fetch(
|
|
@@ -861,6 +990,11 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
861
990
|
}
|
|
862
991
|
await refreshItems();
|
|
863
992
|
} catch (error) {
|
|
993
|
+
// Revert optimistic update on failure.
|
|
994
|
+
updateItem(item);
|
|
995
|
+
if (selectedItemId === item.id) {
|
|
996
|
+
setSelectedItemFallback(item);
|
|
997
|
+
}
|
|
864
998
|
if (error instanceof Error) {
|
|
865
999
|
window.alert(error.message);
|
|
866
1000
|
}
|
|
@@ -871,6 +1005,161 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
871
1005
|
[refreshItems, selectedItemId, updateItem, trackerType, projectId]
|
|
872
1006
|
);
|
|
873
1007
|
|
|
1008
|
+
// Update the ref whenever the callback changes
|
|
1009
|
+
handleItemStatusChangeRef.current = handleItemStatusChange;
|
|
1010
|
+
|
|
1011
|
+
const handleBulkRecap = useCallback(async () => {
|
|
1012
|
+
const ids = Array.from(multiSelectedItemIds);
|
|
1013
|
+
const selectedItems = ids
|
|
1014
|
+
.map((id) => items.find((item) => item.id === id))
|
|
1015
|
+
.filter(Boolean) as TrackerItem[];
|
|
1016
|
+
|
|
1017
|
+
if (selectedItems.length === 0 || participants.length === 0) return;
|
|
1018
|
+
const agent = participants[0];
|
|
1019
|
+
|
|
1020
|
+
for (const item of selectedItems) {
|
|
1021
|
+
try {
|
|
1022
|
+
await fetch(`/api/trackers/${trackerType}/runs/scripted`, {
|
|
1023
|
+
method: "POST",
|
|
1024
|
+
headers: { "Content-Type": "application/json" },
|
|
1025
|
+
body: JSON.stringify({
|
|
1026
|
+
projectId: projectId ?? undefined,
|
|
1027
|
+
projectSlug: projectSlug ?? undefined,
|
|
1028
|
+
issueId: item.id,
|
|
1029
|
+
issueIdentifier: item.identifier,
|
|
1030
|
+
issueTitle: item.title,
|
|
1031
|
+
issueStatus: item.status,
|
|
1032
|
+
issueAssignee: item.assignee?.name ?? null,
|
|
1033
|
+
agentId: agent.id,
|
|
1034
|
+
scriptName: "Recap",
|
|
1035
|
+
scriptPrompt: "Summarize recent activity and current state of this ticket. Focus on: what was done, what's outstanding, and any blockers.",
|
|
1036
|
+
}),
|
|
1037
|
+
});
|
|
1038
|
+
} catch (err) {
|
|
1039
|
+
console.error(`Failed to start recap for ${item.identifier}:`, err);
|
|
1040
|
+
}
|
|
1041
|
+
}
|
|
1042
|
+
setMultiSelectedItemIds(new Set());
|
|
1043
|
+
}, [multiSelectedItemIds, items, participants, trackerType, projectId, projectSlug]);
|
|
1044
|
+
|
|
1045
|
+
const handleBulkPrompt = useCallback(async (prompt: string, agentId: string) => {
|
|
1046
|
+
const ids = Array.from(multiSelectedItemIds);
|
|
1047
|
+
const selectedItems = ids
|
|
1048
|
+
.map((id) => items.find((item) => item.id === id))
|
|
1049
|
+
.filter(Boolean) as TrackerItem[];
|
|
1050
|
+
|
|
1051
|
+
for (const item of selectedItems) {
|
|
1052
|
+
try {
|
|
1053
|
+
await fetch(`/api/trackers/${trackerType}/runs/scripted`, {
|
|
1054
|
+
method: "POST",
|
|
1055
|
+
headers: { "Content-Type": "application/json" },
|
|
1056
|
+
body: JSON.stringify({
|
|
1057
|
+
projectId: projectId ?? undefined,
|
|
1058
|
+
projectSlug: projectSlug ?? undefined,
|
|
1059
|
+
issueId: item.id,
|
|
1060
|
+
issueIdentifier: item.identifier,
|
|
1061
|
+
issueTitle: item.title,
|
|
1062
|
+
issueStatus: item.status,
|
|
1063
|
+
issueAssignee: item.assignee?.name ?? null,
|
|
1064
|
+
agentId,
|
|
1065
|
+
scriptPrompt: prompt,
|
|
1066
|
+
}),
|
|
1067
|
+
});
|
|
1068
|
+
} catch (err) {
|
|
1069
|
+
console.error(`Failed to send prompt for ${item.identifier}:`, err);
|
|
1070
|
+
}
|
|
1071
|
+
}
|
|
1072
|
+
setMultiSelectedItemIds(new Set());
|
|
1073
|
+
}, [multiSelectedItemIds, items, trackerType, projectId, projectSlug]);
|
|
1074
|
+
|
|
1075
|
+
const handleBulkEstimate = useCallback(async (estimate: number | null) => {
|
|
1076
|
+
const ids = Array.from(multiSelectedItemIds);
|
|
1077
|
+
if (ids.length === 0 || !projectId) return;
|
|
1078
|
+
try {
|
|
1079
|
+
await fetch(`/api/trackers/${trackerType}/metadata/bulk`, {
|
|
1080
|
+
method: "POST",
|
|
1081
|
+
headers: { "Content-Type": "application/json" },
|
|
1082
|
+
body: JSON.stringify({
|
|
1083
|
+
projectId,
|
|
1084
|
+
issueIds: ids,
|
|
1085
|
+
action: "set_estimate",
|
|
1086
|
+
payload: { estimate },
|
|
1087
|
+
}),
|
|
1088
|
+
});
|
|
1089
|
+
void refreshMetadata();
|
|
1090
|
+
} catch {}
|
|
1091
|
+
setMultiSelectedItemIds(new Set());
|
|
1092
|
+
}, [multiSelectedItemIds, projectId, trackerType, refreshMetadata]);
|
|
1093
|
+
|
|
1094
|
+
const handleBulkAddLabel = useCallback(async (label: string) => {
|
|
1095
|
+
const ids = Array.from(multiSelectedItemIds);
|
|
1096
|
+
if (ids.length === 0 || !projectId) return;
|
|
1097
|
+
try {
|
|
1098
|
+
await fetch(`/api/trackers/${trackerType}/metadata/bulk`, {
|
|
1099
|
+
method: "POST",
|
|
1100
|
+
headers: { "Content-Type": "application/json" },
|
|
1101
|
+
body: JSON.stringify({
|
|
1102
|
+
projectId,
|
|
1103
|
+
issueIds: ids,
|
|
1104
|
+
action: "add_labels",
|
|
1105
|
+
payload: { labels: [label] },
|
|
1106
|
+
}),
|
|
1107
|
+
});
|
|
1108
|
+
void refreshMetadata();
|
|
1109
|
+
void refreshLabels();
|
|
1110
|
+
} catch {}
|
|
1111
|
+
}, [multiSelectedItemIds, projectId, trackerType, refreshMetadata, refreshLabels]);
|
|
1112
|
+
|
|
1113
|
+
const handleBulkRemoveLabel = useCallback(async (label: string) => {
|
|
1114
|
+
const ids = Array.from(multiSelectedItemIds);
|
|
1115
|
+
if (ids.length === 0 || !projectId) return;
|
|
1116
|
+
try {
|
|
1117
|
+
await fetch(`/api/trackers/${trackerType}/metadata/bulk`, {
|
|
1118
|
+
method: "POST",
|
|
1119
|
+
headers: { "Content-Type": "application/json" },
|
|
1120
|
+
body: JSON.stringify({
|
|
1121
|
+
projectId,
|
|
1122
|
+
issueIds: ids,
|
|
1123
|
+
action: "remove_label",
|
|
1124
|
+
payload: { label },
|
|
1125
|
+
}),
|
|
1126
|
+
});
|
|
1127
|
+
void refreshMetadata();
|
|
1128
|
+
void refreshLabels();
|
|
1129
|
+
} catch {}
|
|
1130
|
+
}, [multiSelectedItemIds, projectId, trackerType, refreshMetadata, refreshLabels]);
|
|
1131
|
+
|
|
1132
|
+
const [bulkStatusUpdating, setBulkStatusUpdating] = useState(false);
|
|
1133
|
+
|
|
1134
|
+
const handleBulkStatus = useCallback(async (status: string) => {
|
|
1135
|
+
const ids = Array.from(multiSelectedItemIds);
|
|
1136
|
+
const selectedItems = ids
|
|
1137
|
+
.map((id) => items.find((item) => item.id === id))
|
|
1138
|
+
.filter(Boolean) as TrackerItem[];
|
|
1139
|
+
|
|
1140
|
+
if (selectedItems.length === 0) return;
|
|
1141
|
+
setBulkStatusUpdating(true);
|
|
1142
|
+
for (const item of selectedItems) {
|
|
1143
|
+
await handleItemStatusChange(item, status);
|
|
1144
|
+
}
|
|
1145
|
+
setBulkStatusUpdating(false);
|
|
1146
|
+
setMultiSelectedItemIds(new Set());
|
|
1147
|
+
}, [multiSelectedItemIds, items, handleItemStatusChange]);
|
|
1148
|
+
|
|
1149
|
+
const handleCreateLabel = useCallback(async (name: string) => {
|
|
1150
|
+
if (!projectId) return;
|
|
1151
|
+
await createLabelDefinition(name);
|
|
1152
|
+
}, [projectId, createLabelDefinition]);
|
|
1153
|
+
|
|
1154
|
+
const selectedMetadata = useMemo(() => {
|
|
1155
|
+
const map = new Map<string, { labels: string[]; estimate: number | null }>();
|
|
1156
|
+
for (const id of multiSelectedItemIds) {
|
|
1157
|
+
const meta = metadataMap.get(id);
|
|
1158
|
+
map.set(id, meta ?? { labels: [], estimate: null });
|
|
1159
|
+
}
|
|
1160
|
+
return map;
|
|
1161
|
+
}, [multiSelectedItemIds, metadataMap]);
|
|
1162
|
+
|
|
874
1163
|
useEffect(() => {
|
|
875
1164
|
if (!selectedItemId || !projectId) {
|
|
876
1165
|
setSelectedItemFallback(null);
|
|
@@ -948,12 +1237,12 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
948
1237
|
}, [selectedItemId, selectedRunId]);
|
|
949
1238
|
|
|
950
1239
|
useEffect(() => {
|
|
951
|
-
if (!isAwaitingRestore || runsLoading ||
|
|
1240
|
+
if (!isAwaitingRestore || runsLoading || runsLoadedForIssueId !== selectedItemId) return;
|
|
952
1241
|
lastRestoredItemRef.current = selectedItemId;
|
|
953
1242
|
if (storedRunId && runs.some((r) => r.id === storedRunId)) {
|
|
954
1243
|
replaceSelection({ run: storedRunId });
|
|
955
1244
|
}
|
|
956
|
-
}, [isAwaitingRestore, storedRunId, selectedItemId, runs, runsLoading, replaceSelection]);
|
|
1245
|
+
}, [isAwaitingRestore, storedRunId, selectedItemId, runs, runsLoading, runsLoadedForIssueId, replaceSelection]);
|
|
957
1246
|
|
|
958
1247
|
useEffect(() => {
|
|
959
1248
|
if (!isTouchLayout) {
|
|
@@ -1156,6 +1445,16 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1156
1445
|
onChange={setSelectedAssigneeIds}
|
|
1157
1446
|
emptyLabel="All assignees"
|
|
1158
1447
|
/>
|
|
1448
|
+
{labelFilterOptions.length > 0 && (
|
|
1449
|
+
<MultiFilterPopdown
|
|
1450
|
+
label="Label"
|
|
1451
|
+
values={selectedLabelNames}
|
|
1452
|
+
options={labelFilterOptions}
|
|
1453
|
+
activeClasses="border-pink-500/30 bg-pink-500/10 text-pink-400"
|
|
1454
|
+
onChange={setSelectedLabelNames}
|
|
1455
|
+
emptyLabel="All labels"
|
|
1456
|
+
/>
|
|
1457
|
+
)}
|
|
1159
1458
|
{showWorkspaceFilter ? (
|
|
1160
1459
|
<FilterSelect
|
|
1161
1460
|
label="Workspace"
|
|
@@ -1167,7 +1466,7 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1167
1466
|
) : null}
|
|
1168
1467
|
{showGroupFilter ? (
|
|
1169
1468
|
<FilterSelect
|
|
1170
|
-
label=
|
|
1469
|
+
label={groupLabel}
|
|
1171
1470
|
value={selectedGroupId}
|
|
1172
1471
|
options={groupOptions}
|
|
1173
1472
|
activeClasses="border-purple-500/30 bg-purple-500/10 text-purple-400"
|
|
@@ -1178,10 +1477,10 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1178
1477
|
label="Sort"
|
|
1179
1478
|
value={sortBy}
|
|
1180
1479
|
options={[
|
|
1181
|
-
{ value: "activity", label: "
|
|
1480
|
+
{ value: "activity", label: "Updated At" },
|
|
1182
1481
|
{ value: "identifier", label: "Ticket ID" },
|
|
1183
1482
|
{ value: "status", label: "Status" },
|
|
1184
|
-
{ value: "created", label: "Created" },
|
|
1483
|
+
{ value: "created", label: "Created At" },
|
|
1185
1484
|
]}
|
|
1186
1485
|
activeClasses="border-sky-500/30 bg-sky-500/10 text-sky-400"
|
|
1187
1486
|
onChange={(value) => setSortBy(value as typeof sortBy)}
|
|
@@ -1194,17 +1493,6 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1194
1493
|
>
|
|
1195
1494
|
{sortDir === "desc" ? <ArrowDown size={12} /> : <ArrowUp size={12} />}
|
|
1196
1495
|
</button>
|
|
1197
|
-
<button
|
|
1198
|
-
type="button"
|
|
1199
|
-
className={`flex items-center gap-1 rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors ${
|
|
1200
|
-
hasActivity
|
|
1201
|
-
? "border-orange-500/30 bg-orange-500/10 text-orange-400"
|
|
1202
|
-
: "border-[var(--card-border)] text-[var(--muted-foreground)] hover:bg-[var(--card-bg)]"
|
|
1203
|
-
}`}
|
|
1204
|
-
onClick={() => setHasActivity((v) => !v)}
|
|
1205
|
-
>
|
|
1206
|
-
My activity
|
|
1207
|
-
</button>
|
|
1208
1496
|
</div>
|
|
1209
1497
|
</div>
|
|
1210
1498
|
|
|
@@ -1219,31 +1507,90 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1219
1507
|
</div>
|
|
1220
1508
|
) : (
|
|
1221
1509
|
<>
|
|
1222
|
-
{
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
<
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1510
|
+
{groupByStatus ? (
|
|
1511
|
+
statusGroups.map((sg) => {
|
|
1512
|
+
const collapsed = collapsedStatusGroups.has(sg.status);
|
|
1513
|
+
return (
|
|
1514
|
+
<React.Fragment key={`sg-${sg.status}`}>
|
|
1515
|
+
<StatusGroupRow
|
|
1516
|
+
status={sg.status}
|
|
1517
|
+
categoryColor={STATUS_CATEGORY_COLORS[sg.category] ?? "bg-zinc-400"}
|
|
1518
|
+
count={sg.items.length}
|
|
1519
|
+
collapsed={collapsed}
|
|
1520
|
+
onToggle={() =>
|
|
1521
|
+
setCollapsedStatusGroups((prev) => {
|
|
1522
|
+
const next = new Set(prev);
|
|
1523
|
+
if (next.has(sg.status)) next.delete(sg.status);
|
|
1524
|
+
else next.add(sg.status);
|
|
1525
|
+
return next;
|
|
1526
|
+
})
|
|
1527
|
+
}
|
|
1528
|
+
/>
|
|
1529
|
+
{!collapsed &&
|
|
1530
|
+
sg.items.map((item) => (
|
|
1531
|
+
<TicketRow
|
|
1532
|
+
key={item.id}
|
|
1533
|
+
item={item}
|
|
1534
|
+
selected={selectedItem?.id === item.id}
|
|
1535
|
+
pinned={pinnedItemIds.has(item.id)}
|
|
1536
|
+
activeAgents={issueActiveAgents.get(item.id)}
|
|
1537
|
+
participants={participants}
|
|
1538
|
+
projectSlug={projectSlug}
|
|
1539
|
+
stats={issueStats.get(item.id)}
|
|
1540
|
+
hideStatus
|
|
1541
|
+
estimate={metadataMap.get(item.id)?.estimate}
|
|
1542
|
+
localLabels={metadataMap.get(item.id)?.labels}
|
|
1543
|
+
labelDefinitions={labelDefinitions}
|
|
1544
|
+
allLabels={allLabels}
|
|
1545
|
+
onToggleLabel={(label) => handleItemToggleLabel(item.id, label)}
|
|
1546
|
+
onAddLabel={handleItemAddLabel}
|
|
1547
|
+
onSelect={() => {
|
|
1548
|
+
setTouchPanelTab("runs");
|
|
1549
|
+
pushSelection({
|
|
1550
|
+
issue: item.id,
|
|
1551
|
+
run: null,
|
|
1552
|
+
});
|
|
1553
|
+
}}
|
|
1554
|
+
onTogglePin={() => togglePin(item.id)}
|
|
1555
|
+
/>
|
|
1556
|
+
))}
|
|
1557
|
+
</React.Fragment>
|
|
1558
|
+
);
|
|
1559
|
+
})
|
|
1560
|
+
) : (
|
|
1561
|
+
labelFilteredItems.map((item, idx) => (
|
|
1562
|
+
<React.Fragment key={item.id}>
|
|
1563
|
+
{pinnedItemIds.size > 0 &&
|
|
1564
|
+
!pinnedItemIds.has(item.id) &&
|
|
1565
|
+
(idx === 0 || pinnedItemIds.has(labelFilteredItems[idx - 1].id)) && (
|
|
1566
|
+
<div className="mx-4 border-t border-amber-500/20" />
|
|
1567
|
+
)}
|
|
1568
|
+
<TicketRow
|
|
1569
|
+
item={item}
|
|
1570
|
+
selected={selectedItem?.id === item.id}
|
|
1571
|
+
pinned={pinnedItemIds.has(item.id)}
|
|
1572
|
+
activeAgents={issueActiveAgents.get(item.id)}
|
|
1573
|
+
participants={participants}
|
|
1574
|
+
projectSlug={projectSlug}
|
|
1575
|
+
stats={issueStats.get(item.id)}
|
|
1576
|
+
estimate={metadataMap.get(item.id)?.estimate}
|
|
1577
|
+
localLabels={metadataMap.get(item.id)?.labels}
|
|
1578
|
+
labelDefinitions={labelDefinitions}
|
|
1579
|
+
allLabels={allLabels}
|
|
1580
|
+
onToggleLabel={(label) => handleItemToggleLabel(item.id, label)}
|
|
1581
|
+
onAddLabel={handleItemAddLabel}
|
|
1582
|
+
onSelect={() => {
|
|
1583
|
+
setTouchPanelTab("runs");
|
|
1584
|
+
pushSelection({
|
|
1585
|
+
issue: item.id,
|
|
1586
|
+
run: null,
|
|
1587
|
+
});
|
|
1588
|
+
}}
|
|
1589
|
+
onTogglePin={() => togglePin(item.id)}
|
|
1590
|
+
/>
|
|
1591
|
+
</React.Fragment>
|
|
1592
|
+
))
|
|
1593
|
+
)}
|
|
1247
1594
|
{hasMore ? (
|
|
1248
1595
|
<div
|
|
1249
1596
|
ref={sentinelRef}
|
|
@@ -1488,6 +1835,16 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1488
1835
|
onChange={setSelectedAssigneeIds}
|
|
1489
1836
|
emptyLabel="All assignees"
|
|
1490
1837
|
/>
|
|
1838
|
+
{labelFilterOptions.length > 0 && (
|
|
1839
|
+
<MultiFilterPopdown
|
|
1840
|
+
label="Label"
|
|
1841
|
+
values={selectedLabelNames}
|
|
1842
|
+
options={labelFilterOptions}
|
|
1843
|
+
activeClasses="border-pink-500/30 bg-pink-500/10 text-pink-400"
|
|
1844
|
+
onChange={setSelectedLabelNames}
|
|
1845
|
+
emptyLabel="All labels"
|
|
1846
|
+
/>
|
|
1847
|
+
)}
|
|
1491
1848
|
{showWorkspaceFilter ? (
|
|
1492
1849
|
<FilterSelect
|
|
1493
1850
|
label="Workspace"
|
|
@@ -1499,7 +1856,7 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1499
1856
|
) : null}
|
|
1500
1857
|
{showGroupFilter ? (
|
|
1501
1858
|
<FilterSelect
|
|
1502
|
-
label=
|
|
1859
|
+
label={groupLabel}
|
|
1503
1860
|
value={selectedGroupId}
|
|
1504
1861
|
options={groupOptions}
|
|
1505
1862
|
activeClasses="border-purple-500/30 bg-purple-500/10 text-purple-400"
|
|
@@ -1510,10 +1867,10 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1510
1867
|
label="Sort"
|
|
1511
1868
|
value={sortBy}
|
|
1512
1869
|
options={[
|
|
1513
|
-
{ value: "activity", label: "
|
|
1870
|
+
{ value: "activity", label: "Updated At" },
|
|
1514
1871
|
{ value: "identifier", label: "Ticket ID" },
|
|
1515
1872
|
{ value: "status", label: "Status" },
|
|
1516
|
-
{ value: "created", label: "Created" },
|
|
1873
|
+
{ value: "created", label: "Created At" },
|
|
1517
1874
|
]}
|
|
1518
1875
|
activeClasses="border-sky-500/30 bg-sky-500/10 text-sky-400"
|
|
1519
1876
|
onChange={(value) => setSortBy(value as typeof sortBy)}
|
|
@@ -1526,17 +1883,6 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1526
1883
|
>
|
|
1527
1884
|
{sortDir === "desc" ? <ArrowDown size={12} /> : <ArrowUp size={12} />}
|
|
1528
1885
|
</button>
|
|
1529
|
-
<button
|
|
1530
|
-
type="button"
|
|
1531
|
-
className={`flex items-center gap-1 rounded-full border px-2.5 py-0.5 text-[11px] font-medium transition-colors ${
|
|
1532
|
-
hasActivity
|
|
1533
|
-
? "border-orange-500/30 bg-orange-500/10 text-orange-400"
|
|
1534
|
-
: "border-[var(--card-border)] text-[var(--muted-foreground)] hover:bg-[var(--card-bg)]"
|
|
1535
|
-
}`}
|
|
1536
|
-
onClick={() => setHasActivity((v) => !v)}
|
|
1537
|
-
>
|
|
1538
|
-
My activity
|
|
1539
|
-
</button>
|
|
1540
1886
|
</div>
|
|
1541
1887
|
</div>
|
|
1542
1888
|
|
|
@@ -1557,33 +1903,188 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1557
1903
|
</div>
|
|
1558
1904
|
) : (
|
|
1559
1905
|
<>
|
|
1560
|
-
{
|
|
1561
|
-
|
|
1906
|
+
{groupByStatus ? (
|
|
1907
|
+
/* ── Status-grouped view ── */
|
|
1908
|
+
statusGroups.map((sg) => {
|
|
1909
|
+
const collapsed = collapsedStatusGroups.has(sg.status);
|
|
1910
|
+
return (
|
|
1911
|
+
<React.Fragment key={`sg-${sg.status}`}>
|
|
1912
|
+
<StatusGroupRow
|
|
1913
|
+
status={sg.status}
|
|
1914
|
+
categoryColor={STATUS_CATEGORY_COLORS[sg.category] ?? "bg-zinc-400"}
|
|
1915
|
+
count={sg.items.length}
|
|
1916
|
+
collapsed={collapsed}
|
|
1917
|
+
onToggle={() =>
|
|
1918
|
+
setCollapsedStatusGroups((prev) => {
|
|
1919
|
+
const next = new Set(prev);
|
|
1920
|
+
if (next.has(sg.status)) next.delete(sg.status);
|
|
1921
|
+
else next.add(sg.status);
|
|
1922
|
+
return next;
|
|
1923
|
+
})
|
|
1924
|
+
}
|
|
1925
|
+
/>
|
|
1926
|
+
{!collapsed && (() => {
|
|
1927
|
+
const pendingSet = showGroupNamePrompt ? new Set(pendingGroupTaskIds) : null;
|
|
1928
|
+
const firstMemberToGroup = new Map<string, typeof taskGroups[number]>();
|
|
1929
|
+
for (const group of taskGroups) {
|
|
1930
|
+
const firstInStatus = sg.items.find((i) => group.task_ids.includes(i.id));
|
|
1931
|
+
if (firstInStatus) firstMemberToGroup.set(firstInStatus.id, group);
|
|
1932
|
+
}
|
|
1933
|
+
const pendingTickets = showGroupNamePrompt
|
|
1934
|
+
? pendingGroupTaskIds
|
|
1935
|
+
.map((id) => sg.items.find((i) => i.id === id))
|
|
1936
|
+
.filter(Boolean)
|
|
1937
|
+
.map((i) => ({ id: i!.id, identifier: i!.identifier, title: i!.title, status: STATUS_LABELS[i!.status] ?? i!.status }))
|
|
1938
|
+
: [];
|
|
1939
|
+
const renderedGroups = new Set<string>();
|
|
1940
|
+
|
|
1941
|
+
return sg.items.map((item) => {
|
|
1942
|
+
if (pendingSet?.has(item.id)) {
|
|
1943
|
+
if (item.id === pendingGroupTargetId && showGroupNamePrompt) {
|
|
1944
|
+
return (
|
|
1945
|
+
<GroupNamePrompt
|
|
1946
|
+
key="__pending-group__"
|
|
1947
|
+
tickets={pendingTickets}
|
|
1948
|
+
onConfirm={handleCreateGroup}
|
|
1949
|
+
onCancel={() => {
|
|
1950
|
+
setShowGroupNamePrompt(false);
|
|
1951
|
+
setPendingGroupTaskIds([]);
|
|
1952
|
+
setPendingGroupTargetId(null);
|
|
1953
|
+
}}
|
|
1954
|
+
/>
|
|
1955
|
+
);
|
|
1956
|
+
}
|
|
1957
|
+
return null;
|
|
1958
|
+
}
|
|
1959
|
+
|
|
1960
|
+
const group = firstMemberToGroup.get(item.id);
|
|
1961
|
+
if (group && !renderedGroups.has(group.id)) {
|
|
1962
|
+
renderedGroups.add(group.id);
|
|
1963
|
+
const groupItems = group.task_ids
|
|
1964
|
+
.map((id) => sg.items.find((i) => i.id === id))
|
|
1965
|
+
.filter(Boolean) as TrackerItem[];
|
|
1966
|
+
return (
|
|
1967
|
+
<React.Fragment key={`group-${group.id}`}>
|
|
1968
|
+
<FolderRow
|
|
1969
|
+
groupId={group.id}
|
|
1970
|
+
name={group.name}
|
|
1971
|
+
count={groupItems.length}
|
|
1972
|
+
collapsed={!!group.collapsed}
|
|
1973
|
+
selected={selectedGroupTaskGroupId === group.id}
|
|
1974
|
+
projectSlug={projectSlug}
|
|
1975
|
+
onToggleCollapse={() => updateGroup(group.id, { collapsed: !group.collapsed })}
|
|
1976
|
+
onSelect={() => pushSelection({ group: group.id, issue: null, run: null })}
|
|
1977
|
+
onUngroup={() => {
|
|
1978
|
+
void deleteGroup(group.id);
|
|
1979
|
+
if (selectedGroupTaskGroupId === group.id) {
|
|
1980
|
+
replaceSelection({ group: null });
|
|
1981
|
+
}
|
|
1982
|
+
}}
|
|
1983
|
+
/>
|
|
1984
|
+
{!group.collapsed &&
|
|
1985
|
+
groupItems.map((gi, giIdx) => (
|
|
1986
|
+
<TicketRow
|
|
1987
|
+
key={gi.id}
|
|
1988
|
+
item={gi}
|
|
1989
|
+
selected={selectedItem?.id === gi.id}
|
|
1990
|
+
pinned={pinnedItemIds.has(gi.id)}
|
|
1991
|
+
activeAgents={issueActiveAgents.get(gi.id)}
|
|
1992
|
+
participants={participants}
|
|
1993
|
+
draggable
|
|
1994
|
+
multiSelected={multiSelectedItemIds.has(gi.id)}
|
|
1995
|
+
treeConnector={giIdx === groupItems.length - 1 ? "last" : "mid"}
|
|
1996
|
+
projectSlug={projectSlug}
|
|
1997
|
+
stats={issueStats.get(gi.id)}
|
|
1998
|
+
hideStatus
|
|
1999
|
+
estimate={metadataMap.get(gi.id)?.estimate}
|
|
2000
|
+
localLabels={metadataMap.get(gi.id)?.labels}
|
|
2001
|
+
labelDefinitions={labelDefinitions}
|
|
2002
|
+
allLabels={allLabels}
|
|
2003
|
+
onToggleLabel={(label) => handleItemToggleLabel(gi.id, label)}
|
|
2004
|
+
onAddLabel={handleItemAddLabel}
|
|
2005
|
+
onSelect={(event) => {
|
|
2006
|
+
if (event && (event.metaKey || event.ctrlKey)) {
|
|
2007
|
+
toggleItemMultiSelect(gi.id);
|
|
2008
|
+
} else {
|
|
2009
|
+
pushSelection({
|
|
2010
|
+
issue: gi.id,
|
|
2011
|
+
run: null,
|
|
2012
|
+
group: null,
|
|
2013
|
+
});
|
|
2014
|
+
}
|
|
2015
|
+
}}
|
|
2016
|
+
onTogglePin={() => togglePin(gi.id)}
|
|
2017
|
+
/>
|
|
2018
|
+
))}
|
|
2019
|
+
</React.Fragment>
|
|
2020
|
+
);
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2023
|
+
if (groupedItemIds.has(item.id)) {
|
|
2024
|
+
return null;
|
|
2025
|
+
}
|
|
2026
|
+
|
|
2027
|
+
return (
|
|
2028
|
+
<TicketRow
|
|
2029
|
+
key={item.id}
|
|
2030
|
+
item={item}
|
|
2031
|
+
selected={selectedItem?.id === item.id}
|
|
2032
|
+
pinned={pinnedItemIds.has(item.id)}
|
|
2033
|
+
activeAgents={issueActiveAgents.get(item.id)}
|
|
2034
|
+
participants={participants}
|
|
2035
|
+
draggable
|
|
2036
|
+
multiSelected={multiSelectedItemIds.has(item.id)}
|
|
2037
|
+
projectSlug={projectSlug}
|
|
2038
|
+
stats={issueStats.get(item.id)}
|
|
2039
|
+
hideStatus
|
|
2040
|
+
estimate={metadataMap.get(item.id)?.estimate}
|
|
2041
|
+
localLabels={metadataMap.get(item.id)?.labels}
|
|
2042
|
+
labelDefinitions={labelDefinitions}
|
|
2043
|
+
allLabels={allLabels}
|
|
2044
|
+
onToggleLabel={(label) => handleItemToggleLabel(item.id, label)}
|
|
2045
|
+
onAddLabel={handleItemAddLabel}
|
|
2046
|
+
onSelect={(event) => {
|
|
2047
|
+
if (event && (event.metaKey || event.ctrlKey)) {
|
|
2048
|
+
toggleItemMultiSelect(item.id);
|
|
2049
|
+
} else {
|
|
2050
|
+
pushSelection({
|
|
2051
|
+
issue: item.id,
|
|
2052
|
+
run: null,
|
|
2053
|
+
group: null,
|
|
2054
|
+
});
|
|
2055
|
+
}
|
|
2056
|
+
}}
|
|
2057
|
+
onTogglePin={() => togglePin(item.id)}
|
|
2058
|
+
/>
|
|
2059
|
+
);
|
|
2060
|
+
});
|
|
2061
|
+
})()}
|
|
2062
|
+
</React.Fragment>
|
|
2063
|
+
);
|
|
2064
|
+
})
|
|
2065
|
+
) : (
|
|
2066
|
+
/* ── Flat/folder view ── */
|
|
2067
|
+
(() => {
|
|
1562
2068
|
const pendingSet = showGroupNamePrompt ? new Set(pendingGroupTaskIds) : null;
|
|
1563
2069
|
|
|
1564
|
-
// Build a map: itemId → group (for the first member of each group)
|
|
1565
2070
|
const firstMemberToGroup = new Map<string, typeof taskGroups[number]>();
|
|
1566
2071
|
for (const group of taskGroups) {
|
|
1567
|
-
const firstInSort =
|
|
2072
|
+
const firstInSort = labelFilteredItems.find((i) => group.task_ids.includes(i.id));
|
|
1568
2073
|
if (firstInSort) firstMemberToGroup.set(firstInSort.id, group);
|
|
1569
2074
|
}
|
|
1570
2075
|
|
|
1571
|
-
// Pending group prompt: find insert position
|
|
1572
2076
|
const pendingTickets = showGroupNamePrompt
|
|
1573
2077
|
? pendingGroupTaskIds
|
|
1574
|
-
.map((id) =>
|
|
2078
|
+
.map((id) => labelFilteredItems.find((i) => i.id === id))
|
|
1575
2079
|
.filter(Boolean)
|
|
1576
2080
|
.map((i) => ({ id: i!.id, identifier: i!.identifier, title: i!.title, status: STATUS_LABELS[i!.status] ?? i!.status }))
|
|
1577
2081
|
: [];
|
|
1578
2082
|
|
|
1579
|
-
// Track which groups we've rendered
|
|
1580
2083
|
const renderedGroups = new Set<string>();
|
|
1581
2084
|
let looseIdx = 0;
|
|
1582
2085
|
|
|
1583
|
-
return
|
|
1584
|
-
// Skip pending tickets
|
|
2086
|
+
return labelFilteredItems.map((item) => {
|
|
1585
2087
|
if (pendingSet?.has(item.id)) {
|
|
1586
|
-
// Render prompt at target position
|
|
1587
2088
|
if (item.id === pendingGroupTargetId && showGroupNamePrompt) {
|
|
1588
2089
|
return (
|
|
1589
2090
|
<GroupNamePrompt
|
|
@@ -1601,12 +2102,11 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1601
2102
|
return null;
|
|
1602
2103
|
}
|
|
1603
2104
|
|
|
1604
|
-
// If this item is the first member of a group, render the group here
|
|
1605
2105
|
const group = firstMemberToGroup.get(item.id);
|
|
1606
2106
|
if (group && !renderedGroups.has(group.id)) {
|
|
1607
2107
|
renderedGroups.add(group.id);
|
|
1608
2108
|
const groupItems = group.task_ids
|
|
1609
|
-
.map((id) =>
|
|
2109
|
+
.map((id) => labelFilteredItems.find((i) => i.id === id))
|
|
1610
2110
|
.filter(Boolean) as TrackerItem[];
|
|
1611
2111
|
return (
|
|
1612
2112
|
<React.Fragment key={`group-${group.id}`}>
|
|
@@ -1643,6 +2143,13 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1643
2143
|
multiSelected={multiSelectedItemIds.has(gi.id)}
|
|
1644
2144
|
treeConnector={giIdx === groupItems.length - 1 ? "last" : "mid"}
|
|
1645
2145
|
projectSlug={projectSlug}
|
|
2146
|
+
stats={issueStats.get(gi.id)}
|
|
2147
|
+
estimate={metadataMap.get(gi.id)?.estimate}
|
|
2148
|
+
localLabels={metadataMap.get(gi.id)?.labels}
|
|
2149
|
+
labelDefinitions={labelDefinitions}
|
|
2150
|
+
allLabels={allLabels}
|
|
2151
|
+
onToggleLabel={(label) => handleItemToggleLabel(gi.id, label)}
|
|
2152
|
+
onAddLabel={handleItemAddLabel}
|
|
1646
2153
|
onSelect={(event) => {
|
|
1647
2154
|
if (event && (event.metaKey || event.ctrlKey)) {
|
|
1648
2155
|
toggleItemMultiSelect(gi.id);
|
|
@@ -1661,13 +2168,11 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1661
2168
|
);
|
|
1662
2169
|
}
|
|
1663
2170
|
|
|
1664
|
-
// Skip grouped items (already rendered with their group)
|
|
1665
2171
|
if (groupedItemIds.has(item.id)) return null;
|
|
1666
2172
|
|
|
1667
|
-
// Loose ticket
|
|
1668
2173
|
const currentLooseIdx = looseIdx++;
|
|
1669
2174
|
const prevLoose = currentLooseIdx > 0
|
|
1670
|
-
?
|
|
2175
|
+
? labelFilteredItems.filter((i) => !groupedItemIds.has(i.id) && (!pendingSet || !pendingSet.has(i.id)))[currentLooseIdx - 1]
|
|
1671
2176
|
: null;
|
|
1672
2177
|
return (
|
|
1673
2178
|
<React.Fragment key={item.id}>
|
|
@@ -1685,6 +2190,13 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1685
2190
|
draggable
|
|
1686
2191
|
multiSelected={multiSelectedItemIds.has(item.id)}
|
|
1687
2192
|
projectSlug={projectSlug}
|
|
2193
|
+
stats={issueStats.get(item.id)}
|
|
2194
|
+
estimate={metadataMap.get(item.id)?.estimate}
|
|
2195
|
+
localLabels={metadataMap.get(item.id)?.labels}
|
|
2196
|
+
labelDefinitions={labelDefinitions}
|
|
2197
|
+
allLabels={allLabels}
|
|
2198
|
+
onToggleLabel={(label) => handleItemToggleLabel(item.id, label)}
|
|
2199
|
+
onAddLabel={handleItemAddLabel}
|
|
1688
2200
|
onSelect={(event) => {
|
|
1689
2201
|
if (event && (event.metaKey || event.ctrlKey)) {
|
|
1690
2202
|
toggleItemMultiSelect(item.id);
|
|
@@ -1701,7 +2213,7 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1701
2213
|
</React.Fragment>
|
|
1702
2214
|
);
|
|
1703
2215
|
});
|
|
1704
|
-
})()}
|
|
2216
|
+
})())}
|
|
1705
2217
|
{hasMore ? (
|
|
1706
2218
|
<div
|
|
1707
2219
|
ref={sentinelRef}
|
|
@@ -1716,11 +2228,23 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1716
2228
|
count={multiSelectedItemIds.size}
|
|
1717
2229
|
onGroup={handleMultiSelectGroup}
|
|
1718
2230
|
onClear={() => setMultiSelectedItemIds(new Set())}
|
|
2231
|
+
onBulkRecap={handleBulkRecap}
|
|
2232
|
+
onBulkPrompt={handleBulkPrompt}
|
|
2233
|
+
onBulkEstimate={handleBulkEstimate}
|
|
2234
|
+
onBulkAddLabel={handleBulkAddLabel}
|
|
2235
|
+
onBulkRemoveLabel={handleBulkRemoveLabel}
|
|
2236
|
+
onBulkStatus={handleBulkStatus}
|
|
2237
|
+
statusOptions={itemStatusOptions}
|
|
2238
|
+
participants={participants}
|
|
2239
|
+
labels={allLabels}
|
|
2240
|
+
onCreateLabel={handleCreateLabel}
|
|
2241
|
+
selectedMetadata={selectedMetadata}
|
|
2242
|
+
statusUpdating={bulkStatusUpdating}
|
|
1719
2243
|
/>
|
|
1720
2244
|
</div>
|
|
1721
2245
|
<DragOverlay dropAnimation={null}>
|
|
1722
2246
|
{dragActiveId && (() => {
|
|
1723
|
-
const dragItem =
|
|
2247
|
+
const dragItem = sortedItemsRef.current.find((i) => i.id === dragActiveId);
|
|
1724
2248
|
if (!dragItem) return null;
|
|
1725
2249
|
return (
|
|
1726
2250
|
<div className="flex items-center gap-3 rounded-lg border border-[var(--primary)]/30 bg-[var(--card-bg)] px-4 py-2.5 text-sm shadow-xl backdrop-blur-sm">
|
|
@@ -1737,7 +2261,7 @@ export default function TrackerBoard({ trackerType, projectId, projectSlug, init
|
|
|
1737
2261
|
</DndContext>
|
|
1738
2262
|
</div>
|
|
1739
2263
|
|
|
1740
|
-
<ResizeHandle onResize={(delta) => setTicketPanelWidth((w) => { const next = Math.max(
|
|
2264
|
+
<ResizeHandle onResize={(delta) => setTicketPanelWidth((w) => { const next = Math.max(280, Math.min(960, w + delta)); persistLinearTicketPanelWidth(next); return next; })} />
|
|
1741
2265
|
|
|
1742
2266
|
{showRunScripts ? (
|
|
1743
2267
|
<div
|