Files
bflows-bandi-fe/src/modules/ar1/service/ar1Service.js
BFLOWS 00ef1eb1e0 feat(ar1-admin): bottone Anteprima PDF wirato a BE /admin/ar1-templates/:id/preview-pdf
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).
2026-04-23 14:36:32 +02:00

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;