Phase 1b: React Query + Vitest on client
- @tanstack/react-query v5 with QueryClientProvider at app root - client/src/api/queries.ts: query-key factory, hooks for tickets, ticket, audit, comments, users, CTI tree + cascade, plus full mutation set (create/update/delete ticket, add/delete comment, CTI CRUD, user CRUD) - All page-level useEffect + useState fetching replaced: Dashboard, MyTickets, TicketDetail, NewTicket, admin/CTI, admin/Users - Dashboard preserves 300ms debounced search via separate debouncedSearch state - CTISelect cascades via useCategories / useTypes(categoryId) / useItems(typeId); dependent hooks disabled until parent selected - vitest + @testing-library/react + jsdom; 6 client tests cover SeverityBadge + StatusBadge Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import api from '../api/client';
|
||||
import { Category, CTIType, Item } from '../types';
|
||||
import { useCategories, useItems, useTypes } from '../api/queries';
|
||||
|
||||
interface CTISelectProps {
|
||||
value: { categoryId: string; typeId: string; itemId: string };
|
||||
@@ -9,34 +7,9 @@ interface CTISelectProps {
|
||||
}
|
||||
|
||||
export default function CTISelect({ value, onChange, disabled }: CTISelectProps) {
|
||||
const [categories, setCategories] = useState<Category[]>([]);
|
||||
const [types, setTypes] = useState<CTIType[]>([]);
|
||||
const [items, setItems] = useState<Item[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
api.get<Category[]>('/cti/categories').then((r) => setCategories(r.data));
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (!value.categoryId) {
|
||||
setTypes([]);
|
||||
setItems([]);
|
||||
return;
|
||||
}
|
||||
api
|
||||
.get<CTIType[]>('/cti/types', { params: { categoryId: value.categoryId } })
|
||||
.then((r) => setTypes(r.data));
|
||||
}, [value.categoryId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!value.typeId) {
|
||||
setItems([]);
|
||||
return;
|
||||
}
|
||||
api
|
||||
.get<Item[]>('/cti/items', { params: { typeId: value.typeId } })
|
||||
.then((r) => setItems(r.data));
|
||||
}, [value.typeId]);
|
||||
const { data: categories = [] } = useCategories();
|
||||
const { data: types = [] } = useTypes(value.categoryId || undefined);
|
||||
const { data: items = [] } = useItems(value.typeId || undefined);
|
||||
|
||||
const handleCategory = (categoryId: string) => {
|
||||
onChange({ categoryId, typeId: '', itemId: '' });
|
||||
|
||||
Reference in New Issue
Block a user