feat(graph): wire popover actions to real dialogs (Message, Open task/member)
- TeamGraphOverlay accepts onSendMessage, onOpenTaskDetail, onOpenMemberProfile - TeamDetailView passes dialog openers to overlay: - Message → opens SendMessageDialog with recipient pre-filled - Open (task) → opens TaskDetailDialog with task found by ID - Open (member) → opens SendMessageDialog for that member - Double-click → same as Open - Removed console.log stubs
This commit is contained in:
parent
789b74219e
commit
98a1155635
3 changed files with 58 additions and 41 deletions
42
.github/CONTRIBUTING.md
vendored
42
.github/CONTRIBUTING.md
vendored
|
|
@ -1,28 +1,17 @@
|
|||
# Contributing
|
||||
|
||||
Thanks for contributing to Claude Agent Teams UI.
|
||||
Thanks for contributing to Claude Agent Teams UI!
|
||||
|
||||
## Project Philosophy & Scope
|
||||
## Before You Start
|
||||
|
||||
claude-devtools exists to make the invisible parts of Claude Code visible — the token flows, context injections, tool executions, and session dynamics that are otherwise hidden behind the CLI. It is not a general-purpose dashboard or an IDE.
|
||||
For big features and major changes, please discuss them in our [Discord](https://discord.gg/RgBHMBsn) first so we can figure out the best approach together and avoid conflicts.
|
||||
|
||||
Our priorities:
|
||||
|
||||
1. **Parity with Claude Code** — When Claude Code ships new capabilities (agent teams, context tracking, new tool types), we adopt them quickly so users always have full visibility.
|
||||
2. **Context engineering insight** — Features that help users understand *what* is consuming their context window, *how* tokens flow through a session, and *where* to optimize. If it doesn't help someone make better decisions about their Claude Code usage, it probably doesn't belong here.
|
||||
3. **Stability over novelty** — A reliable, fast tool for professional workflows. We'd rather do fewer things well than many things poorly.
|
||||
|
||||
**What we generally do not accept:**
|
||||
- Large custom features that don't directly serve context visibility or Claude Code parity.
|
||||
- Speculative features that add maintenance burden without solving a concrete problem users face today.
|
||||
- PRs that significantly expand scope without prior discussion in an Issue.
|
||||
|
||||
If you're considering a non-trivial contribution, **open an Issue first** to check alignment with the current roadmap. This saves everyone time and keeps the project focused.
|
||||
Small fixes, bug reports, and minor improvements are always welcome -- just open a PR.
|
||||
|
||||
## Prerequisites
|
||||
- Node.js 20+
|
||||
- pnpm 10+
|
||||
- macOS or Windows
|
||||
- macOS, Windows, or Linux
|
||||
|
||||
## Setup
|
||||
```bash
|
||||
|
|
@ -39,12 +28,16 @@ pnpm test
|
|||
pnpm build
|
||||
```
|
||||
|
||||
Or all at once:
|
||||
```bash
|
||||
pnpm check
|
||||
```
|
||||
|
||||
## Pull Request Guidelines
|
||||
- Keep changes focused and small — one purpose per PR.
|
||||
- Keep changes focused and small -- one purpose per PR.
|
||||
- Add/adjust tests for behavior changes.
|
||||
- Update docs when changing public behavior or setup.
|
||||
- Use clear PR titles and include a short validation checklist.
|
||||
- **Large changes (new features, new dependencies, large data additions) must have a discussion in an Issue first.** Do not open a large PR without prior agreement on the approach.
|
||||
- Avoid committing large hardcoded data blobs. If data can be fetched at runtime or generated at build time, prefer that approach.
|
||||
|
||||
## AI-Assisted Contributions
|
||||
|
|
@ -52,15 +45,14 @@ pnpm build
|
|||
AI coding tools are welcome, but **you are responsible for what you submit**:
|
||||
|
||||
- **Review before submitting.** Read every line of AI-generated code and understand what it does. Do not submit raw, unreviewed AI output.
|
||||
- **Do not commit AI workflow artifacts.** Planning documents, session logs, step-by-step plans, or other outputs from AI tools (e.g. `docs/plans/`, `.speckit/`, etc.) do not belong in the repository.
|
||||
- **Test it yourself.** AI-generated code must be manually verified — run the app, confirm the feature works, check edge cases.
|
||||
- **Do not commit AI workflow artifacts.** Planning documents, session logs, step-by-step plans, or other outputs from AI tools do not belong in the repository.
|
||||
- **Test it yourself.** AI-generated code must be manually verified -- run the app, confirm the feature works, check edge cases.
|
||||
- **Keep it intentional.** Every line in your PR should exist for a reason you can explain. If you can't explain why a piece of code is there, remove it.
|
||||
|
||||
## What Does NOT Belong in the Repo
|
||||
- Personal planning/workflow artifacts (AI session plans, task lists, etc.)
|
||||
- Large static data that could be fetched at runtime
|
||||
- Generated files that aren't part of the build output
|
||||
- Experimental features without prior discussion
|
||||
|
||||
## Commit Style
|
||||
- Prefer conventional commits (`feat:`, `fix:`, `chore:`, `docs:`).
|
||||
|
|
@ -69,7 +61,7 @@ AI coding tools are welcome, but **you are responsible for what you submit**:
|
|||
## Reporting Bugs
|
||||
Please include:
|
||||
- OS version
|
||||
- app version / commit hash
|
||||
- repro steps
|
||||
- expected vs actual behavior
|
||||
- logs/screenshots when possible
|
||||
- App version / commit hash
|
||||
- Repro steps
|
||||
- Expected vs actual behavior
|
||||
- Logs/screenshots when possible
|
||||
|
|
|
|||
|
|
@ -2088,6 +2088,22 @@ export const TeamDetailView = ({ teamName }: TeamDetailViewProps): React.JSX.Ele
|
|||
.getState()
|
||||
.openTab({ type: 'graph', label: `${data.config.name} Graph`, teamName });
|
||||
}}
|
||||
onSendMessage={(memberName) => {
|
||||
setSendDialogRecipient(memberName);
|
||||
setSendDialogDefaultText(undefined);
|
||||
setSendDialogDefaultChip(undefined);
|
||||
setSendDialogOpen(true);
|
||||
}}
|
||||
onOpenTaskDetail={(taskId) => {
|
||||
const task = data.tasks.find((t) => t.id === taskId);
|
||||
if (task) setSelectedTask(task);
|
||||
}}
|
||||
onOpenMemberProfile={(memberName) => {
|
||||
setSendDialogRecipient(memberName);
|
||||
setSendDialogDefaultText(undefined);
|
||||
setSendDialogDefaultChip(undefined);
|
||||
setSendDialogOpen(true);
|
||||
}}
|
||||
/>
|
||||
</Suspense>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -15,32 +15,41 @@ export interface TeamGraphOverlayProps {
|
|||
teamName: string;
|
||||
onClose: () => void;
|
||||
onPinAsTab?: () => void;
|
||||
onSendMessage?: (memberName: string) => void;
|
||||
onOpenTaskDetail?: (taskId: string) => void;
|
||||
onOpenMemberProfile?: (memberName: string) => void;
|
||||
}
|
||||
|
||||
export const TeamGraphOverlay = ({
|
||||
teamName,
|
||||
onClose,
|
||||
onPinAsTab,
|
||||
onSendMessage,
|
||||
onOpenTaskDetail,
|
||||
onOpenMemberProfile,
|
||||
}: TeamGraphOverlayProps): React.JSX.Element => {
|
||||
const graphData = useTeamGraphAdapter(teamName);
|
||||
|
||||
const events: GraphEventPort = {
|
||||
onNodeClick: useCallback((_ref: GraphDomainRef) => {
|
||||
// Popover shown by GraphView internally
|
||||
}, []),
|
||||
onNodeDoubleClick: useCallback((ref: GraphDomainRef) => {
|
||||
// TODO: open TaskDetailDialog or MemberDetailDialog based on ref.kind
|
||||
console.log('Double-click:', ref);
|
||||
}, []),
|
||||
onSendMessage: useCallback((_memberName: string, _teamName: string) => {
|
||||
// TODO: open SendMessageDialog
|
||||
}, []),
|
||||
onOpenTaskDetail: useCallback((_taskId: string, _teamName: string) => {
|
||||
// TODO: open TaskDetailDialog
|
||||
}, []),
|
||||
onBackgroundClick: useCallback(() => {
|
||||
// Deselect handled by GraphView
|
||||
}, []),
|
||||
onNodeDoubleClick: useCallback(
|
||||
(ref: GraphDomainRef) => {
|
||||
if (ref.kind === 'task') onOpenTaskDetail?.(ref.taskId);
|
||||
else if (ref.kind === 'member') onOpenMemberProfile?.(ref.memberName);
|
||||
},
|
||||
[onOpenTaskDetail, onOpenMemberProfile]
|
||||
),
|
||||
onSendMessage: useCallback(
|
||||
(memberName: string) => onSendMessage?.(memberName),
|
||||
[onSendMessage]
|
||||
),
|
||||
onOpenTaskDetail: useCallback(
|
||||
(taskId: string) => onOpenTaskDetail?.(taskId),
|
||||
[onOpenTaskDetail]
|
||||
),
|
||||
onOpenMemberProfile: useCallback(
|
||||
(memberName: string) => onOpenMemberProfile?.(memberName),
|
||||
[onOpenMemberProfile]
|
||||
),
|
||||
};
|
||||
|
||||
return (
|
||||
|
|
|
|||
Loading…
Reference in a new issue