Use editable-field with save for scenarios

This commit is contained in:
akhisud3195 2025-02-19 12:42:47 +05:30
parent f1e0a83bd1
commit 68cf6d6fd1

View file

@ -1,10 +1,11 @@
'use client'; 'use client';
import { useState, useEffect, useCallback, ChangeEvent } from 'react'; import { useState, useEffect } from 'react';
import { XMarkIcon } from '@heroicons/react/24/outline'; import { XMarkIcon } from '@heroicons/react/24/outline';
import { WithStringId } from '../../../../lib/types/types'; import { WithStringId } from '../../../../lib/types/types';
import { Scenario } from "../../../../lib/types/testing_types"; import { Scenario } from "../../../../lib/types/testing_types";
import { z } from 'zod'; import { z } from 'zod';
import { EditableField } from '../../../../lib/components/editable-field';
type ScenarioType = WithStringId<z.infer<typeof Scenario>>; type ScenarioType = WithStringId<z.infer<typeof Scenario>>;
@ -16,49 +17,20 @@ interface ScenarioViewerProps {
export function ScenarioViewer({ scenario, onSave, onClose }: ScenarioViewerProps) { export function ScenarioViewer({ scenario, onSave, onClose }: ScenarioViewerProps) {
const [editedScenario, setEditedScenario] = useState<ScenarioType>(scenario); const [editedScenario, setEditedScenario] = useState<ScenarioType>(scenario);
const [saveTimeout, setSaveTimeout] = useState<NodeJS.Timeout | null>(null);
// Reset state when scenario changes // Reset state when scenario changes
useEffect(() => { useEffect(() => {
setEditedScenario(scenario); setEditedScenario(scenario);
}, [scenario]); }, [scenario]);
const handleChange = useCallback((field: keyof ScenarioType, event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => { const handleFieldChange = (field: keyof ScenarioType) => (value: string) => {
event.preventDefault(); const updatedScenario = {
const value = event.target.value; ...editedScenario,
setEditedScenario(prev => ({
...prev,
[field]: value, [field]: value,
}));
if (saveTimeout) {
clearTimeout(saveTimeout);
}
const timeoutId = setTimeout(() => {
onSave({
...editedScenario,
[field]: value,
});
}, 1000); // Increased debounce time to 1 second
setSaveTimeout(timeoutId);
}, [editedScenario, onSave, saveTimeout]);
// Cleanup timeout on unmount
useEffect(() => {
return () => {
if (saveTimeout) {
clearTimeout(saveTimeout);
}
}; };
}, [saveTimeout]); setEditedScenario(updatedScenario);
onSave(updatedScenario);
const adjustTextareaHeight = useCallback((element: HTMLTextAreaElement) => { };
element.style.height = 'auto';
element.style.height = `${element.scrollHeight}px`;
}, []);
return ( return (
<div> <div>
@ -73,62 +45,45 @@ export function ScenarioViewer({ scenario, onSave, onClose }: ScenarioViewerProp
</button> </button>
</div> </div>
<div className="flex flex-col gap-4"> <div className="flex flex-col gap-4">
<div className="flex flex-col"> <EditableField
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">NAME</div> label="NAME"
<input value={editedScenario.name}
type="text" onChange={handleFieldChange('name')}
value={editedScenario.name} placeholder="Enter scenario name..."
onChange={(e) => handleChange('name', e)} />
className="text-base border border-gray-200 rounded px-2 py-1 hover:border-gray-300 focus:border-blue-500 focus:ring-1 focus:ring-blue-500"
autoComplete="off"
spellCheck="false"
/>
</div>
<div className="border-t border-gray-200 my-4"></div> <div className="border-t border-gray-200 my-4"></div>
<div className="flex flex-col"> <EditableField
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">DESCRIPTION</div> label="DESCRIPTION"
<textarea value={editedScenario.description}
value={editedScenario.description} onChange={handleFieldChange('description')}
onChange={(e) => handleChange('description', e)} placeholder="Enter scenario description..."
onInput={(e) => adjustTextareaHeight(e.target as HTMLTextAreaElement)} multiline
className="text-base border border-gray-200 rounded px-2 py-1 hover:border-gray-300 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 min-h-[24px] resize-none" markdown
style={{ height: 'auto', minHeight: '24px' }} />
autoComplete="off"
spellCheck="false"
/>
</div>
<div className="border-t border-gray-200 my-4"></div> <div className="border-t border-gray-200 my-4"></div>
<div className="flex flex-col"> <EditableField
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">CRITERIA</div> label="CRITERIA"
<textarea value={editedScenario.criteria}
value={editedScenario.criteria} onChange={handleFieldChange('criteria')}
onChange={(e) => handleChange('criteria', e)} placeholder="Enter success criteria..."
onInput={(e) => adjustTextareaHeight(e.target as HTMLTextAreaElement)} multiline
className="text-base border border-gray-200 rounded px-2 py-1 hover:border-gray-300 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 min-h-[24px] resize-none" markdown
style={{ height: 'auto', minHeight: '24px' }} />
autoComplete="off"
spellCheck="false"
/>
</div>
<div className="border-t border-gray-200 my-4"></div> <div className="border-t border-gray-200 my-4"></div>
<div className="flex flex-col"> <EditableField
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">CONTEXT</div> label="CONTEXT"
<textarea value={editedScenario.context}
value={editedScenario.context} onChange={handleFieldChange('context')}
onChange={(e) => handleChange('context', e)} placeholder="Enter scenario context..."
onInput={(e) => adjustTextareaHeight(e.target as HTMLTextAreaElement)} multiline
className="text-base border border-gray-200 rounded px-2 py-1 hover:border-gray-300 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 min-h-[24px] resize-none" markdown
style={{ height: 'auto', minHeight: '24px' }} />
autoComplete="off"
spellCheck="false"
/>
</div>
</div> </div>
</div> </div>
); );