Files
HangmanLab.Frontend/src/components/Markdowns/TemplatedEditor.js
2025-04-14 17:02:22 +01:00

172 lines
5.9 KiB
JavaScript

import React, {useState} from "react";
import {useMarkdownTemplate} from "../../utils/queries/template-queries";
const TemplatedEditorComponent = ({ variable, value, namespace, onContentChanged }) => {
if(variable.type.base_type === "string") {
return (
<div>
<label>{namespace}{variable.name} - {variable.type.base_type}</label>
<input
type="text"
className="input"
value={value}
onChange={(e) => onContentChanged(variable.name, e.target.value)}
/>
<hr/>
</div>
);
}
if (variable.type.base_type === 'markdown') {
return(
<div>
<label>{namespace}{variable.name} - {variable.type.base_type}</label>
<textarea
className="textarea"
value={value}
onChange={(e) => onContentChanged(variable.name, e.target.value)}
/>
<hr/>
</div>
);
}
if(variable.type.base_type === "enum"){
return (
<div>
<label>{namespace}{variable.name} - {variable.type.base_type}</label>
<select
value={value}
onChange={(e) => onContentChanged(variable.name, e.target.value)}
>
{variable.type.definition.enums.map((item) => (
<option key={item} value={item}>{item}</option>
))}
</select>
<hr/>
</div>
);
}
if(variable.type.base_type === "list"){
const [cache, setCache] = useState(value);
const defaultValue = variable.type.definition.default || undefined;
const addItem = () => {
setCache(prev => {
const newCache = [...prev, defaultValue];
onContentChanged(variable.name, newCache);
return newCache;
});
};
const removeItem = (index) => {
setCache(prev => {
const newCache = prev.filter((_, i) => i!==index);
onContentChanged(variable.name, newCache);
return newCache;
})
};
const _onContentChanged = (index, value) => {
setCache(prev => {
const newCache = [...prev];
newCache[index] = value;
onContentChanged(variable.name, newCache);
return newCache;
});
};
return (
<div>
<label>{namespace}{variable.name} - {variable.type.base_type}[{variable.type.extend_type.base_type}]</label>
{cache.map((item, index) =>
(<div key={index}>
<TemplatedEditorComponent
variable={{name: index, type: variable.type.extend_type}}
value={item}
namespace={namespace}
onContentChanged={_onContentChanged}
/>
<button
className="button is-danger"
type="button"
onClick={() => removeItem(index)}
>
DELETE
</button>
</div>)
)}
<button className="button is-warning" type="button" onClick={addItem}>
ADD
</button>
<hr/>
</div>
);
}
if(variable.type.base_type === 'template'){
const {data: _template, isFetching: _templateIsFetching} = useMarkdownTemplate(variable.type.definition.template_id);
if(_templateIsFetching){
return(<p>Loading...</p>);
}
const _parameters = _template.parameters;
const _namespace = namespace + _template.title+ "::"
const _onSubChanged = (subKey, subValue) => {
const updated = {
...value,
[subKey]: subValue
};
onContentChanged(variable.name, updated);
};
return (
<div>
<label>{namespace}{variable.name} - {variable.type.base_type}</label>
{
_parameters.map((_variable, index) => (
<div key={index}>
<TemplatedEditorComponent
variable={_variable}
value={value[_variable.name]}
namespace={_namespace}
onContentChanged={_onSubChanged}
/>
</div>
))
}
<hr/>
</div>
);
}
};
const TemplatedEditor = ({content, template, onContentChanged}) => {
if(!template){
template = {
parameters: [
{
name: "markdown",
type: {
base_type: "markdown",
definition: {}
}
}
],
layout: "<markdown/>",
title: "default"
};
}
return(
<div>
{
template.parameters.map((variable, index) => (
<div key={index}>
<TemplatedEditorComponent
variable={variable}
value={content[variable.name]}
namespace={template.title+"::"}
onContentChanged={onContentChanged}
/>
</div>
))
}
</div>
);
};
export default TemplatedEditor;