Projektarten: Zuordnen-Seite nachgebessert

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-09-30 17:44:55 +00:00
1 parent 7e79dac6b4
commit 8653756935
1 file changed
+19 -7
+19 -7
View File
@@ -44,6 +44,8 @@ export default function AssignProjectPage() {
const [showNewCustomer, setShowNewCustomer] = useState(false)
const [tickets, setTickets] = useState([])
const [ticketsLoading, setTicketsLoading] = useState(false)
const [ticketsError, setTicketsError] = useState(false)
const [ticketsReload, setTicketsReload] = useState(0)
const [previewOn, setPreviewOn] = useState(true)
const [subdomain, setSubdomain] = useState('')
const [busy, setBusy] = useState(false)
@@ -75,17 +77,20 @@ export default function AssignProjectPage() {
if (state.step !== 'ticket' || !state.customerId) return
let cancelled = false
setTicketsLoading(true)
setTicketsError(false)
databases
.listDocuments(DATABASE_ID, COLLECTIONS.WORKORDERS, [
Query.equal('customerId', state.customerId),
Query.notEqual('status', 'Closed'),
Query.notEqual('status', 'Cancelled'),
Query.orderDesc('$createdAt'),
Query.limit(200),
])
.then((r) => { if (!cancelled) setTickets(r.documents || []) })
.catch(() => { if (!cancelled) setTickets([]) })
.catch(() => { if (!cancelled) { setTickets([]); setTicketsError(true) } })
.finally(() => { if (!cancelled) setTicketsLoading(false) })
return () => { cancelled = true }
}, [state.step, state.customerId])
}, [state.step, state.customerId, ticketsReload])
const openTickets = useMemo(() => openTicketsFor(tickets, state.customerId), [tickets, state.customerId])
@@ -142,7 +147,7 @@ export default function AssignProjectPage() {
}
try {
const result = await completeAssignment(id, body)
let path = '/projects'
let path = state.forCustomer ? '/projects' : '/services'
if (result.ticketId) {
try {
const t = await databases.getDocument(DATABASE_ID, COLLECTIONS.WORKORDERS, result.ticketId)
@@ -183,7 +188,7 @@ export default function AssignProjectPage() {
<div style={{ fontWeight: 700, fontSize: 18 }}>{repoName || project.projectName}</div>
<div className="muted" style={{ marginTop: 4 }}>
{repoUrl && <a href={repoUrl} target="_blank" rel="noreferrer">Repository in Gitea öffnen</a>}
{project.$createdAt && <> · angelegt am {fmtDate(project.$createdAt)}{project.createdByGitea ? ' (über Gitea)' : ''}</>}
{project.$createdAt && <> · angelegt am {fmtDate(project.$createdAt)}{project.createdByGitea ? ` von ${project.createdByGitea}` : ''}</>}
</div>
</Card>
)
@@ -239,7 +244,7 @@ export default function AssignProjectPage() {
key={k.key}
variant={state.kind === k.key ? 'primary' : 'default'}
style={{ padding: '18px 12px', fontSize: 16, fontWeight: 700 }}
onClick={() => patch({ kind: k.key })}
onClick={() => patch({ kind: k.key, newTicket: null, ticketId: '' })}
>
{k.label}
</Button>
@@ -298,7 +303,12 @@ export default function AssignProjectPage() {
{state.step === 'ticket' && (
<>
{ticketsLoading ? <FaSpinner className="spinner" /> : (
{ticketsLoading ? <FaSpinner className="spinner" /> : ticketsError ? (
<div style={{ marginBottom: 12 }}>
<div className="text-red" style={{ marginBottom: 8 }}>Die Tickets des Kunden konnten nicht geladen werden.</div>
<Button onClick={() => setTicketsReload((n) => n + 1)}>Erneut versuchen</Button>
</div>
) : (
<div className="list" style={{ marginBottom: 12 }}>
{openTickets.map((t) => (
<div key={t.$id} className="list-row" style={{ cursor: 'pointer', background: state.ticketId === t.$id ? 'var(--surface-2)' : undefined }}
@@ -313,7 +323,9 @@ export default function AssignProjectPage() {
{openTickets.length === 0 && <div className="muted" style={{ padding: 12 }}>Dieser Kunde hat keine offenen Tickets.</div>}
</div>
)}
<Button variant={state.newTicket ? 'primary' : 'default'} onClick={startNewTicket}><FaPlus /> Neues Ticket anlegen</Button>
{!ticketsError && !ticketsLoading && (
<Button variant={state.newTicket ? 'primary' : 'default'} onClick={startNewTicket}><FaPlus /> Neues Ticket anlegen</Button>
)}
{state.newTicket && (
<div style={{ marginTop: 12 }}>
<div className="flex gap-3 wrap">