121 lines
3.6 KiB
TypeScript
121 lines
3.6 KiB
TypeScript
import React, { useState } from 'react';
|
|
import ContainerProperties from '../../Interfaces/Properties';
|
|
import { INPUT_TYPES } from './PropertiesInputTypes';
|
|
|
|
interface IPropertiesProps {
|
|
properties?: ContainerProperties
|
|
onChange: (key: string, value: string | number | boolean) => void
|
|
onSubmit: (event: React.FormEvent<HTMLFormElement>, refs: Array<React.RefObject<HTMLInputElement>>) => void
|
|
}
|
|
|
|
export const Properties: React.FC<IPropertiesProps> = (props: IPropertiesProps) => {
|
|
if (props.properties === undefined) {
|
|
return <div></div>;
|
|
}
|
|
|
|
const [isDynamicInput, setIsDynamicInput] = useState<boolean>(true);
|
|
|
|
const groupInput: React.ReactNode[] = [];
|
|
const refs: Array<React.RefObject<HTMLInputElement>> = [];
|
|
Object
|
|
.entries(props.properties)
|
|
.forEach((pair) => handleProperties(pair, groupInput, refs, isDynamicInput, props.onChange));
|
|
|
|
const form = isDynamicInput
|
|
? <div>
|
|
{ groupInput }
|
|
</div>
|
|
: <form
|
|
key={props.properties.id}
|
|
onSubmit={(event) => props.onSubmit(event, refs)}
|
|
>
|
|
<input type='submit' className='normal-btn' value='Submit'/>
|
|
{ groupInput }
|
|
</form>
|
|
;
|
|
|
|
return (
|
|
<div className='h-3/5 p-3 bg-slate-200 overflow-y-auto'>
|
|
<input
|
|
type='checkbox'
|
|
onChange={() => { setIsDynamicInput(!isDynamicInput); }}
|
|
checked={isDynamicInput}
|
|
/>
|
|
{ form }
|
|
</div>
|
|
);
|
|
};
|
|
|
|
const handleProperties = (
|
|
[key, value]: [string, string | number],
|
|
groupInput: React.ReactNode[],
|
|
refs: Array<React.RefObject<HTMLInputElement>>,
|
|
isDynamicInput: boolean,
|
|
onChange: (key: string, value: string | number | boolean) => void
|
|
): void => {
|
|
const id = `property-${key}`;
|
|
let type = 'text';
|
|
let checked;
|
|
|
|
/// hardcoded stuff for ergonomy ///
|
|
if (typeof value === 'boolean') {
|
|
checked = value;
|
|
}
|
|
|
|
if (key in INPUT_TYPES) {
|
|
type = INPUT_TYPES[key];
|
|
}
|
|
|
|
const ref: React.RefObject<HTMLInputElement> = React.useRef<HTMLInputElement>(null);
|
|
refs.push(ref);
|
|
|
|
const isDisabled = ['id', 'parentId'].includes(key);
|
|
if (isDynamicInput) {
|
|
groupInput.push(
|
|
<div key={id} className='mt-4'>
|
|
<label className='text-sm font-medium text-gray-800' htmlFor={id}>{key}</label>
|
|
<input
|
|
className='text-base font-medium transition-all text-gray-800 mt-1 block w-full px-3 py-2
|
|
bg-white border-2 border-white rounded-lg placeholder-gray-800
|
|
focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500
|
|
disabled:bg-slate-300 disabled:text-gray-500 disabled:border-slate-300 disabled:shadow-none
|
|
'
|
|
type={type}
|
|
id={id}
|
|
ref={ref}
|
|
value={value}
|
|
checked={checked}
|
|
onChange={(event) => {
|
|
if (type === 'checkbox') {
|
|
onChange(key, event.target.checked);
|
|
return;
|
|
}
|
|
onChange(key, event.target.value);
|
|
}}
|
|
disabled={isDisabled}
|
|
/>
|
|
</div>
|
|
);
|
|
return;
|
|
}
|
|
|
|
///
|
|
groupInput.push(
|
|
<div key={id} className='mt-4'>
|
|
<label className='text-sm font-medium text-gray-800' htmlFor={id}>{key}</label>
|
|
<input
|
|
className='text-base font-medium transition-all text-gray-800 mt-1 block w-full px-3 py-2
|
|
bg-white border-2 border-white rounded-lg placeholder-gray-800
|
|
focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500
|
|
disabled:bg-slate-300 disabled:text-gray-500 disabled:border-slate-300 disabled:shadow-none
|
|
'
|
|
type={type}
|
|
id={key}
|
|
ref={ref}
|
|
defaultValue={value}
|
|
defaultChecked={checked}
|
|
disabled={isDisabled}
|
|
/>
|
|
</div>
|
|
);
|
|
};
|