I’m developing a component for the right sidebar to create a form and send it via API to an external application. The problem I have is that I need to send the StudyUID and SerieUID of the series and study currently displayed in the viewer. But I have no way to obtain them and all the solutions I see don’t help me. How could I do it?
I’m using the master branch of the repository to develop the component and I get the images through a URL like dicomjson
My new component is placed like this: "platform/ui-next/src/components/CustomForm/CustomForm.tsx
And looks like this
import React, { useState, useEffect, useRef } from 'react';
interface TipoSerieOption {
id: number;
modalidad_id: number;
nombre: string;
created_at: string;
updated_at: string;
}
function CustomForm() {
const urlParams = new URLSearchParams(window.location.search);
const id_caso = urlParams.get("id_caso");
const id_user = urlParams.get("user_id");
const externalApiToken = LARAVEL_TOKEN || '';
const laravelUrl = LARAVEL_URL || '';
const [studyInfo, setStudyInfo] = useState(null);
const [formData, setFormData] = useState({
id_usuario: id_user || '',
id_caso: id_caso || '',
uso: '',
informe_presente: false,
informe_ok: false,
cumple_objetivos: false,
ventana_ok: false,
contraste_suficiente: false,
grosor_ok: false,
fecha_reciente: false,
no_artefactado: false,
});
const [typeOptions, setTypeOptions] = useState<TipoSerieOption[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [submitting, setSubmitting] = useState(false);
const handleChange = (e) => {
const { name, value, type, checked } = e.target;
setFormData(prevState => ({
...prevState,
[name]: type === 'checkbox' ? checked : value
}));
};
const callExternalApi = async (endpoint, method = 'GET', data = null) => {
if (!externalApiToken || !laravelUrl) {
console.error('Token o URL de API no configurados');
return;
}
const options: RequestInit = {
method,
headers: {
'Content-Type': 'application/json',
'X-API-OHIFKEY': externalApiToken
}
};
if (data && (method === 'POST' || method === 'PUT')) {
options.body = JSON.stringify(data);
}
try {
const response = await fetch(`${laravelUrl}${endpoint}`, options);
if (!response.ok) {
throw new Error(`Error en la respuesta: ${response.status} ${response.statusText}`);
}
return response.json();
} catch (error) {
console.error('Error en la llamada a la API:', error);
throw error;
}
};
const fetchTypeOptions = async () => {
try {
setLoading(true);
const data = await callExternalApi('api/v1/tiposSeries');
if (Array.isArray(data)) {
setTypeOptions(data);
if (data.length > 0) {
setFormData(prevState => ({
...prevState,
type: data[0].id.toString()
}));
}
} else {
throw new Error('El formato de datos recibido no es válido');
}
setError(null);
} catch (err) {
console.error('Error al cargar las opciones:', err);
setError('No se pudieron cargar las opciones.');
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchTypeOptions();
}, []);
const handleSubmit = async (e) => {
e.preventDefault();
console.log('Enviando formulario:', formData);
setSubmitting(true);
try {
const result = await callExternalApi('api/v1/checkEstudioDicom/store', 'POST', formData);
console.log('Respuesta de la API:', result);
alert('Registro guardado exitosamente');
} catch (error) {
console.error('Error al enviar el formulario:', error);
alert('Hubo un error al enviar el formulario');
} finally {
setSubmitting(false);
}
};
return (
<div className="p-4">
<form onSubmit={handleSubmit} className="flex flex-col space-y-4">
<div>
</div>
<div>
<label className="block text-md font-medium mb-1" style={{ color: '#fff' }}>Tipo:</label>
<select
name="type"
value={formData.type}
onChange={handleChange}
className="w-full p-2 border border-gray-300 rounded"
>
<option value=""> ---- </option>
{loading ? (
<option>Cargando...</option>
) : (
typeOptions.map(option => (
<option key={option.id} value={option.id.toString()}>
{option.nombre}
</option>
))
)}
</select>
</div>
<div>
<label className='block text-md font-medium mb-1' style={{ color: '#fff' }}>Uso</label>
<select name="uso" className="w-full p-2 border border-gray-300 rounded" onChange={handleChange} value={formData.uso}>
<option value=""> --- </option>
<option value="segm_regfijo"> Segmentar y registro fijo</option>
<option value="segm_regmovil"> Segmentar y registro móvil</option>
<option value="referencia"> Usar como referencia</option>
<option value="no_usar"> No las voy a usar </option>
</select>
</div>
<div>
<table>
<tbody>
{[
{ id: 'informe_presente', label: 'Tenemos informe radiológico para este estudio' },
{ id: 'informe_ok', label: 'El informe concuerda con lo que se ve' },
{ id: 'cumple_objetivos', label: 'La imagen permite cumplir los objetivos' },
{ id: 'ventana_ok', label: 'La ventana de adquisición es apropiada' },
{ id: 'contraste_suficiente', label: 'El contraste es suficiente' },
{ id: 'grosor_ok', label: 'El grosor de corte es apropiado' },
{ id: 'fecha_reciente', label: 'La fecha de las imágenes es reciente' },
{ id: 'no_artefactado', label: 'Las imágenes no están artefactadas' }
].map(({ id, label }) => (
<tr key={id}>
<td style={{ color: '#fff' }}>{label}</td>
<td>
<input type="checkbox" name={id} checked={formData[id]} onChange={handleChange} />
</td>
</tr>
))}
</tbody>
</table>
</div>
<button type="submit" className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 w-full" disabled={submitting}>
{submitting ? 'Guardando' : 'Guardar'}
</button>
</form>
</div>
);
}
export default CustomForm;