2026-02-17 12:24:48 -06:00
|
|
|
import { useEffect } from "react";
|
Add detail pages, property panels, and restyle list pages
New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:06 -06:00
|
|
|
import { useNavigate, useParams } from "react-router-dom";
|
2026-02-18 16:46:55 -06:00
|
|
|
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
|
Add detail pages, property panels, and restyle list pages
New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:06 -06:00
|
|
|
import { goalsApi } from "../api/goals";
|
|
|
|
|
import { projectsApi } from "../api/projects";
|
Add MarkdownEditor component, asset image upload, and rich description editing
Introduce MarkdownEditor built on @mdxeditor/editor with headings,
lists, links, quotes, image upload with drag-and-drop, and themed CSS
integration. Add asset image upload API (routes, service, storage) and
wire image upload into InlineEditor multiline mode, NewIssueDialog,
NewProjectDialog, GoalDetail, IssueDetail, and ProjectDetail
description fields. Tighten prompt template editor styling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 12:50:45 -06:00
|
|
|
import { assetsApi } from "../api/assets";
|
Add detail pages, property panels, and restyle list pages
New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:06 -06:00
|
|
|
import { usePanel } from "../context/PanelContext";
|
|
|
|
|
import { useCompany } from "../context/CompanyContext";
|
|
|
|
|
import { useBreadcrumbs } from "../context/BreadcrumbContext";
|
2026-02-17 12:24:48 -06:00
|
|
|
import { queryKeys } from "../lib/queryKeys";
|
Add detail pages, property panels, and restyle list pages
New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:06 -06:00
|
|
|
import { GoalProperties } from "../components/GoalProperties";
|
|
|
|
|
import { GoalTree } from "../components/GoalTree";
|
|
|
|
|
import { StatusBadge } from "../components/StatusBadge";
|
2026-02-18 16:46:55 -06:00
|
|
|
import { InlineEditor } from "../components/InlineEditor";
|
Add detail pages, property panels, and restyle list pages
New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:06 -06:00
|
|
|
import { EntityRow } from "../components/EntityRow";
|
|
|
|
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
|
|
|
import type { Goal, Project } from "@paperclip/shared";
|
|
|
|
|
|
|
|
|
|
export function GoalDetail() {
|
|
|
|
|
const { goalId } = useParams<{ goalId: string }>();
|
|
|
|
|
const { selectedCompanyId } = useCompany();
|
|
|
|
|
const { openPanel, closePanel } = usePanel();
|
|
|
|
|
const { setBreadcrumbs } = useBreadcrumbs();
|
|
|
|
|
const navigate = useNavigate();
|
2026-02-18 16:46:55 -06:00
|
|
|
const queryClient = useQueryClient();
|
Add detail pages, property panels, and restyle list pages
New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:06 -06:00
|
|
|
|
2026-02-17 12:24:48 -06:00
|
|
|
const { data: goal, isLoading, error } = useQuery({
|
|
|
|
|
queryKey: queryKeys.goals.detail(goalId!),
|
|
|
|
|
queryFn: () => goalsApi.get(goalId!),
|
|
|
|
|
enabled: !!goalId,
|
|
|
|
|
});
|
Add detail pages, property panels, and restyle list pages
New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:06 -06:00
|
|
|
|
2026-02-17 12:24:48 -06:00
|
|
|
const { data: allGoals } = useQuery({
|
|
|
|
|
queryKey: queryKeys.goals.list(selectedCompanyId!),
|
|
|
|
|
queryFn: () => goalsApi.list(selectedCompanyId!),
|
|
|
|
|
enabled: !!selectedCompanyId,
|
|
|
|
|
});
|
Add detail pages, property panels, and restyle list pages
New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:06 -06:00
|
|
|
|
2026-02-17 12:24:48 -06:00
|
|
|
const { data: allProjects } = useQuery({
|
|
|
|
|
queryKey: queryKeys.projects.list(selectedCompanyId!),
|
|
|
|
|
queryFn: () => projectsApi.list(selectedCompanyId!),
|
|
|
|
|
enabled: !!selectedCompanyId,
|
|
|
|
|
});
|
Add detail pages, property panels, and restyle list pages
New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:06 -06:00
|
|
|
|
2026-02-18 16:46:55 -06:00
|
|
|
const updateGoal = useMutation({
|
|
|
|
|
mutationFn: (data: Record<string, unknown>) => goalsApi.update(goalId!, data),
|
|
|
|
|
onSuccess: () => {
|
|
|
|
|
queryClient.invalidateQueries({ queryKey: queryKeys.goals.detail(goalId!) });
|
|
|
|
|
if (selectedCompanyId) {
|
|
|
|
|
queryClient.invalidateQueries({ queryKey: queryKeys.goals.list(selectedCompanyId) });
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
Add MarkdownEditor component, asset image upload, and rich description editing
Introduce MarkdownEditor built on @mdxeditor/editor with headings,
lists, links, quotes, image upload with drag-and-drop, and themed CSS
integration. Add asset image upload API (routes, service, storage) and
wire image upload into InlineEditor multiline mode, NewIssueDialog,
NewProjectDialog, GoalDetail, IssueDetail, and ProjectDetail
description fields. Tighten prompt template editor styling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 12:50:45 -06:00
|
|
|
const uploadImage = useMutation({
|
|
|
|
|
mutationFn: async (file: File) => {
|
|
|
|
|
if (!selectedCompanyId) throw new Error("No company selected");
|
|
|
|
|
return assetsApi.uploadImage(selectedCompanyId, file, `goals/${goalId ?? "draft"}`);
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
Add detail pages, property panels, and restyle list pages
New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:06 -06:00
|
|
|
const childGoals = (allGoals ?? []).filter((g) => g.parentId === goalId);
|
|
|
|
|
const linkedProjects = (allProjects ?? []).filter((p) => p.goalId === goalId);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
setBreadcrumbs([
|
|
|
|
|
{ label: "Goals", href: "/goals" },
|
|
|
|
|
{ label: goal?.title ?? goalId ?? "Goal" },
|
|
|
|
|
]);
|
|
|
|
|
}, [setBreadcrumbs, goal, goalId]);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (goal) {
|
2026-02-18 16:46:55 -06:00
|
|
|
openPanel(
|
|
|
|
|
<GoalProperties goal={goal} onUpdate={(data) => updateGoal.mutate(data)} />
|
|
|
|
|
);
|
Add detail pages, property panels, and restyle list pages
New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:06 -06:00
|
|
|
}
|
|
|
|
|
return () => closePanel();
|
|
|
|
|
}, [goal]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
|
|
|
|
2026-02-17 12:24:48 -06:00
|
|
|
if (isLoading) return <p className="text-sm text-muted-foreground">Loading...</p>;
|
Add detail pages, property panels, and restyle list pages
New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:06 -06:00
|
|
|
if (error) return <p className="text-sm text-destructive">{error.message}</p>;
|
|
|
|
|
if (!goal) return null;
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<div className="space-y-6">
|
2026-02-18 16:46:55 -06:00
|
|
|
<div className="space-y-3">
|
Add detail pages, property panels, and restyle list pages
New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:06 -06:00
|
|
|
<div className="flex items-center gap-2">
|
|
|
|
|
<span className="text-xs uppercase text-muted-foreground">{goal.level}</span>
|
|
|
|
|
<StatusBadge status={goal.status} />
|
|
|
|
|
</div>
|
2026-02-18 16:46:55 -06:00
|
|
|
|
|
|
|
|
<InlineEditor
|
|
|
|
|
value={goal.title}
|
|
|
|
|
onSave={(title) => updateGoal.mutate({ title })}
|
|
|
|
|
as="h2"
|
|
|
|
|
className="text-xl font-bold"
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<InlineEditor
|
|
|
|
|
value={goal.description ?? ""}
|
|
|
|
|
onSave={(description) => updateGoal.mutate({ description })}
|
|
|
|
|
as="p"
|
|
|
|
|
className="text-sm text-muted-foreground"
|
|
|
|
|
placeholder="Add a description..."
|
|
|
|
|
multiline
|
Add MarkdownEditor component, asset image upload, and rich description editing
Introduce MarkdownEditor built on @mdxeditor/editor with headings,
lists, links, quotes, image upload with drag-and-drop, and themed CSS
integration. Add asset image upload API (routes, service, storage) and
wire image upload into InlineEditor multiline mode, NewIssueDialog,
NewProjectDialog, GoalDetail, IssueDetail, and ProjectDetail
description fields. Tighten prompt template editor styling.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-20 12:50:45 -06:00
|
|
|
imageUploadHandler={async (file) => {
|
|
|
|
|
const asset = await uploadImage.mutateAsync(file);
|
|
|
|
|
return asset.contentPath;
|
|
|
|
|
}}
|
2026-02-18 16:46:55 -06:00
|
|
|
/>
|
Add detail pages, property panels, and restyle list pages
New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:06 -06:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<Tabs defaultValue="children">
|
|
|
|
|
<TabsList>
|
|
|
|
|
<TabsTrigger value="children">Sub-Goals ({childGoals.length})</TabsTrigger>
|
|
|
|
|
<TabsTrigger value="projects">Projects ({linkedProjects.length})</TabsTrigger>
|
|
|
|
|
</TabsList>
|
|
|
|
|
|
|
|
|
|
<TabsContent value="children" className="mt-4">
|
|
|
|
|
{childGoals.length === 0 ? (
|
|
|
|
|
<p className="text-sm text-muted-foreground">No sub-goals.</p>
|
|
|
|
|
) : (
|
|
|
|
|
<GoalTree
|
|
|
|
|
goals={childGoals}
|
|
|
|
|
onSelect={(g) => navigate(`/goals/${g.id}`)}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
</TabsContent>
|
|
|
|
|
|
|
|
|
|
<TabsContent value="projects" className="mt-4">
|
|
|
|
|
{linkedProjects.length === 0 ? (
|
|
|
|
|
<p className="text-sm text-muted-foreground">No linked projects.</p>
|
|
|
|
|
) : (
|
Polish UI components and rework AgentConfigForm
Major AgentConfigForm rework with improved adapter configuration
fields and layout. Refine sidebar, breadcrumbs, and card/tab
components for visual consistency. Clean up page layouts across
Activity, Agents, Approvals, Costs, Dashboard, Goals, Inbox,
Issues, Org, and Projects pages. Minor heartbeat-run CLI fix.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 10:43:25 -06:00
|
|
|
<div className="border border-border">
|
Add detail pages, property panels, and restyle list pages
New pages: AgentDetail, GoalDetail, IssueDetail, ProjectDetail, Inbox,
MyIssues. New feature components: AgentProperties, GoalProperties,
IssueProperties, ProjectProperties, GoalTree, NewIssueDialog. Add
heartbeats API client. Restyle all list pages (Agents, Issues, Goals,
Projects, Dashboard, Costs, Activity, Org) with EntityRow, FilterBar,
and improved layouts. Add routing for detail views.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 09:57:06 -06:00
|
|
|
{linkedProjects.map((project) => (
|
|
|
|
|
<EntityRow
|
|
|
|
|
key={project.id}
|
|
|
|
|
title={project.name}
|
|
|
|
|
subtitle={project.description ?? undefined}
|
|
|
|
|
onClick={() => navigate(`/projects/${project.id}`)}
|
|
|
|
|
trailing={<StatusBadge status={project.status} />}
|
|
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</TabsContent>
|
|
|
|
|
</Tabs>
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|