Remove extra clicks for edit and save scenarios

This commit is contained in:
akhisud3195 2025-02-14 16:30:05 +05:30
parent cca55c3773
commit 2f7688b1a6
2 changed files with 53 additions and 118 deletions

View file

@ -19,7 +19,7 @@ import { type WithStringId } from '../../../lib/types/types';
import { Scenario, SimulationRun, SimulationResult } from "../../../lib/types/testing_types"; import { Scenario, SimulationRun, SimulationResult } from "../../../lib/types/testing_types";
import { z } from 'zod'; import { z } from 'zod';
import { SimulationResultCard, ScenarioResultCard } from './components/RunComponents'; import { SimulationResultCard, ScenarioResultCard } from './components/RunComponents';
import { ScenarioViewer, ScenarioEditor } from './components/ScenarioComponents'; import { ScenarioViewer } from './components/ScenarioComponents';
type ScenarioType = WithStringId<z.infer<typeof Scenario>>; type ScenarioType = WithStringId<z.infer<typeof Scenario>>;
type SimulationRunType = WithStringId<z.infer<typeof SimulationRun>>; type SimulationRunType = WithStringId<z.infer<typeof SimulationRun>>;
@ -339,19 +339,11 @@ export default function SimulationApp() {
{/* Main content */} {/* Main content */}
<div className="flex-1 p-6 overflow-auto"> <div className="flex-1 p-6 overflow-auto">
{selectedScenario ? ( {selectedScenario ? (
isEditing ? ( <ScenarioViewer
<ScenarioEditor scenario={selectedScenario}
scenario={selectedScenario} onSave={handleUpdateScenario}
onSave={handleUpdateScenario} onClose={handleCloseScenario}
onCancel={() => setIsEditing(false)} />
/>
) : (
<ScenarioViewer
scenario={selectedScenario}
onEdit={() => setIsEditing(true)}
onClose={handleCloseScenario}
/>
)
) : ( ) : (
<div className="space-y-6"> <div className="space-y-6">
<div className="flex justify-between items-center mb-6"> <div className="flex justify-between items-center mb-6">

View file

@ -1,6 +1,6 @@
'use client'; 'use client';
import { useState } from 'react'; import { useState, useEffect } from 'react';
import { PencilIcon, XMarkIcon, DocumentDuplicateIcon } from '@heroicons/react/24/outline'; import { PencilIcon, XMarkIcon, DocumentDuplicateIcon } 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";
@ -10,77 +10,18 @@ type ScenarioType = WithStringId<z.infer<typeof Scenario>>;
interface ScenarioViewerProps { interface ScenarioViewerProps {
scenario: ScenarioType; scenario: ScenarioType;
onEdit: () => void; onSave: (scenario: ScenarioType) => void;
onClose: () => void; onClose: () => void;
} }
export function ScenarioViewer({ scenario, onEdit, onClose }: ScenarioViewerProps) { export function ScenarioViewer({ scenario, onSave, onClose }: ScenarioViewerProps) {
return (
<div>
<div className="flex justify-between items-center mb-6">
<h1 className="text-2xl font-bold">{scenario.name}</h1>
<div className="flex gap-2">
<button
onClick={onEdit}
className="p-2 rounded-full hover:bg-gray-100"
title="Edit"
>
<PencilIcon className="h-5 w-5 text-gray-600" />
</button>
<button
onClick={onClose}
className="p-2 rounded-full hover:bg-gray-100"
title="Close"
>
<XMarkIcon className="h-5 w-5 text-gray-600" />
</button>
</div>
</div>
<div className="flex flex-col gap-4">
<div className="flex flex-col">
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">NAME</div>
<div className="text-base">{scenario.name}</div>
</div>
<div className="border-t border-gray-200 my-4"></div>
<div className="flex flex-col">
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">DESCRIPTION</div>
<div className="text-base whitespace-pre-wrap">{scenario.description}</div>
</div>
<div className="border-t border-gray-200 my-4"></div>
<div className="flex flex-col">
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">CRITERIA</div>
<div className="text-base whitespace-pre-wrap">{scenario.criteria}</div>
</div>
<div className="border-t border-gray-200 my-4"></div>
<div className="flex flex-col">
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">CONTEXT</div>
<div className="text-base whitespace-pre-wrap">{scenario.context}</div>
</div>
</div>
</div>
);
}
interface ScenarioEditorProps {
scenario: ScenarioType;
onSave: (scenario: ScenarioType) => void;
onCancel: () => void;
}
export function ScenarioEditor({ scenario, onSave, onCancel }: ScenarioEditorProps) {
const [name, setName] = useState(scenario.name); const [name, setName] = useState(scenario.name);
const [description, setDescription] = useState(scenario.description); const [description, setDescription] = useState(scenario.description);
const [criteria, setCriteria] = useState(scenario.criteria || ''); const [criteria, setCriteria] = useState(scenario.criteria || '');
const [context, setContext] = useState(scenario.context || ''); const [context, setContext] = useState(scenario.context || '');
const handleSubmit = (e: React.FormEvent) => { // Save changes whenever any field changes
e.preventDefault(); useEffect(() => {
onSave({ onSave({
...scenario, ...scenario,
name, name,
@ -88,80 +29,82 @@ export function ScenarioEditor({ scenario, onSave, onCancel }: ScenarioEditorPro
criteria, criteria,
context, context,
}); });
}; }, [name, description, criteria, context]);
return ( return (
<div> <div>
<div className="flex justify-between items-center mb-6"> <div className="flex justify-between items-center mb-6">
<h1 className="text-2xl font-bold">Edit Scenario</h1> <h1 className="text-2xl font-bold">Scenario Details</h1>
<div className="flex gap-2"> <button
<button onClick={onClose}
onClick={() => handleSubmit({ preventDefault: () => {} } as React.FormEvent)} className="p-2 rounded-full hover:bg-gray-100"
className="p-2 rounded-full hover:bg-gray-100" title="Close"
title="Save" >
> <XMarkIcon className="h-5 w-5 text-gray-600" />
<DocumentDuplicateIcon className="h-5 w-5 text-gray-600" /> </button>
</button>
<button
onClick={onCancel}
className="p-2 rounded-full hover:bg-gray-100"
title="Close"
>
<XMarkIcon className="h-5 w-5 text-gray-600" />
</button>
</div>
</div> </div>
<form onSubmit={handleSubmit} className="space-y-4"> <div className="flex flex-col gap-4">
<div> <div className="flex flex-col">
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">NAME</div> <div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">NAME</div>
<input <input
type="text" type="text"
value={name} value={name}
onChange={(e) => setName(e.target.value)} onChange={(e) => setName(e.target.value)}
className="mt-1 block w-full rounded-md border-2 border-gray-300 shadow-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500 px-3 py-2" 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"
placeholder="An identifiable scenario name"
/> />
</div> </div>
<div className="border-t border-gray-200 my-4"></div> <div className="border-t border-gray-200 my-4"></div>
<div> <div className="flex flex-col">
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">DESCRIPTION</div> <div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">DESCRIPTION</div>
<textarea <textarea
value={description} value={description}
onChange={(e) => setDescription(e.target.value)} onChange={(e) => setDescription(e.target.value)}
rows={4} 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"
className="mt-1 block w-full rounded-md border-2 border-gray-300 shadow-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500 px-3 py-2" style={{ height: 'auto', minHeight: '24px' }}
placeholder="Specify the user scenario that the simulator should simulate" onInput={(e) => {
const target = e.target as HTMLTextAreaElement;
target.style.height = 'auto';
target.style.height = `${target.scrollHeight}px`;
}}
/> />
</div> </div>
<div className="border-t border-gray-200 my-4"></div> <div className="border-t border-gray-200 my-4"></div>
<div> <div className="flex flex-col">
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">CRITERIA</div> <div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">CRITERIA</div>
<textarea <textarea
value={criteria} value={criteria}
onChange={(e) => setCriteria(e.target.value)} onChange={(e) => setCriteria(e.target.value)}
rows={4} 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"
className="mt-1 block w-full rounded-md border-2 border-gray-300 shadow-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500 px-3 py-2" style={{ height: 'auto', minHeight: '24px' }}
placeholder="Enter success criteria for this scenario" onInput={(e) => {
const target = e.target as HTMLTextAreaElement;
target.style.height = 'auto';
target.style.height = `${target.scrollHeight}px`;
}}
/> />
</div> </div>
<div className="border-t border-gray-200 my-4"></div> <div className="border-t border-gray-200 my-4"></div>
<div> <div className="flex flex-col">
<div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">CONTEXT</div> <div className="text-sm font-medium text-gray-500 uppercase tracking-wider mb-4">CONTEXT</div>
<textarea <textarea
value={context} value={context}
onChange={(e) => setContext(e.target.value)} onChange={(e) => setContext(e.target.value)}
rows={4} 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"
className="mt-1 block w-full rounded-md border-2 border-gray-300 shadow-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500 px-3 py-2" style={{ height: 'auto', minHeight: '24px' }}
placeholder="Provide context about the user to the assistant at the start of chat" onInput={(e) => {
const target = e.target as HTMLTextAreaElement;
target.style.height = 'auto';
target.style.height = `${target.scrollHeight}px`;
}}
/> />
</div> </div>
</form> </div>
</div> </div>
); );
} }