diff --git a/src/components/TicketProjects.jsx b/src/components/TicketProjects.jsx index 140aa67..7bd18cc 100644 --- a/src/components/TicketProjects.jsx +++ b/src/components/TicketProjects.jsx @@ -4,6 +4,8 @@ import { useWebsiteProjects } from '../hooks/useWebsiteProjects' import { createProjectFromTemplate, importNewRepos } from '../lib/projectAdminApi' import { isOutsideOrg, assignSummary } from '../lib/projectAssign' import AssignedProjectCard from './AssignedProjectCard' +import { fetchServices, completeAssignment } from '../lib/projectKindsApi' +import { kindLabelFor } from '../lib/assignFlow' function slugify(v) { return String(v || '').toLowerCase().replace(/[^a-z0-9-]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 100) @@ -35,6 +37,12 @@ export default function TicketProjects({ ticket }) { const [importing, setImporting] = useState(false) const [importHint, setImportHint] = useState('') const [assignResult, setAssignResult] = useState(null) + const [kinds, setKinds] = useState([]) + const [kindDialog, setKindDialog] = useState(false) + + useEffect(() => { + fetchServices().then((s) => setKinds(s.kinds || [])).catch(() => {}) + }, []) const load = useCallback(async () => { if (!ticket?.$id) return @@ -73,7 +81,17 @@ export default function TicketProjects({ ticket }) { } } - const assign = async () => { + const assign = () => { + const project = available.find((p) => p.$id === selected) + // Ohne Art erst "Was ist das?" fragen + if (project && !project.kind) { + setKindDialog(true) + return + } + assignPlain() + } + + const assignPlain = async () => { setBusy(true) setError('') setAssignResult(null) @@ -91,6 +109,35 @@ export default function TicketProjects({ ticket }) { } } + // Art gewaehlt: completeAssignment weist serverseitig (wie assignProject) zu, + // daher kein zusaetzliches assignProjects. + // Bei 409 (bereits zugeordnet) bewusst NICHT auf assignProjects zurueckfallen: + // das wuerde das Projekt ohne Art zuweisen. Stattdessen Meldung zeigen und neu laden. + const assignWithKind = async (kind) => { + setKindDialog(false) + setBusy(true) + setError('') + setAssignResult(null) + try { + const projectName = available.find((p) => p.$id === selected)?.projectName || '' + const r = await completeAssignment(selected, { + kind, + forCustomer: true, + customerId: ticket.customerId, + ticketId: ticket.$id, + }) + setAssignResult({ text: `${projectName || 'Projekt'} wurde zugewiesen.`, warnings: r.warnings || [] }) + setSelected('') + } catch (err) { + setError(err.status === 409 + ? `${err.message} Die Liste wurde neu geladen.` + : err.message || 'Aktion fehlgeschlagen') + } finally { + try { await load() } catch { /* Anzeige bleibt wie sie ist */ } + setBusy(false) + } + } + const unassign = (projectId) => run(async () => { const r = await unassignProject(projectId) if (!r.success) throw new Error(r.error) @@ -121,14 +168,16 @@ export default function TicketProjects({ ticket }) { {assigned.length === 0 ?
Noch kein Projekt an diesem Ticket.
: assigned.map((p) => ( -Bitte wähle die Art des Projekts, bevor es zugewiesen wird.
+