diff --git a/src/components/TicketProjects.jsx b/src/components/TicketProjects.jsx index e1c395e..d3838bb 100644 --- a/src/components/TicketProjects.jsx +++ b/src/components/TicketProjects.jsx @@ -1,5 +1,4 @@ -import { useState, useEffect, useCallback } from 'react' -import { FaPlus, FaLink } from 'react-icons/fa6' +import { Fragment, useState, useEffect, useCallback, useRef } from 'react' import { useWebsiteProjects } from '../hooks/useWebsiteProjects' import { createProjectFromTemplate, importNewReposThrottled } from '../lib/projectAdminApi' import { isOutsideOrg, assignSummary, assignableProjects } from '../lib/projectAssign' @@ -7,6 +6,7 @@ import { slugify } from '../lib/subdomain' import AssignedProjectCard from './AssignedProjectCard' import { fetchServices, completeAssignment } from '../lib/projectKindsApi' import { kindLabelFor } from '../lib/assignFlow' +import { Card, Button, Dialog } from './ui' // Projekte am Ticket: Liste, Zuweisen, Loesen und neues Projekt an einer Stelle. // Loesen nimmt das Projekt nur vom Ticket; die Kundenzuordnung (Sichtbarkeit im Portal) bleibt. @@ -29,12 +29,18 @@ export default function TicketProjects({ ticket }) { fetchServices().then((s) => setKinds(s.kinds || [])).catch(() => {}) }, []) + // Neu laden (samt "Suche neue Repos ...") nur bei einem anderen Ticket, nicht bei Status, Zustaendig oder Dringend: + // load haengt an der Ticket-ID, den jeweils neuesten Ticketstand (Kunde) liest es ueber ticketRef + const ticketRef = useRef(ticket) + ticketRef.current = ticket + const ticketId = ticket?.$id + const load = useCallback(async () => { - if (!ticket?.$id) return - const [all, mine] = await Promise.all([fetchAllProjects(), fetchByTicketId(ticket.$id)]) + if (!ticketId) return + const [all, mine] = await Promise.all([fetchAllProjects(), fetchByTicketId(ticketId)]) setAssigned(mine) - setAvailable(assignableProjects(all, ticket, new Set(mine.map((p) => p.$id)))) - }, [ticket, fetchAllProjects, fetchByTicketId]) + setAvailable(assignableProjects(all, ticketRef.current, new Set(mine.map((p) => p.$id)))) + }, [ticketId, fetchAllProjects, fetchByTicketId]) useEffect(() => { let cancelled = false @@ -156,16 +162,15 @@ export default function TicketProjects({ ticket }) { } return ( -
Suche neue Repos …
} - {importHint &&Suche neue Repos …
} + {importHint &&{importHint}
} + {error &&{error}
} {assigned.length === 0 - ?Noch kein Projekt an diesem Ticket.
+ ?Noch kein Projekt an diesem Ticket.
: assigned.map((p) => (+ {assignResult.text} {assignResult.warnings.map((w, i) => ( -
Bitte wähle die Art des Projekts, bevor es zugewiesen wird.
- {kinds.length === 0 && ( -