feat: implement interactive Knowledge Graph visualization with AI-driven content analysis and handbook synchronization tools
This commit is contained in:
@@ -3,7 +3,8 @@ import * as d3 from 'd3';
|
||||
import { Trash2, Edit2, Save, X, RefreshCw, AlertCircle, Plus, Link as LinkIcon } from 'lucide-react';
|
||||
import * as db from '../../lib/db';
|
||||
import { anthropicApi } from '../../lib/api';
|
||||
import { getRepoFolder } from '../../lib/giteaService';
|
||||
import { analyzeHandbookDelta } from '../../lib/extractionPipeline';
|
||||
import { getRepoFolder, getFileContent } from '../../lib/giteaService';
|
||||
import Button from '../ui/Button';
|
||||
import SuggestionsQueue from './SuggestionsQueue';
|
||||
|
||||
@@ -21,6 +22,7 @@ const KnowledgeGraph = () => {
|
||||
const [isSyncing, setIsSyncing] = useState(false);
|
||||
const [syncResult, setSyncResult] = useState(null);
|
||||
const [syncError, setSyncError] = useState(null);
|
||||
const [syncProgress, setSyncProgress] = useState(null);
|
||||
|
||||
const [topics, setTopics] = useState([]);
|
||||
const [relations, setRelations] = useState([]);
|
||||
@@ -221,10 +223,32 @@ const KnowledgeGraph = () => {
|
||||
});
|
||||
|
||||
setSyncResult({ added, modified, unchanged });
|
||||
|
||||
const filesToProcess = [...added, ...modified];
|
||||
if (filesToProcess.length > 0) {
|
||||
setSyncProgress(`Processing 0 of ${filesToProcess.length} files...`);
|
||||
let count = 0;
|
||||
for (const file of filesToProcess) {
|
||||
count++;
|
||||
setSyncProgress(`Processing ${count} of ${filesToProcess.length}: ${file.name}...`);
|
||||
try {
|
||||
const rawContent = await getFileContent('respellion', 'employee-handbook', file.path);
|
||||
await analyzeHandbookDelta(rawContent, file.path);
|
||||
await db.updateHandbookSyncState(file.path, file.sha);
|
||||
} catch (err) {
|
||||
console.error('Failed to process file:', file.path, err);
|
||||
// We continue processing other files even if one fails
|
||||
}
|
||||
}
|
||||
setSyncProgress('Sync Complete!');
|
||||
reloadKb();
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
setSyncError(e.message || 'Failed to check GitHub for updates.');
|
||||
} finally {
|
||||
setIsSyncing(false);
|
||||
setTimeout(() => setSyncProgress(null), 5000); // Clear progress after 5s
|
||||
}
|
||||
};
|
||||
|
||||
@@ -358,9 +382,14 @@ Analyze this graph and return ONLY the optimized JSON object with this EXACT str
|
||||
<p>Added files: {syncResult.added.length}</p>
|
||||
<p>Modified files: {syncResult.modified.length}</p>
|
||||
<p>Unchanged: {syncResult.unchanged.length}</p>
|
||||
{(syncResult.added.length > 0 || syncResult.modified.length > 0) && (
|
||||
<p className="mt-2 italic text-teal">Ready for Phase 2 implementation.</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{syncProgress && (
|
||||
<div className="mt-2 text-xs text-teal p-2 bg-teal/10 border border-teal/20 rounded">
|
||||
<p className="font-medium flex items-center gap-2">
|
||||
{syncProgress !== 'Sync Complete!' && <RefreshCw size={12} className="animate-spin" />}
|
||||
{syncProgress}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user