Job ID: {currentJob}
+ )} +No activity yet
+Agent logs will appear here during generation
+{log.message}
+ + {/* Metadata */} + {log.metadata && Object.keys(log.metadata).length > 0 && ( +Enter a GitHub repository URL to generate comprehensive documentation
++ {statusInfo.message} +
+Automatic Documentation Generator
+Error rendering diagram: ${error.message}`
+ }
+ }
+
+ renderDiagram()
+ }
+ }, [chart])
+
+ return
+}
+
+export default Mermaid
diff --git a/sample_solutions/Docugen-Microagents/ui/src/components/ProjectSelector.jsx b/sample_solutions/Docugen-Microagents/ui/src/components/ProjectSelector.jsx
new file mode 100644
index 00000000..279da952
--- /dev/null
+++ b/sample_solutions/Docugen-Microagents/ui/src/components/ProjectSelector.jsx
@@ -0,0 +1,275 @@
+import { useState, useEffect } from 'react'
+import { Folder, CheckSquare, Square, Play, Loader2, CheckCheck, XSquare, Search, AlertCircle } from 'lucide-react'
+import { api } from '../services/api'
+
+function ProjectSelector({ currentJob, detectedProjects, skippedFolders, onProjectsSelected }) {
+ const [selectedPaths, setSelectedPaths] = useState([])
+ const [submitting, setSubmitting] = useState(false)
+ const [searchQuery, setSearchQuery] = useState('')
+ const [error, setError] = useState(null)
+
+ // Debug logging
+ console.log('DEBUG ProjectSelector - skippedFolders:', skippedFolders)
+ console.log('DEBUG ProjectSelector - skippedFolders type:', typeof skippedFolders)
+ console.log('DEBUG ProjectSelector - skippedFolders length:', skippedFolders?.length)
+
+ // Initialize with empty selection (better UX for large repos)
+ useEffect(() => {
+ if (detectedProjects && detectedProjects.length > 0) {
+ // For small repos (< 10 projects), select all. For large repos, select none.
+ if (detectedProjects.length <= 10) {
+ setSelectedPaths(detectedProjects.map(p => p.path))
+ } else {
+ setSelectedPaths([])
+ }
+ }
+ }, [detectedProjects])
+
+ const selectAll = () => {
+ const filtered = getFilteredProjects()
+ setSelectedPaths(prev => {
+ const newPaths = filtered.map(p => p.path)
+ return Array.from(new Set([...prev, ...newPaths]))
+ })
+ }
+
+ const deselectAll = () => {
+ const filtered = getFilteredProjects()
+ const filteredPaths = filtered.map(p => p.path)
+ setSelectedPaths(prev => prev.filter(path => !filteredPaths.includes(path)))
+ }
+
+ const getFilteredProjects = () => {
+ if (!detectedProjects) return []
+ if (!searchQuery.trim()) return detectedProjects
+
+ const query = searchQuery.toLowerCase()
+ return detectedProjects.filter(p =>
+ p.name.toLowerCase().includes(query) ||
+ p.path.toLowerCase().includes(query) ||
+ p.types.some(t => t.toLowerCase().includes(query))
+ )
+ }
+
+ const toggleProject = (path) => {
+ setError(null) // Clear error when user changes selection
+ setSelectedPaths(prev => {
+ if (prev.includes(path)) {
+ return prev.filter(p => p !== path)
+ } else {
+ return [...prev, path]
+ }
+ })
+ }
+
+ const handleSubmit = async () => {
+ if (selectedPaths.length === 0) {
+ setError('Please select at least one project to document')
+ return
+ }
+
+ setSubmitting(true)
+ setError(null)
+ try {
+ await api.selectProjects(currentJob, selectedPaths)
+ onProjectsSelected()
+ } catch (err) {
+ console.error('Failed to submit project selection:', err)
+ // Extract error message from backend response
+ const errorMessage = err.response?.data?.detail || 'Failed to submit selection. Please try again.'
+ setError(errorMessage)
+ setSubmitting(false)
+ }
+ }
+
+ if (!detectedProjects || detectedProjects.length === 0) {
+ return null
+ }
+
+ const filteredProjects = getFilteredProjects()
+ const filteredSelectedCount = filteredProjects.filter(p => selectedPaths.includes(p.path)).length
+
+ return (
+ + {detectedProjects.length} project(s) Found in this repository. Select a project to generate Readme file. +
+{error}
++ {selectedPaths.length} of {detectedProjects.length} selected +
+No projects match your search criteria.
++ Path: {project.path} +
+ ++ Type: {projectTypes} +
+ ++ The following folders were not detected as code projects: +
++ {selectedPaths.length} project{selectedPaths.length !== 1 ? 's' : ''} selected +
+ + +{projectTitle}
+ )} +
+ {children}
+
+ )
+ }
+ }}
+ >
+ {markdownContent}
+
+ {prError}
+ {prError.includes('GITHUB_TOKEN') && ( ++ Make sure GITHUB_TOKEN is configured in your backend environment variables. +
+ )} +