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:
1 parent
2ecc0b627a
commit
30b3caee34
6 files changed
+10
-7
No files matched your search
@@ -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)]))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
@@ -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)',
|
||||||
|
|||||||
@@ -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>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in new issue
Block a user