import { linter } from '@codemirror/lint'; import type { HttpRequest } from '@yaakapp-internal/models'; import { patchModel } from '@yaakapp-internal/models'; import { useCallback, useMemo } from 'react'; import { useKeyValue } from '../hooks/useKeyValue'; import { textLikelyContainsJsonComments } from '../lib/jsonComments'; import { Banner } from './core/Banner'; import type { DropdownItem } from './core/Dropdown'; import { Dropdown } from './core/Dropdown'; import type { EditorProps } from './core/Editor/Editor'; import { jsonParseLinter } from './core/Editor/json-lint'; import { Editor } from './core/Editor/LazyEditor'; import { Icon } from './core/Icon'; import { IconButton } from './core/IconButton'; import { IconTooltip } from './core/IconTooltip'; interface Props { forceUpdateKey: string; heightMode: EditorProps['heightMode']; request: HttpRequest; } export function JsonBodyEditor({ forceUpdateKey, heightMode, request }: Props) { const handleChange = useCallback( (text: string) => patchModel(request, { body: { ...request.body, text } }), [request], ); const autoFix = request.body?.sendJsonComments !== true; const lintExtension = useMemo( () => linter( jsonParseLinter( autoFix ? { allowComments: true, allowTrailingCommas: true } : { allowComments: false, allowTrailingCommas: false }, ), ), [autoFix], ); const hasComments = useMemo( () => textLikelyContainsJsonComments(request.body?.text ?? ''), [request.body?.text], ); const { value: bannerDismissed, set: setBannerDismissed } = useKeyValue({ namespace: 'no_sync', key: ['json-fix-3', request.workspaceId], fallback: false, }); const handleToggleAutoFix = useCallback(() => { const newBody = { ...request.body }; if (autoFix) { newBody.sendJsonComments = true; } else { delete newBody.sendJsonComments; } patchModel(request, { body: newBody }); }, [request, autoFix]); const handleDropdownOpen = useCallback(() => { if (!bannerDismissed) { setBannerDismissed(true); } }, [bannerDismissed, setBannerDismissed]); const showBanner = hasComments && autoFix && !bannerDismissed; const stripMessage = 'Automatically strip comments and trailing commas before sending'; const actions = useMemo( () => [ showBanner && (

Auto-fix enabled

),
, leftSlot: ( ), }, ] satisfies DropdownItem[] } >
, ], [handleDropdownOpen, handleToggleAutoFix, autoFix, showBanner], ); return ( ); }