MCPcopy Create free account
hub / github.com/ForgeAILab/forge / ProjectHooksSection

Function ProjectHooksSection

web/src/components/settings/ProjectHooksSection.tsx:547–1441  ·  view source on GitHub ↗
({
  project,
  projectId,
  projectIsLoading,
}: {
  project?: Project
  projectId: string
  projectIsLoading: boolean
})

Source from the content-addressed store, hash-verified

545}
546
547export function ProjectHooksSection({
548 project,
549 projectId,
550 projectIsLoading,
551}: {
552 project?: Project
553 projectId: string
554 projectIsLoading: boolean
555}) {
556 const queryClient = useQueryClient()
557 const runsQuery = useProjectHookRunsQuery(projectId)
558 const agentsQuery = useAgentsQuery()
559 const agentsList = agentsQuery.data?.items ?? []
560 const agentOptions = useMemo<ComboSelectOption[]>(
561 () =>
562 agentsList.map((agent) => ({
563 value: agent.id,
564 label: agent.name,
565 description: `${agent.executor_type} · ${agent.id}`,
566 })),
567 [agentsList],
568 )
569 const agentNames = useMemo(() => {
570 const map = new Map<string, string>()
571 for (const agent of agentsList) map.set(agent.id, agent.name)
572 return map
573 }, [agentsList])
574 const rules = project?.project_hooks ?? []
575 const runs = useMemo(
576 () => runsQuery.data?.pages.flatMap((page) => page.items) ?? [],
577 [runsQuery.data],
578 )
579 const runStats = useMemo(() => computeRunStats(runs), [runs])
580
581 const [dialogMode, setDialogMode] = useState<DialogMode | null>(null)
582 const [form, setForm] = useState<ProjectHookRuleFormState>(() => emptyRuleForm())
583 const [formError, setFormError] = useState('')
584 const [sectionError, setSectionError] = useState('')
585 const [detailIndex, setDetailIndex] = useState<number | null>(null)
586 const [showAllRuns, setShowAllRuns] = useState(false)
587
588 const selectedRule = detailIndex !== null ? rules[detailIndex] : null
589 const selectedRuleRuns = useMemo(
590 () => (selectedRule ? runs.filter((run) => run.rule_id === selectedRule.id) : []),
591 [runs, selectedRule],
592 )
593
594 const saveRules = useMutation({
595 mutationFn: (nextRules: ProjectHookRuleWire[]) =>
596 apiFetch<Project>(`/projects/${projectId}`, {
597 method: 'PATCH',
598 body: JSON.stringify({ project_hooks: nextRules }),
599 }),
600 onSuccess: (updatedProject) => {
601 void queryClient.invalidateQueries({ queryKey: qk.project(updatedProject.id) })
602 void queryClient.invalidateQueries({ queryKey: qk.projects })
603 },
604 })

Callers

nothing calls this directly

Calls 15

useProjectHookRunsQueryFunction · 0.90
useAgentsQueryFunction · 0.90
apiFetchFunction · 0.90
cnFunction · 0.90
computeRunStatsFunction · 0.85
emptyRuleFormFunction · 0.85
shortTriggerFunction · 0.85
actionSummaryFunction · 0.85
formatCooldownFunction · 0.85
openEditDialogFunction · 0.85
toggleEnabledFunction · 0.85
deleteRuleFunction · 0.85

Tested by

no test coverage detected