Files
configucci/src/componets/env/EnvironmentParam.tsx
2026-02-20 16:02:43 +03:00

105 lines
3.0 KiB
TypeScript

import { useState } from 'react';
import { Check, Minus } from 'lucide-react';
import { Button, Input } from '../../components/ui';
import { EnvParam } from '../../models/EnvParam';
import { AddEvent, RemoveEvent, UpdateEvent } from '../../models/Env';
interface EnvironmentParamProps {
param: EnvParam;
onChanged: (event: AddEvent<EnvParam> | RemoveEvent<EnvParam> | UpdateEvent<EnvParam>) => void;
isNew: boolean;
}
export function EnvironmentParam({ param, onChanged, isNew }: EnvironmentParamProps) {
const [localParam, setLocalParam] = useState(param);
const [isFocused, setIsFocused] = useState(false);
function updateParam(updates: Partial<EnvParam>) {
const updated = localParam.update(updates).markChanged(true);
setLocalParam(updated);
}
function handleChange() {
if (!localParam.isChanged) return;
const savedParam = localParam.markChanged(false);
if (!isNew) {
onChanged(UpdateEvent.update(savedParam));
}
setLocalParam(savedParam);
}
function handleAdd() {
onChanged(AddEvent.add(localParam));
setLocalParam(new EnvParam(0, '', ''));
}
function handleKeyUp(event: React.KeyboardEvent<HTMLInputElement>) {
if (event.key === 'Enter') {
handleChange();
}
}
const isChangedClass = localParam.isChanged ? 'ring-2 ring-yellow-400 border-yellow-400' : '';
const focusedClass = isFocused ? 'bg-blue-50' : '';
return (
<div
className={`
grid grid-cols-12 gap-1 p-1 rounded-lg transition-all duration-200
${isChangedClass}
${focusedClass ? 'bg-blue-50' : 'bg-white'}
hover:bg-slate-50
`}
>
<div className="col-span-4">
<Input
value={localParam.name ?? ''}
onChange={(e) => updateParam({ name: e.target.value })}
onBlur={() => { handleChange(); setIsFocused(false); }}
onFocus={() => setIsFocused(true)}
onKeyUp={handleKeyUp}
placeholder="Parameter name"
className="text-sm"
/>
</div>
<div className="col-span-7">
<Input
value={localParam.value ?? ''}
onChange={(e) => updateParam({ value: e.target.value })}
onBlur={() => { handleChange(); setIsFocused(false); }}
onFocus={() => setIsFocused(true)}
onKeyUp={handleKeyUp}
placeholder="Parameter value"
className="text-sm"
/>
</div>
<div className="col-span-1 flex items-center justify-center">
{isNew ? (
<Button
variant="success"
size="sm"
onClick={handleAdd}
title="Add parameter"
icon={Check}
className="px-2"
/>
) : (
<Button
variant="secondary"
size="sm"
onClick={() => onChanged(new RemoveEvent(localParam))}
title="Remove parameter"
icon={Minus}
className="px-2 text-red-600 hover:text-red-700 hover:bg-red-50"
/>
)}
</div>
</div>
);
}