Add requester filter and improve error messages
- Add requester filter to device tickets history page - Create listMachineRequesters query to list unique requesters - Add friendly API error formatting in desktop agent - Translate validation errors to user-friendly Portuguese messages 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
bb82efa9d3
commit
cf31e78edb
3 changed files with 140 additions and 5 deletions
|
|
@ -45,6 +45,7 @@ type DeviceTicketsHistoryArgs = {
|
|||
machineId: Id<"machines">
|
||||
status?: "open" | "resolved"
|
||||
priority?: string
|
||||
requesterEmail?: string
|
||||
search?: string
|
||||
from?: number
|
||||
to?: number
|
||||
|
|
@ -146,12 +147,15 @@ function getPriorityMeta(priority: TicketPriority | string | null | undefined) {
|
|||
export function DeviceTicketsHistoryClient({ tenantId: _tenantId, deviceId }: { tenantId: string; deviceId: string }) {
|
||||
const [statusFilter, setStatusFilter] = useState<"all" | "open" | "resolved">("all")
|
||||
const [priorityFilter, setPriorityFilter] = useState<string>("ALL")
|
||||
const [requesterFilter, setRequesterFilter] = useState<string>("ALL")
|
||||
const [periodPreset, setPeriodPreset] = useState<PeriodPreset>("90d")
|
||||
const [customFrom, setCustomFrom] = useState<string>("")
|
||||
const [customTo, setCustomTo] = useState<string>("")
|
||||
const [searchValue, setSearchValue] = useState<string>("")
|
||||
const [debouncedSearch, setDebouncedSearch] = useState<string>("")
|
||||
|
||||
const requesters = useQuery(api.devices.listMachineRequesters, { machineId: deviceId as Id<"machines"> })
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => {
|
||||
setDebouncedSearch(searchValue.trim())
|
||||
|
|
@ -178,6 +182,9 @@ export function DeviceTicketsHistoryClient({ tenantId: _tenantId, deviceId }: {
|
|||
if (priorityFilter !== "ALL") {
|
||||
args.priority = priorityFilter
|
||||
}
|
||||
if (requesterFilter !== "ALL") {
|
||||
args.requesterEmail = requesterFilter
|
||||
}
|
||||
if (debouncedSearch) {
|
||||
args.search = debouncedSearch
|
||||
}
|
||||
|
|
@ -188,7 +195,7 @@ export function DeviceTicketsHistoryClient({ tenantId: _tenantId, deviceId }: {
|
|||
args.to = range.to
|
||||
}
|
||||
return args
|
||||
}, [debouncedSearch, deviceId, priorityFilter, range.from, range.to, statusFilter])
|
||||
}, [debouncedSearch, deviceId, priorityFilter, requesterFilter, range.from, range.to, statusFilter])
|
||||
|
||||
const { results: tickets, status: paginationStatus, loadMore } = usePaginatedQuery(
|
||||
api.devices.listTicketsHistory,
|
||||
|
|
@ -208,6 +215,7 @@ export function DeviceTicketsHistoryClient({ tenantId: _tenantId, deviceId }: {
|
|||
const resetFilters = () => {
|
||||
setStatusFilter("all")
|
||||
setPriorityFilter("ALL")
|
||||
setRequesterFilter("ALL")
|
||||
setPeriodPreset("90d")
|
||||
setCustomFrom("")
|
||||
setCustomTo("")
|
||||
|
|
@ -271,6 +279,19 @@ export function DeviceTicketsHistoryClient({ tenantId: _tenantId, deviceId }: {
|
|||
<SelectItem value="LOW">Baixa</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<Select value={requesterFilter} onValueChange={(value) => setRequesterFilter(value)}>
|
||||
<SelectTrigger className="sm:w-[200px]">
|
||||
<SelectValue placeholder="Solicitante" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="ALL">Todos os solicitantes</SelectItem>
|
||||
{requesters?.map((requester: { email: string; name: string | null }) => (
|
||||
<SelectItem key={requester.email} value={requester.email}>
|
||||
{requester.name ?? requester.email}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="flex flex-col gap-3 sm:flex-row sm:items-center">
|
||||
<Select value={periodPreset} onValueChange={(value) => setPeriodPreset(value as PeriodPreset)}>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue