Rimosso toast 'TODO' dal bottone eye icon in Tab Template. Ora:
1. chiama Ar1Service.previewTemplatePdf(row.id) (nuovo metodo, ritorna Blob)
2. crea URL.createObjectURL + window.open('_blank')
3. revokeObjectURL dopo 60s (cleanup)
4. toast info iniziale 'Generazione anteprima...' + error toast su fail
Service: +1 metodo previewTemplatePdf(templateId) che torna Promise<Blob>
usando buildHeadersMultipart (nessun Content-Type per risposta binaria).
254 lines
11 KiB
JavaScript
254 lines
11 KiB
JavaScript
/**
|
|
* Client HTTP per ar1-compiler (microservizio BFLOWS).
|
|
* Il microservizio valida lo stesso JWT di GEPAFIN-BE (HS512 shared secret).
|
|
*
|
|
* Env var: REACT_APP_AR1_API_URL (es. http://78.46.41.91:18091)
|
|
*
|
|
* Pattern replicato 1:1 da rendicontazioneService.js.
|
|
*/
|
|
import { storeGet } from '../../../store';
|
|
|
|
const BASE_URL = process.env.REACT_APP_AR1_API_URL || '';
|
|
|
|
const buildHeaders = () => {
|
|
const token = storeGet('getToken');
|
|
const h = { 'Content-Type': 'application/json' };
|
|
if (token) h['Authorization'] = `Bearer ${token}`;
|
|
return h;
|
|
};
|
|
|
|
const buildHeadersMultipart = () => {
|
|
const token = storeGet('getToken');
|
|
const h = {};
|
|
if (token) h['Authorization'] = `Bearer ${token}`;
|
|
return h;
|
|
};
|
|
|
|
const handleResponse = async (response, onSuccess, onError) => {
|
|
let body = null;
|
|
try { body = await response.json(); } catch (e) { body = { detail: response.statusText }; }
|
|
if (response.status >= 200 && response.status < 300) {
|
|
if (onSuccess) onSuccess(body);
|
|
} else {
|
|
if (onError) onError({ status: response.status, ...body });
|
|
}
|
|
};
|
|
|
|
const handleError = (err, onError) => {
|
|
if (onError) onError({ status: 0, detail: err.message });
|
|
};
|
|
|
|
const Ar1Service = {
|
|
// ---------- Status pubblico (per compliance modal) ----------
|
|
getStatusForCompany(companyId, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/public/ar1-status/${companyId}`, {
|
|
method: 'GET', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
// ---------- CRUD form beneficiario ----------
|
|
createDraft(companyId, variant, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/api/ar1-forms`, {
|
|
method: 'POST', mode: 'cors', headers: buildHeaders(),
|
|
body: JSON.stringify({ company_id: companyId, variant })
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
getForm(formId, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/api/ar1-forms/${formId}`, {
|
|
method: 'GET', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
listFormsForCompany(companyId, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/api/ar1-forms/company/${companyId}`, {
|
|
method: 'GET', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
updateQuadri(formId, quadriPatch, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/api/ar1-forms/${formId}/quadri`, {
|
|
method: 'PUT', mode: 'cors', headers: buildHeaders(),
|
|
body: JSON.stringify({ quadri: quadriPatch })
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
submitForSignature(formId, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/api/ar1-forms/${formId}/submit-for-signature`, {
|
|
method: 'PUT', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
deleteForm(formId, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/api/ar1-forms/${formId}`, {
|
|
method: 'DELETE', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => {
|
|
if (r.status === 204) { if (onSuccess) onSuccess({}); }
|
|
else handleResponse(r, onSuccess, onError);
|
|
}).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
// ---------- PDF ----------
|
|
generatePdf(formId, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/api/ar1-forms/${formId}/generate-pdf`, {
|
|
method: 'POST', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
downloadPdfUnsigned(formId) {
|
|
return fetch(`${BASE_URL}/api/ar1-forms/${formId}/pdf-unsigned`, {
|
|
method: 'GET', mode: 'cors', headers: buildHeadersMultipart()
|
|
}).then(r => { if (!r.ok) throw new Error(`HTTP ${r.status}`); return r.blob(); });
|
|
},
|
|
|
|
downloadPdfSigned(formId) {
|
|
return fetch(`${BASE_URL}/api/ar1-forms/${formId}/pdf-signed`, {
|
|
method: 'GET', mode: 'cors', headers: buildHeadersMultipart()
|
|
}).then(r => { if (!r.ok) throw new Error(`HTTP ${r.status}`); return r.blob(); });
|
|
},
|
|
|
|
// ---------- Firma ----------
|
|
uploadSignature(formId, fileObject, onSuccess, onError) {
|
|
const formData = new FormData();
|
|
formData.append('file', fileObject);
|
|
fetch(`${BASE_URL}/api/ar1-forms/${formId}/upload-signature`, {
|
|
method: 'POST', mode: 'cors', headers: buildHeadersMultipart(),
|
|
body: formData
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
reVerifySignature(formId, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/api/ar1-forms/${formId}/verify`, {
|
|
method: 'POST', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
archiveToCompanyDocument(formId, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/api/ar1-forms/${formId}/archive-to-company-document`, {
|
|
method: 'POST', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
// ---------- ADMIN: templates ----------
|
|
listTemplates(onSuccess, onError, queryParams) {
|
|
const qs = queryParams ? ('?' + new URLSearchParams(queryParams).toString()) : '';
|
|
fetch(`${BASE_URL}/admin/ar1-templates${qs}`, {
|
|
method: 'GET', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
getTemplateDetail(templateId, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/admin/ar1-templates/${templateId}`, {
|
|
method: 'GET', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
updateTemplateLayout(templateId, layoutConfig, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/admin/ar1-templates/${templateId}/layout-config`, {
|
|
method: 'PUT', mode: 'cors', headers: buildHeaders(),
|
|
body: JSON.stringify({ layout_config: layoutConfig })
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
createNewTemplateVersion(variant, payload, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/admin/ar1-templates/${variant}/new-version`, {
|
|
method: 'POST', mode: 'cors', headers: buildHeaders(),
|
|
body: JSON.stringify(payload)
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
// ---------- ADMIN: policy ----------
|
|
getPolicy(onSuccess, onError) {
|
|
fetch(`${BASE_URL}/admin/ar1-policy`, {
|
|
method: 'GET', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
updatePolicy(patch, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/admin/ar1-policy`, {
|
|
method: 'PUT', mode: 'cors', headers: buildHeaders(),
|
|
body: JSON.stringify(patch)
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
// ---------- ADMIN: pec-schedule-config ----------
|
|
listPecSchedule(onSuccess, onError) {
|
|
fetch(`${BASE_URL}/admin/ar1-pec-schedule-config`, {
|
|
method: 'GET', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
createPecRule(payload, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/admin/ar1-pec-schedule-config`, {
|
|
method: 'POST', mode: 'cors', headers: buildHeaders(),
|
|
body: JSON.stringify(payload)
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
updatePecRule(ruleId, payload, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/admin/ar1-pec-schedule-config/${ruleId}`, {
|
|
method: 'PUT', mode: 'cors', headers: buildHeaders(),
|
|
body: JSON.stringify(payload)
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
deletePecRule(ruleId, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/admin/ar1-pec-schedule-config/${ruleId}`, {
|
|
method: 'DELETE', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => {
|
|
if (r.status === 204) { if (onSuccess) onSuccess({}); }
|
|
else handleResponse(r, onSuccess, onError);
|
|
}).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
// ---------- ADMIN: bulk PEC ----------
|
|
bulkRequestRecompilation(payload, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/admin/ar1-forms/bulk-request-recompilation`, {
|
|
method: 'POST', mode: 'cors', headers: buildHeaders(),
|
|
body: JSON.stringify(payload)
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
// ---------- ADMIN: document categories (per dropdown) ----------
|
|
previewTemplatePdf(templateId) {
|
|
return fetch(`${BASE_URL}/admin/ar1-templates/${templateId}/preview-pdf`, {
|
|
method: 'POST', mode: 'cors', headers: buildHeadersMultipart()
|
|
}).then(r => { if (!r.ok) throw new Error(`HTTP ${r.status}`); return r.blob(); });
|
|
},
|
|
|
|
listDocumentCategories(onSuccess, onError) {
|
|
fetch(`${BASE_URL}/admin/document-categories`, {
|
|
method: 'GET', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
// ---------- ADMIN: email templates (Opzione 3 — tenant-agnostic, BE Gepafin pull) ----------
|
|
listEmailTemplates(onSuccess, onError) {
|
|
fetch(`${BASE_URL}/admin/ar1-email-templates`, {
|
|
method: 'GET', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
getEmailTemplate(kind, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/admin/ar1-email-templates/${kind}`, {
|
|
method: 'GET', mode: 'cors', headers: buildHeaders()
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
updateEmailTemplate(kind, payload, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/admin/ar1-email-templates/${kind}`, {
|
|
method: 'PUT', mode: 'cors', headers: buildHeaders(),
|
|
body: JSON.stringify(payload)
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
|
|
previewEmailTemplate(kind, mockVars, onSuccess, onError) {
|
|
fetch(`${BASE_URL}/admin/ar1-email-templates/${kind}/preview`, {
|
|
method: 'POST', mode: 'cors', headers: buildHeaders(),
|
|
body: JSON.stringify(mockVars || {})
|
|
}).then(r => handleResponse(r, onSuccess, onError)).catch(e => handleError(e, onError));
|
|
},
|
|
};
|
|
|
|
export default Ar1Service;
|