fix(lint): תיקון 10 שגיאות ESLint + ניקוי directives מיותרים
10 שגיאות (כולן קיימות-מראש, לא מהפיצ'רים האחרונים): - react/no-unescaped-entities (3): legal-arguments-panel, precedent-edit-sheet — escaping של מרכאות ב-JSX (“/") - react-hooks/set-state-in-effect (6): documents-panel, chair-editor, content-checklists, discussion-rules, golden-ratios, documents.ts — disable-comment לדפוסי sync/reset לגיטימיים (false-positive ידוע) - React Compiler reassign (1): subject-donut — refactor לחישוב prefix-sums ללא mutable accumulator ניקוי: הסרת 5 eslint-disable directives מיותרים (halacha-review-panel, precedent-upload-sheet). תוצאה: 0 errors (היה 10), 24→ warnings (היה 29). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -107,8 +107,10 @@ function DocumentPreviewDialog({
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) {
|
||||
/* eslint-disable react-hooks/set-state-in-effect -- reset on close */
|
||||
setText(null);
|
||||
setError(null);
|
||||
/* eslint-enable react-hooks/set-state-in-effect */
|
||||
return;
|
||||
}
|
||||
let cancelled = false;
|
||||
|
||||
@@ -203,7 +203,7 @@ export function LegalArgumentsPanel({ caseNumber }: LegalArgumentsPanelProps) {
|
||||
</p>
|
||||
) : !data?.total ? (
|
||||
<p className="text-ink-muted text-sm">
|
||||
אין טיעונים מאוגדים עדיין. לחץ "חשב טיעונים" כדי להריץ את ה-aggregator.
|
||||
אין טיעונים מאוגדים עדיין. לחץ “חשב טיעונים” כדי להריץ את ה-aggregator.
|
||||
</p>
|
||||
) : (
|
||||
<div className="space-y-6">
|
||||
|
||||
@@ -34,6 +34,7 @@ export function ChairEditor({
|
||||
|
||||
/* Reset when the upstream analysis refetches (e.g. after initial load) */
|
||||
useEffect(() => {
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect -- sync from server
|
||||
setValue(initialValue);
|
||||
lastSaved.current = initialValue;
|
||||
}, [initialValue]);
|
||||
|
||||
@@ -49,6 +49,7 @@ export function ContentChecklistsPanel() {
|
||||
|
||||
useEffect(() => {
|
||||
if (!data?.items) return;
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect -- sync from server
|
||||
setItems(
|
||||
CHECKLIST_ORDER
|
||||
.filter((k) => k in data.items)
|
||||
|
||||
@@ -40,6 +40,7 @@ export function DiscussionRulesPanel() {
|
||||
useEffect(() => {
|
||||
if (!data?.items) return;
|
||||
const order = ["universal", "rejection", "partial_acceptance", "full_acceptance", "betterment_levy"];
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect -- sync from server
|
||||
setSections(
|
||||
order
|
||||
.filter((k) => k in data.items)
|
||||
|
||||
@@ -46,6 +46,7 @@ export function GoldenRatiosPanel() {
|
||||
// Sync from server
|
||||
useEffect(() => {
|
||||
if (!data?.items) return;
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect -- sync from server
|
||||
setCards(
|
||||
Object.entries(data.items).map(([key, item]) => ({
|
||||
key,
|
||||
|
||||
@@ -474,7 +474,6 @@ function PendingPanel() {
|
||||
useEffect(() => {
|
||||
if (focusedId === null) return;
|
||||
if (visibleItems.some((h) => h.id === focusedId)) return;
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
setFocusedId(visibleItems[0]?.id ?? null);
|
||||
}, [focusedId, visibleItems]);
|
||||
|
||||
|
||||
@@ -239,7 +239,7 @@ export function PrecedentEditSheet({ caseLawId, onOpenChange }: Props) {
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label htmlFor="chair-name">יו"ר</Label>
|
||||
<Label htmlFor="chair-name">יו"ר</Label>
|
||||
<Input id="chair-name" value={form.chair_name}
|
||||
onChange={(e) => setForm({ ...form, chair_name: e.target.value })}
|
||||
placeholder="" />
|
||||
|
||||
@@ -75,15 +75,11 @@ export function PrecedentUploadSheet({ open, onOpenChange }: Props) {
|
||||
|
||||
useEffect(() => {
|
||||
if (open) return;
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect -- reset form on close
|
||||
setFile(null); setCitation(""); setCaseName(""); setCourt("");
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
setDecisionDate(""); setSourceType(""); setPrecedentLevel("");
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
setPracticeArea(""); setAppealSubtype(""); setSubjectTags("");
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
setHeadnote(""); setIsBinding(true); setTaskId(null); setConflict(null);
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
setChairName(""); setDistrict(""); setCaseNumber("");
|
||||
}, [open]);
|
||||
|
||||
|
||||
@@ -25,11 +25,12 @@ export function SubjectDonut({
|
||||
segments: Array<{ label: string; count: number }>;
|
||||
total: number;
|
||||
}) {
|
||||
let pct = 0;
|
||||
// Prefix sums without a mutable outer accumulator (React Compiler rejects
|
||||
// reassigning a let after render). segments is tiny, so O(n²) is fine.
|
||||
const parts = segments.map((s, i) => {
|
||||
const start = total === 0 ? 0 : (pct / total) * 360;
|
||||
pct += s.count;
|
||||
const end = total === 0 ? 360 : (pct / total) * 360;
|
||||
const before = segments.slice(0, i).reduce((acc, x) => acc + x.count, 0);
|
||||
const start = total === 0 ? 0 : (before / total) * 360;
|
||||
const end = total === 0 ? 360 : ((before + s.count) / total) * 360;
|
||||
return { ...s, start, end, color: DONUT_COLORS[i % DONUT_COLORS.length] };
|
||||
});
|
||||
|
||||
|
||||
@@ -217,6 +217,7 @@ export function useProgress(taskId: string | null, caseNumber?: string) {
|
||||
|
||||
useEffect(() => {
|
||||
if (!taskId) return;
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect -- reset on taskId change
|
||||
setEvent(null);
|
||||
|
||||
/* Self-heal fallback: if no SSE message arrives within 10s — usually
|
||||
|
||||
Reference in New Issue
Block a user