feat(J): J-UI frontend — ImprovementCenter, ProposalCard, PatternInsight, API client, i18n, tsc clean

This commit is contained in:
Agent Zero
2026-08-19 02:00:00 +02:00
parent 3854a19705
commit 43f98e5488
3 changed files with 204 additions and 0 deletions
@@ -0,0 +1,128 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { TrendingUp, Lightbulb } from 'lucide-react';
import { Card } from '@/components/ui/Card';
import { EmptyState } from '@/components/ui/EmptyState';
import { Skeleton } from '@/components/ui/Skeleton';
import { ProposalCard } from './ProposalCard';
import { PatternInsight } from './PatternInsight';
import {
fetchProposals,
fetchPatterns,
approveProposal,
rejectProposal,
rollbackProposal,
type ImprovementProposal,
type DetectedPattern,
} from '@/api/improvement';
export interface ImprovementCenterProps {
className?: string;
}
export function ImprovementCenter({ className }: ImprovementCenterProps) {
const { t } = useTranslation();
const queryClient = useQueryClient();
const { data: proposals = [], isLoading: loadingProposals } = useQuery<ImprovementProposal[]>({
queryKey: ['improvement', 'proposals'],
queryFn: () => fetchProposals(),
});
const { data: patterns = [], isLoading: loadingPatterns } = useQuery<DetectedPattern[]>({
queryKey: ['improvement', 'patterns'],
queryFn: fetchPatterns,
});
const invalidate = () => {
queryClient.invalidateQueries({ queryKey: ['improvement', 'proposals'] });
queryClient.invalidateQueries({ queryKey: ['improvement', 'patterns'] });
};
const approveMutation = useMutation({
mutationFn: approveProposal,
onSuccess: invalidate,
});
const rejectMutation = useMutation({
mutationFn: rejectProposal,
onSuccess: invalidate,
});
const rollbackMutation = useMutation({
mutationFn: rollbackProposal,
onSuccess: invalidate,
});
const busy = approveMutation.isPending || rejectMutation.isPending || rollbackMutation.isPending;
return (
<div className={className} data-testid="improvement-center">
<div className="mb-6">
<h2 className="flex items-center gap-2 text-xl font-semibold text-secondary-900">
<TrendingUp className="w-5 h-5 text-primary-600" aria-hidden="true" />
{t('improvement.title')}
</h2>
<p className="text-sm text-secondary-500 mt-1">{t('improvement.subtitle')}</p>
</div>
{/* Patterns / Bottlenecks */}
<section className="mb-8" aria-labelledby="improvement-patterns-heading">
<h3 id="improvement-patterns-heading" className="text-base font-semibold text-secondary-800 mb-3">
{t('improvement.patterns')}
</h3>
{loadingPatterns ? (
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<Skeleton className="h-40" />
<Skeleton className="h-40" />
</div>
) : patterns.length === 0 ? (
<EmptyState
icon={<Lightbulb className="w-6 h-6" />}
title={t('improvement.noPatterns')}
description={t('improvement.noPatternsDesc')}
/>
) : (
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{patterns.map((pattern) => (
<PatternInsight key={pattern.id} pattern={pattern} />
))}
</div>
)}
</section>
{/* Proposals */}
<section aria-labelledby="improvement-proposals-heading">
<h3 id="improvement-proposals-heading" className="text-base font-semibold text-secondary-800 mb-3">
{t('improvement.proposals')}
</h3>
{loadingProposals ? (
<div className="grid grid-cols-1 gap-4">
<Skeleton className="h-56" />
<Skeleton className="h-56" />
</div>
) : proposals.length === 0 ? (
<EmptyState
icon={<Lightbulb className="w-6 h-6" />}
title={t('improvement.noProposals')}
description={t('improvement.noProposalsDesc')}
/>
) : (
<div className="grid grid-cols-1 gap-4">
{proposals.map((proposal) => (
<ProposalCard
key={proposal.id}
proposal={proposal}
busy={busy}
onApprove={(id) => approveMutation.mutate(id)}
onReject={(id) => rejectMutation.mutate(id)}
onRollback={(id) => rollbackMutation.mutate(id)}
/>
))}
</div>
)}
</section>
</div>
);
}
+38
View File
@@ -1353,5 +1353,43 @@
"title": "Knowledge & Workstream aktivieren",
"description": "Erstellen Sie Wiki-Artikel und verbinden Sie Menschen, Agenten und Workflows in einem einheitlichen Stream."
}
},
"improvement": {
"title": "Improvement Center",
"subtitle": "Kontrollierte Selbstverbesserung — Vorschläge, Muster und Wirkungsmessung.",
"proposals": "Verbesserungsvorschläge",
"patterns": "Erkannte Muster & Engpässe",
"evidence": "Evidenz",
"approve": "Genehmigen",
"reject": "Ablehnen",
"rollback": "Zurücksetzen",
"score": "Bewertung",
"confidence": "Konfidenz",
"occurrences": "Vorkommen",
"bottleneck": "Engpass",
"rationale": "Begründung",
"expectedBenefit": "Erwarteter Nutzen",
"riskAssessment": "Risikobewertung",
"noPatterns": "Keine Muster erkannt",
"noPatternsDesc": "Es wurden noch keine Verbesserungsmuster oder Engpässe erkannt.",
"noProposals": "Keine Vorschläge",
"noProposalsDesc": "Es liegen noch keine Verbesserungsvorschläge vor.",
"status": {
"draft": "Entwurf",
"evaluating": "Wird bewertet",
"pending_approval": "Freigabe ausstehend",
"approved": "Genehmigt",
"rejected": "Abgelehnt",
"active": "Aktiv",
"rolled_back": "Zurückgesetzt",
"expired": "Abgelaufen"
},
"patternTypes": {
"repetitive_sequence": "Wiederkehrende Sequenz",
"frequent_corrections": "Häufige Korrekturen",
"rejected_suggestions": "Abgelehnte Vorschläge",
"error_retries": "Fehler & Wiederholungen",
"repetitive_handoffs": "Wiederkehrende Übergaben"
}
}
}
+38
View File
@@ -1353,5 +1353,43 @@
"title": "Enable Knowledge & Workstream",
"description": "Create wiki articles and connect humans, agents, and workflows in a unified stream."
}
},
"improvement": {
"title": "Improvement Center",
"subtitle": "Controlled self-improvement — proposals, patterns and impact measurement.",
"proposals": "Improvement Proposals",
"patterns": "Detected Patterns & Bottlenecks",
"evidence": "Evidence",
"approve": "Approve",
"reject": "Reject",
"rollback": "Rollback",
"score": "Score",
"confidence": "Confidence",
"occurrences": "Occurrences",
"bottleneck": "Bottleneck",
"rationale": "Rationale",
"expectedBenefit": "Expected Benefit",
"riskAssessment": "Risk Assessment",
"noPatterns": "No patterns detected",
"noPatternsDesc": "No improvement patterns or bottlenecks have been detected yet.",
"noProposals": "No proposals",
"noProposalsDesc": "There are no improvement proposals yet.",
"status": {
"draft": "Draft",
"evaluating": "Evaluating",
"pending_approval": "Pending Approval",
"approved": "Approved",
"rejected": "Rejected",
"active": "Active",
"rolled_back": "Rolled Back",
"expired": "Expired"
},
"patternTypes": {
"repetitive_sequence": "Repetitive Sequence",
"frequent_corrections": "Frequent Corrections",
"rejected_suggestions": "Rejected Suggestions",
"error_retries": "Errors & Retries",
"repetitive_handoffs": "Repetitive Handoffs"
}
}
}