chore(frontend): limpiar lint errors pre-existentes

11 errores en archivos pre-existentes (0 en rubros/). Categorización:
2 bugs reales removidos, 1 FP con disable comentado, 8 FPs suprimidos con eslint-disable-next-line.

Files:
- src/web/src/components/ui/badge.tsx — react-refresh/only-export-components (FP: shadcn/ui co-ubica badgeVariants con el componente por diseño)
- src/web/src/components/ui/button.tsx — react-refresh/only-export-components (FP: ídem, buttonVariants)
- src/web/src/components/ui/form.tsx — react-refresh/only-export-components (FP: shadcn/ui co-ubica useFormField hook)
- src/web/src/pages/admin/audit/AuditFilters.tsx — react-refresh/only-export-components x2 (FP: EMPTY_FILTERS y toApiFilter co-ubicados con el componente que los consume)
- src/web/src/features/permisos/components/RolPermisosEditor.tsx — react-hooks/set-state-in-effect (FP: patrón válido de derived state desde prop externa asignados)
- src/web/src/features/users/components/PermisosEditor.tsx — react-hooks/set-state-in-effect (FP: ídem, permisoData → mapa local de overrides)
- src/web/src/pages/admin/audit/AuditPage.tsx — react-hooks/set-state-in-effect (FP: acumulación de páginas paginadas desde query externa)
- src/web/src/features/users/pages/CreateUserPage.tsx — @typescript-eslint/no-unused-vars (FP: _created existe por contrato de callback, no se necesita el valor)
- src/web/src/lib/dateFormat.ts — @typescript-eslint/no-unused-vars (FP: _opts reservado para extensibilidad futura; formato hardcodeado por compatibilidad Intl)
- src/web/src/tests/api/axiosClient.test.ts — @typescript-eslint/no-unused-vars (bug real: requestCount incrementado en mock handler pero nunca asercionado; variable eliminada)
This commit is contained in:
2026-04-18 21:00:00 -03:00
parent 8353f73230
commit 50a3c87b14
10 changed files with 10 additions and 3 deletions

View File

@@ -33,4 +33,5 @@ function Badge({ className, variant, ...props }: BadgeProps) {
) )
} }
// eslint-disable-next-line react-refresh/only-export-components -- shadcn/ui generated: badgeVariants is intentionally co-located with the component
export { Badge, badgeVariants } export { Badge, badgeVariants }

View File

@@ -53,4 +53,5 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
) )
Button.displayName = "Button" Button.displayName = "Button"
// eslint-disable-next-line react-refresh/only-export-components -- shadcn/ui generated: buttonVariants is intentionally co-located with the component
export { Button, buttonVariants } export { Button, buttonVariants }

View File

@@ -165,6 +165,7 @@ const FormMessage = React.forwardRef<
FormMessage.displayName = 'FormMessage' FormMessage.displayName = 'FormMessage'
export { export {
// eslint-disable-next-line react-refresh/only-export-components -- shadcn/ui generated: useFormField hook is intentionally co-located with form components
useFormField, useFormField,
Form, Form,
FormItem, FormItem,

View File

@@ -33,6 +33,7 @@ export function RolPermisosEditor({ rolCodigo }: RolPermisosEditorProps) {
// Prefill checkboxes cuando lleguen los permisos asignados al rol // Prefill checkboxes cuando lleguen los permisos asignados al rol
useEffect(() => { useEffect(() => {
if (asignados) { if (asignados) {
// eslint-disable-next-line react-hooks/set-state-in-effect -- sincroniza prop externa (asignados) con estado local; patrón válido de derived state
setSelected(new Set(asignados.map((p) => p.codigo))) setSelected(new Set(asignados.map((p) => p.codigo)))
setSaved(false) setSaved(false)
} }

View File

@@ -59,6 +59,7 @@ export function PermisosEditor({ userId }: PermisosEditorProps) {
for (const c of permisoData.overrides.grant) map.set(c, 'concedido') for (const c of permisoData.overrides.grant) map.set(c, 'concedido')
// Apply deny overrides // Apply deny overrides
for (const c of permisoData.overrides.deny) map.set(c, 'denegado') for (const c of permisoData.overrides.deny) map.set(c, 'denegado')
// eslint-disable-next-line react-hooks/set-state-in-effect -- sincroniza prop externa (permisoData) con mapa local de overrides; patrón válido de derived state
setStates(map) setStates(map)
setSaveError(null) setSaveError(null)
}, [permisoData]) }, [permisoData])

View File

@@ -12,6 +12,7 @@ import type { CreatedUserDto } from '../api/createUser'
export function CreateUserPage() { export function CreateUserPage() {
const navigate = useNavigate() const navigate = useNavigate()
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- el callback recibe CreatedUserDto por contrato de UserForm pero solo necesitamos navegar
function handleSuccess(_created: CreatedUserDto) { function handleSuccess(_created: CreatedUserDto) {
void navigate('/') void navigate('/')
} }

View File

@@ -25,6 +25,7 @@ interface FormatInstantOptions {
*/ */
export function formatInstant( export function formatInstant(
iso: string, iso: string,
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- parámetro reservado para futura extensibilidad; el formato está hardcodeado por compatibilidad con entornos donde Intl.DateTimeFormat ignora dateStyle/timeStyle
_opts: FormatInstantOptions = { dateStyle: 'short', timeStyle: 'medium' } _opts: FormatInstantOptions = { dateStyle: 'short', timeStyle: 'medium' }
): string { ): string {
const parts = new Intl.DateTimeFormat('es-AR', { const parts = new Intl.DateTimeFormat('es-AR', {

View File

@@ -13,6 +13,7 @@ export interface AuditFiltersValue {
to: string to: string
} }
// eslint-disable-next-line react-refresh/only-export-components -- constante de reset co-ubicada con el componente que la consume como valor inicial
export const EMPTY_FILTERS: AuditFiltersValue = { export const EMPTY_FILTERS: AuditFiltersValue = {
actor: '', actor: '',
targetType: '', targetType: '',
@@ -137,6 +138,7 @@ export function AuditFilters({
* Los convertimos a ISO UTC vía `parseArgentinaDateTimeToUtc()` (fix BUG-FE-05). * Los convertimos a ISO UTC vía `parseArgentinaDateTimeToUtc()` (fix BUG-FE-05).
* - Strings vacíos → omitidos. * - Strings vacíos → omitidos.
*/ */
// eslint-disable-next-line react-refresh/only-export-components -- función utilitaria de mapeo co-ubicada con el componente que la necesita; extraerla a otro archivo aumentaría la fragmentación innecesariamente
export function toApiFilter( export function toApiFilter(
value: AuditFiltersValue, value: AuditFiltersValue,
): import('@/api/audit').AuditEventsFilter { ): import('@/api/audit').AuditEventsFilter {

View File

@@ -67,6 +67,7 @@ export function AuditPage() {
useEffect(() => { useEffect(() => {
if (!data) return if (!data) return
if (cursor === undefined) { if (cursor === undefined) {
// eslint-disable-next-line react-hooks/set-state-in-effect -- acumula datos paginados de una query externa; reset en primera página es intencional
setAccumulated(data.items) setAccumulated(data.items)
} else { } else {
setAccumulated((prev) => { setAccumulated((prev) => {

View File

@@ -131,11 +131,8 @@ describe('axiosClient', () => {
setAuth('expired-access', 'valid-refresh') setAuth('expired-access', 'valid-refresh')
let refreshCallCount = 0 let refreshCallCount = 0
let requestCount = 0
server.use( server.use(
http.get(`${API_URL}/api/v1/protected`, ({ request }) => { http.get(`${API_URL}/api/v1/protected`, ({ request }) => {
requestCount++
const auth = request.headers.get('Authorization') const auth = request.headers.get('Authorization')
if (auth === 'Bearer new-access-from-refresh') { if (auth === 'Bearer new-access-from-refresh') {
return HttpResponse.json({ data: 'ok' }) return HttpResponse.json({ data: 'ok' })