@ 关键路径/反应
反应上下文提供者 & Hooks 对于关键路径.
升级? 升级一次
@critical-path/*组合在一起。 编码代理: 遵循 更新(md); 已标记断开的更改 刹车 此软件包中CHANGELOG.md。 。 。 .
@critical-path/react 提供组件和自定义反应钩( R)useProjects, (中文(简体) ), useTasks, (中文(简体) ), useKanban, (中文(简体) ), useTaskActivity, (中文(简体) ), useComments, (中文(简体) ), useAttachments, (中文(简体) ), useTaskTransitions, (中文(简体) ), useWorkflows, (中文(简体) ), useDeliverables, (中文(简体) ), useDeliverableSummary, (中文(简体) ), useWebMCP用于在 React and Next.js 中渲染项目管理 UI.
* 安装
npm install @critical-path/react @critical-path/client
# or
pnpm add @critical-path/react @critical-path/client
使用示例
1. 与提供者的环绕应用程序
import { CriticalPathProvider } from '@critical-path/react';
export default function RootLayout({ children }) {
return (
<CriticalPathProvider options={{ baseUrl: '/api/critical-path' }}>
{children}
</CriticalPathProvider>
);
}
2. 伦德·坎班董事会
'use client';
import { useKanban } from '@critical-path/react';
export function Board({ projectId }: { projectId: string }) {
const { columns, moveTask, loading } = useKanban(projectId);
if (loading) return <div>Loading board...</div>;
return (
<div className="flex gap-4">
{Object.entries(columns).map(([status, tasks]) => (
<div key={status} className="column">
<h2>{status} ({tasks.length})</h2>
{tasks.map((task) => (
<div key={task.id} className="card">
<h3>{task.title}</h3>
<button onClick={() => moveTask(task.id, 'done')}>Mark Done</button>
</div>
))}
</div>
))}
</div>
);
}
### 3. Manage Task Comments & Reactions
```tsx
'use client';
import { useComments } from '@critical-path/react';
export function TaskDiscussion({ taskId }: { taskId: string }) {
const { comments, threads, addComment, addReaction, removeReaction } = useComments(taskId);
return (
<div className="discussion">
{comments.map((comment) => (
<div key={comment.id} className="comment">
<p>{comment.content}</p>
<div className="reactions flex gap-2">
<button onClick={() => addReaction(comment.id, '👍')}>👍</button>
<button onClick={() => addReaction(comment.id, '🚀')}>🚀</button>
<span>{comment.reactions?.length || 0} reactions</span>
</div>
</div>
))}
</div>
);
}
4. 统一任务活动useTaskActivity(中文(简体) )
将线性评论与内置附件和独立附件合并:
'use client';
import { useTaskActivity } from '@critical-path/react';
export function ActivityStream({ taskId }: { taskId: string }) {
const { threads, standaloneAttachments, addComment, addReaction } = useTaskActivity(taskId);
return (
<div>
{threads.map((thread) => (
<div key={thread.id}>
<p><strong>{thread.authorId}</strong>: {thread.content}</p>
{thread.attachments.map((att) => (
<a key={att.id} href={att.url}>{att.filename}</a>
))}
</div>
))}
</div>
);
}
5. 抽象梯子useTimelineLadder 打开 useCriticalPath(中文(简体) )
在宏观阶段健康、标准甘特任务与CPM关键路径和具体可达到的目标/努力之间流畅地进行:
'use client';
import { useTimelineLadder, useCriticalPath } from '@critical-path/react';
export function ProjectTimelineView({ projectId }: { projectId: string }) {
const { ladder, level, setLevel, macro, standard, concrete, loading } = useTimelineLadder(projectId, { level: 'all' });
const { analysis } = useCriticalPath(projectId);
if (loading) return <div>Synthesizing timeline ladder...</div>;
return (
<div>
{/* Abstraction Slider */}
<div className="flex gap-2 mb-4">
<button onClick={() => setLevel('macro')}>Macro Phases</button>
<button onClick={() => setLevel('standard')}>Standard Gantt</button>
<button onClick={() => setLevel('concrete')}>Concrete Work</button>
<button onClick={() => setLevel('all')}>Full Ladder</button>
</div>
{/* Macro Rung */}
{macro && (
<div className="macro-phase p-4 bg-slate-900 text-white rounded">
<h2>Project Health: {macro.health} ({macro.overallProgressPercentage}% Complete)</h2>
<p>Critical Path Duration: {macro.criticalPathDurationHours}h</p>
</div>
)}
{/* Standard Rung */}
{standard && (
<div className="standard-gantt my-4">
<h3>Gantt Tasks ({standard.tasks.length})</h3>
{standard.tasks.map(item => (
<div key={item.task.id} className={item.isCritical ? 'font-bold text-red-500' : ''}>
{item.task.title} — ES: {item.schedule.earlyStart}h / EF: {item.schedule.earlyFinish}h (Slack: {item.schedule.totalSlack}h)
</div>
))}
</div>
)}
{/* Concrete Grounding Rung */}
{concrete && (
<div className="concrete-evidence">
<h3>Ground Truth & Evidence</h3>
{Object.entries(concrete).map(([taskId, evidence]) => (
<div key={taskId} className="border p-2 rounded mb-2">
<p>Task {taskId}: {evidence.attachments.length} files, {evidence.deliverables.length} deliverables</p>
<p>Reality Delta: {evidence.realityDelta.hoursDelta > 0 ? `+${evidence.realityDelta.hoursDelta}h over estimate` : `${evidence.realityDelta.hoursDelta}h`}</p>
</div>
))}
</div>
)}
</div>
);
}
& 服务器组件
数据钩 (E)useTasks, (中文(简体) ), useProjects, (中文(简体) ), useTaskActivity, (中文(简体) ), useTimelineLadder,.)当其输入或组件卸载时中止其飞行请求,因此对前一个项目或任务的缓慢响应永远无法覆盖更新的数据. 软件包是标记的 'use client',这样您就可以从 Next.js 服务器组件使用的文件中导入钩子,并将其制成客户端组件.
许可证
麻省理工学院 关键路径