fix(mentions): search numeric references directly in DB and avoid Tiptap duplicate 'link' extension by configuring link via StarterKit
This commit is contained in:
parent
4374b1c777
commit
e6c841383e
2 changed files with 46 additions and 36 deletions
|
|
@ -43,35 +43,46 @@ export async function GET(request: Request) {
|
||||||
|
|
||||||
const numericQuery = /^\d+$/.test(query)
|
const numericQuery = /^\d+$/.test(query)
|
||||||
|
|
||||||
const take = numericQuery ? MAX_RESULTS : MAX_SCAN
|
// Fast path for numeric query: exact reference match at DB level
|
||||||
|
let filtered: any[] = []
|
||||||
const tickets = await prisma.ticket.findMany({
|
if (numericQuery) {
|
||||||
where: whereBase,
|
const ref = Number(query)
|
||||||
include: {
|
const exact = await prisma.ticket.findMany({
|
||||||
assignee: { select: { name: true } },
|
where: { ...whereBase, reference: ref },
|
||||||
requester: { select: { name: true } },
|
include: {
|
||||||
company: { select: { name: true } },
|
assignee: { select: { name: true } },
|
||||||
},
|
requester: { select: { name: true } },
|
||||||
orderBy: { updatedAt: "desc" },
|
company: { select: { name: true } },
|
||||||
take,
|
},
|
||||||
})
|
take: MAX_RESULTS,
|
||||||
|
|
||||||
const lowered = query.toLowerCase()
|
|
||||||
|
|
||||||
const filtered = tickets
|
|
||||||
.filter((ticket) => {
|
|
||||||
if (!query) return true
|
|
||||||
const referenceMatch = String(ticket.reference).includes(query)
|
|
||||||
if (referenceMatch) return true
|
|
||||||
const subject = ticket.subject ?? ""
|
|
||||||
if (subject.toLowerCase().includes(lowered)) return true
|
|
||||||
const requesterName = ticket.requester?.name ?? ""
|
|
||||||
if (requesterName.toLowerCase().includes(lowered)) return true
|
|
||||||
const companyName = ticket.company?.name ?? ""
|
|
||||||
if (companyName.toLowerCase().includes(lowered)) return true
|
|
||||||
return false
|
|
||||||
})
|
})
|
||||||
.slice(0, MAX_RESULTS)
|
filtered = exact
|
||||||
|
} else {
|
||||||
|
const tickets = await prisma.ticket.findMany({
|
||||||
|
where: whereBase,
|
||||||
|
include: {
|
||||||
|
assignee: { select: { name: true } },
|
||||||
|
requester: { select: { name: true } },
|
||||||
|
company: { select: { name: true } },
|
||||||
|
},
|
||||||
|
orderBy: { updatedAt: "desc" },
|
||||||
|
take: MAX_SCAN,
|
||||||
|
})
|
||||||
|
|
||||||
|
const lowered = query.toLowerCase()
|
||||||
|
filtered = tickets
|
||||||
|
.filter((ticket) => {
|
||||||
|
if (!query) return true
|
||||||
|
const subject = ticket.subject ?? ""
|
||||||
|
if (subject.toLowerCase().includes(lowered)) return true
|
||||||
|
const requesterName = ticket.requester?.name ?? ""
|
||||||
|
if (requesterName.toLowerCase().includes(lowered)) return true
|
||||||
|
const companyName = ticket.company?.name ?? ""
|
||||||
|
if (companyName.toLowerCase().includes(lowered)) return true
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
.slice(0, MAX_RESULTS)
|
||||||
|
}
|
||||||
|
|
||||||
const basePath = isAgentOrAdmin ? "/tickets" : "/portal/tickets"
|
const basePath = isAgentOrAdmin ? "/tickets" : "/portal/tickets"
|
||||||
|
|
||||||
|
|
@ -93,4 +104,3 @@ export async function GET(request: Request) {
|
||||||
|
|
||||||
return NextResponse.json({ items })
|
return NextResponse.json({ items })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import {
|
||||||
import type { ReactNode } from "react"
|
import type { ReactNode } from "react"
|
||||||
import { useEditor, EditorContent } from "@tiptap/react"
|
import { useEditor, EditorContent } from "@tiptap/react"
|
||||||
import StarterKit from "@tiptap/starter-kit"
|
import StarterKit from "@tiptap/starter-kit"
|
||||||
import Link from "@tiptap/extension-link"
|
|
||||||
import Placeholder from "@tiptap/extension-placeholder"
|
import Placeholder from "@tiptap/extension-placeholder"
|
||||||
import Mention from "@tiptap/extension-mention"
|
import Mention from "@tiptap/extension-mention"
|
||||||
import { ReactRenderer } from "@tiptap/react"
|
import { ReactRenderer } from "@tiptap/react"
|
||||||
|
|
@ -412,12 +411,13 @@ export function RichTextEditor({
|
||||||
StarterKit.configure({
|
StarterKit.configure({
|
||||||
bulletList: { keepMarks: true },
|
bulletList: { keepMarks: true },
|
||||||
orderedList: { keepMarks: true },
|
orderedList: { keepMarks: true },
|
||||||
}),
|
// Configure built-in link from StarterKit to avoid duplicate extension
|
||||||
Link.configure({
|
link: {
|
||||||
openOnClick: true,
|
openOnClick: true,
|
||||||
autolink: true,
|
autolink: true,
|
||||||
protocols: ["http", "https", "mailto"],
|
protocols: ["http", "https", "mailto"],
|
||||||
HTMLAttributes: { rel: "noopener noreferrer", target: "_blank" },
|
HTMLAttributes: { rel: "noopener noreferrer", target: "_blank" },
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
Placeholder.configure({ placeholder }),
|
Placeholder.configure({ placeholder }),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue