Tickets: Links auf Tickets nutzen ticketPath (Planboard, Zuordnen, Services, Funktionen)

Auch drei Kommentare mit dem Altlink-Muster umformuliert (useWorkorders, ticketListUrl, TicketsPage), sonst bleibt die Pruefung auf den Altlink nicht leer.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-06 06:03:09 +00:00
1 parent 2ecc0b627a
commit 30b3caee34
6 files changed
+10 -7

No files matched your search

+1 -1
View File
@@ -78,7 +78,7 @@ export function useWorkorders(filters = {}) {
queries.push(Query.equal('assignedTo', activeFilters.assignedTo)) queries.push(Query.equal('assignedTo', activeFilters.assignedTo))
} }
// WOID-Direktsuche (z. B. Deep-Link aus den Leads: /tickets?woid=123) // WOID-Direktsuche (Altlinks aus den Leads mit woid=123 leitet TicketsPage zur Ticketseite um)
if (activeFilters.woid) { if (activeFilters.woid) {
queries.push(Query.equal('woid', [String(activeFilters.woid)])) queries.push(Query.equal('woid', [String(activeFilters.woid)]))
} }
+1 -1
View File
@@ -78,7 +78,7 @@ export function listFilters(state) {
return { ...countFilters(state, state.tab), search: state.search || undefined, limit: state.limit } return { ...countFilters(state, state.tab), search: state.search || undefined, limit: state.limit }
} }
// Altlinks "/tickets?woid=100131" fuehren zur Ticketseite und haben Vorrang vor allen Filtern // Altlinks aus den Leads (Liste mit Suchteil woid=100131) fuehren zur Ticketseite und haben Vorrang vor allen Filtern
export function woidRedirectTarget(input) { export function woidRedirectTarget(input) {
const woid = (new URLSearchParams(input).get('woid') || '').trim() const woid = (new URLSearchParams(input).get('woid') || '').trim()
return woid ? ticketPath(woid) : null return woid ? ticketPath(woid) : null
+3 -2
View File
@@ -8,6 +8,7 @@ import { fetchServices, completeAssignment, fetchProject } from '../lib/projectK
import { nextStep, prevStep, newTicketDefaults, canFinish, openTicketsFor } from '../lib/assignFlow' import { nextStep, prevStep, newTicketDefaults, canFinish, openTicketsFor } from '../lib/assignFlow'
import { suggestSubdomain, slugify } from '../lib/subdomain' import { suggestSubdomain, slugify } from '../lib/subdomain'
import { isArchived } from '../lib/leads' import { isArchived } from '../lib/leads'
import { ticketPath, ticketRef } from '../lib/ticketRoutes'
import { PageHeader, Card, Button, Field } from '../components/ui' import { PageHeader, Card, Button, Field } from '../components/ui'
import { CreateCustomerForm } from './CustomersPage' import { CreateCustomerForm } from './CustomersPage'
@@ -153,7 +154,7 @@ export default function AssignProjectPage() {
if (result.ticketId) { if (result.ticketId) {
try { try {
const t = await databases.getDocument(DATABASE_ID, COLLECTIONS.WORKORDERS, result.ticketId) const t = await databases.getDocument(DATABASE_ID, COLLECTIONS.WORKORDERS, result.ticketId)
path = `/tickets?woid=${encodeURIComponent(t.woid)}` path = ticketPath(ticketRef(t))
} catch { } catch {
path = '/tickets' path = '/tickets'
} }
@@ -402,5 +403,5 @@ function TicketLink({ ticketId }) {
databases.getDocument(DATABASE_ID, COLLECTIONS.WORKORDERS, ticketId) databases.getDocument(DATABASE_ID, COLLECTIONS.WORKORDERS, ticketId)
.then((t) => setWoid(t.woid)).catch(() => setWoid(null)) .then((t) => setWoid(t.woid)).catch(() => setWoid(null))
}, [ticketId]) }, [ticketId])
return woid ? <Link to={`/tickets?woid=${encodeURIComponent(woid)}`}>Zum Ticket #{woid}</Link> : null return woid ? <Link to={ticketPath(woid)}>Zum Ticket #{woid}</Link> : null
} }
+2 -1
View File
@@ -7,6 +7,7 @@ import { PageHeader, Card, Button } from '../components/ui'
import { useWorkorders } from '../hooks/useWorkorders' import { useWorkorders } from '../hooks/useWorkorders'
import { useEmployees } from '../hooks/useEmployees' import { useEmployees } from '../hooks/useEmployees'
import { groupAppointmentsByDay, countInRange, dayKey } from '../lib/planboard' import { groupAppointmentsByDay, countInRange, dayKey } from '../lib/planboard'
import { ticketPath } from '../lib/ticketRoutes'
/* Termine haengen an den Tickets (startDate/startTime/endTime/assignedTo); /* Termine haengen an den Tickets (startDate/startTime/endTime/assignedTo);
die Aufbereitung steckt in src/lib/planboard.js. */ die Aufbereitung steckt in src/lib/planboard.js. */
@@ -79,7 +80,7 @@ export default function PlanboardPage() {
key={entry.id} key={entry.id}
type="button" type="button"
title={`Ticket #${entry.woid} öffnen`} title={`Ticket #${entry.woid} öffnen`}
onClick={() => navigate(`/tickets?woid=${encodeURIComponent(entry.woid)}`)} onClick={() => navigate(ticketPath(entry.woid || entry.id))}
style={{ style={{
textAlign: 'left', textAlign: 'left',
border: '1px solid var(--border)', border: '1px solid var(--border)',
+2 -1
View File
@@ -4,6 +4,7 @@ import { FaSpinner } from 'react-icons/fa6'
import { dotColor } from '../lib/previewEnv' import { dotColor } from '../lib/previewEnv'
import { fetchServices } from '../lib/projectKindsApi' import { fetchServices } from '../lib/projectKindsApi'
import { servicesCards } from '../lib/servicesView' import { servicesCards } from '../lib/servicesView'
import { ticketPath } from '../lib/ticketRoutes'
import { PageHeader, Card, Button, Badge } from '../components/ui' import { PageHeader, Card, Button, Badge } from '../components/ui'
export default function ServicesPage() { export default function ServicesPage() {
@@ -69,7 +70,7 @@ export default function ServicesPage() {
{[p.customerName, p.previewUrl && 'Preview'].filter(Boolean).join(' · ') || 'Intern'} {[p.customerName, p.previewUrl && 'Preview'].filter(Boolean).join(' · ') || 'Intern'}
</div> </div>
</div> </div>
{p.woid && <Link to={`/tickets?woid=${encodeURIComponent(p.woid)}`}>Ticket #{p.woid}</Link>} {p.woid && <Link to={ticketPath(p.woid)}>Ticket #{p.woid}</Link>}
{c.key === 'missing' && ( {c.key === 'missing' && (
<Button variant="primary" onClick={() => navigate(`/projects/zuordnen/${p.id}`)}>Zuordnen</Button> <Button variant="primary" onClick={() => navigate(`/projects/zuordnen/${p.id}`)}>Zuordnen</Button>
)} )}
+1 -1
View File
@@ -26,7 +26,7 @@ import { appointmentText, assigneeLabel, ticketNumber } from '../lib/ticketView'
// Pause nach dem letzten Tastendruck, bis der Suchtext in die Adresse übernommen wird // Pause nach dem letzten Tastendruck, bis der Suchtext in die Adresse übernommen wird
const SEARCH_DELAY_MS = 300 const SEARCH_DELAY_MS = 300
// Altlinks aus den Leads (/tickets?woid=123) führen zur Ticketseite; dann läuft keine Abfrage der Liste // Altlinks aus den Leads (Liste mit Suchteil woid=123) führen zur Ticketseite; dann läuft keine Abfrage der Liste
export default function TicketsPage() { export default function TicketsPage() {
const [searchParams] = useSearchParams() const [searchParams] = useSearchParams()
const target = woidRedirectTarget(searchParams) const target = woidRedirectTarget(searchParams)