diff --git a/Back-End/DocuSeal/urls.py b/Back-End/DocuSeal/urls.py index 671544d..9e4be83 100644 --- a/Back-End/DocuSeal/urls.py +++ b/Back-End/DocuSeal/urls.py @@ -1,7 +1,8 @@ from django.urls import path, re_path -from .views import generate_jwt_token, clone_template +from .views import generate_jwt_token, clone_template, remove_template urlpatterns = [ re_path(r'generateToken$', generate_jwt_token, name='generate_jwt_token'), re_path(r'cloneTemplate$', clone_template, name='clone_template'), + re_path(r'removeTemplate/(?P[0-9]+)$', remove_template, name='remove_template'), ] diff --git a/Back-End/DocuSeal/views.py b/Back-End/DocuSeal/views.py index 18297c0..dea59a4 100644 --- a/Back-End/DocuSeal/views.py +++ b/Back-End/DocuSeal/views.py @@ -71,11 +71,37 @@ def clone_template(request): 'X-Auth-Token': settings.DOCUSEAL_JWT['API_KEY'] }) - if response.status_code != 200: + if response.status_code != status.HTTP_200_OK: return Response({'error': 'Failed to clone template'}, status=response.status_code) data = response.json() return Response(data, status=status.HTTP_200_OK) + except requests.RequestException as e: + return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) + +@csrf_exempt +@api_view(['DELETE']) +def remove_template(request, id): + # Vérifier la clé API + api_key = request.headers.get('X-Auth-Token') + if not api_key or api_key != settings.DOCUSEAL_JWT["API_KEY"]: + return Response({'error': 'Invalid API key'}, status=status.HTTP_401_UNAUTHORIZED) + + # URL de l'API de DocuSeal pour cloner le template + clone_url = f'https://docuseal.com/api/templates/{id}' + + # Faire la requête pour cloner le template + try: + response = requests.delete(clone_url, headers={ + 'X-Auth-Token': settings.DOCUSEAL_JWT['API_KEY'] + }) + + if response.status_code != status.HTTP_200_OK: + return Response({'error': 'Failed to remove template'}, status=response.status_code) + + data = response.json() + return Response(data, status=status.HTTP_200_OK) + except requests.RequestException as e: return Response({'error': str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR) \ No newline at end of file diff --git a/Back-End/Subscriptions/views/registration_file_views.py b/Back-End/Subscriptions/views/registration_file_views.py index 7df225a..9175fca 100644 --- a/Back-End/Subscriptions/views/registration_file_views.py +++ b/Back-End/Subscriptions/views/registration_file_views.py @@ -44,7 +44,7 @@ class RegistrationTemplateMasterSimpleView(APIView): } ) def get(self, request, id): - master = bdd.getObject(_objectName=RegistrationTemplateMaster, _columnName='id', _value=id) + master = bdd.getObject(_objectName=RegistrationTemplateMaster, _columnName='template_id', _value=id) if master is None: return JsonResponse({"errorMessage":'Le master de template n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND) serializer = RegistrationTemplateMasterSerializer(master) @@ -60,7 +60,7 @@ class RegistrationTemplateMasterSimpleView(APIView): } ) def put(self, request, id): - master = bdd.getObject(_objectName=RegistrationTemplateMaster, _columnName='id', _value=id) + master = bdd.getObject(_objectName=RegistrationTemplateMaster, _columnName='template_id', _value=id) if master is None: return JsonResponse({'erreur': 'Le master de template n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND) serializer = RegistrationTemplateMasterSerializer(master, data=request.data) @@ -77,7 +77,7 @@ class RegistrationTemplateMasterSimpleView(APIView): } ) def delete(self, request, id): - master = bdd.getObject(_objectName=RegistrationTemplateMaster, _columnName='id', _value=id) + master = bdd.getObject(_objectName=RegistrationTemplateMaster, _columnName='template_id', _value=id) if master is not None: master.delete() return JsonResponse({'message': 'La suppression du master de template a été effectuée avec succès'}, safe=False, status=status.HTTP_204_NO_CONTENT) @@ -118,7 +118,7 @@ class RegistrationTemplateSimpleView(APIView): } ) def get(self, request, id): - template = bdd.getObject(_objectName=RegistrationTemplate, _columnName='id', _value=id) + template = bdd.getObject(_objectName=RegistrationTemplate, _columnName='template_id', _value=id) if template is None: return JsonResponse({"errorMessage":'Le template d\'inscription n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND) serializer = RegistrationTemplateSerializer(template) @@ -134,7 +134,7 @@ class RegistrationTemplateSimpleView(APIView): } ) def put(self, request, id): - template = bdd.getObject(_objectName=RegistrationTemplate, _columnName='id', _value=id) + template = bdd.getObject(_objectName=RegistrationTemplate, _columnName='template_id', _value=id) if template is None: return JsonResponse({'erreur': 'Le template d\'inscription n\'a pas été trouvé'}, safe=False, status=status.HTTP_404_NOT_FOUND) serializer = RegistrationTemplateSerializer(template, data=request.data) @@ -151,7 +151,7 @@ class RegistrationTemplateSimpleView(APIView): } ) def delete(self, request, id): - template = bdd.getObject(_objectName=RegistrationTemplate, _columnName='id', _value=id) + template = bdd.getObject(_objectName=RegistrationTemplate, _columnName='template_id', _value=id) if template is not None: template.delete() return JsonResponse({'message': 'La suppression du template a été effectuée avec succès'}, safe=False, status=status.HTTP_204_NO_CONTENT) diff --git a/Front-End/src/app/[locale]/admin/structure/page.js b/Front-End/src/app/[locale]/admin/structure/page.js index 6646c49..ac4f08a 100644 --- a/Front-End/src/app/[locale]/admin/structure/page.js +++ b/Front-End/src/app/[locale]/admin/structure/page.js @@ -23,7 +23,9 @@ import { createDatas, fetchTuitionPaymentModes } from '@/app/actions/schoolAction'; import SidebarTabs from '@/components/SidebarTabs'; import FilesGroupsManagement from '@/components/Structure/Files/FilesGroupsManagement'; -import { fetchRegistrationTemplateMaster } from '@/app/actions/subscriptionAction'; +import { + fetchRegistrationTemplateMaster +} from "@/app/actions/registerFileGroupAction"; import logger from '@/utils/logger'; diff --git a/Front-End/src/app/[locale]/admin/subscriptions/page.js b/Front-End/src/app/[locale]/admin/subscriptions/page.js index 41d35d3..e5d610c 100644 --- a/Front-End/src/app/[locale]/admin/subscriptions/page.js +++ b/Front-End/src/app/[locale]/admin/subscriptions/page.js @@ -24,10 +24,13 @@ import { createRegisterForm, sendRegisterForm, archiveRegisterForm, - fetchRegistrationTemplateMaster, fetchStudents, editRegisterForm } from "@/app/actions/subscriptionAction" + import { + fetchRegistrationTemplateMaster + } from "@/app/actions/registerFileGroupAction"; + import { fetchClasses, fetchRegistrationDiscounts, diff --git a/Front-End/src/app/actions/registerFileGroupAction.js b/Front-End/src/app/actions/registerFileGroupAction.js index 9db0398..0341474 100644 --- a/Front-End/src/app/actions/registerFileGroupAction.js +++ b/Front-End/src/app/actions/registerFileGroupAction.js @@ -1,4 +1,19 @@ -import { BE_SUBSCRIPTION_REGISTRATIONFILE_GROUPS_URL } from '@/utils/Url'; +import { BE_SUBSCRIPTION_REGISTRATIONFILE_GROUPS_URL, + BE_SUBSCRIPTION_REGISTRATION_TEMPLATES_URL, + BE_SUBSCRIPTION_REGISTRATION_TEMPLATE_MASTER_URL +} from '@/utils/Url'; + +const requestResponseHandler = async (response) => { + + const body = await response.json(); + if (response.ok) { + return body; + } + // Throw an error with the JSON body containing the form errors + const error = new Error('Form submission error'); + error.details = body; + throw error; +} export async function fetchRegistrationFileGroups() { const response = await fetch(`${BE_SUBSCRIPTION_REGISTRATIONFILE_GROUPS_URL}`, { @@ -71,4 +86,111 @@ export const fetchRegistrationFileFromGroup = async (groupId) => { throw new Error('Erreur lors de la récupération des fichiers associés au groupe'); } return response.json(); +} + +export const fetchRegistrationTemplates = (id = null) => { + let url = `${BE_SUBSCRIPTION_REGISTRATION_TEMPLATES_URL}` + if (id) { + url = `${BE_SUBSCRIPTION_REGISTRATION_TEMPLATES_URL}/${id}`; + } + const request = new Request( + `${url}`, + { + method:'GET', + headers: { + 'Content-Type':'application/json' + }, + } + ); + return fetch(request).then(requestResponseHandler) +}; + +export const editRegistrationTemplates = (fileId, data, csrfToken) => { + return fetch(`${BE_SUBSCRIPTION_REGISTRATION_TEMPLATES_URL}/${fileId}`, { + method: 'PUT', + body: data, + headers: { + 'X-CSRFToken': csrfToken, + }, + credentials: 'include', + }) + .then(requestResponseHandler) +} + +export const createRegistrationTemplates = (data,csrfToken) => { + + return fetch(`${BE_SUBSCRIPTION_REGISTRATION_TEMPLATES_URL}`, { + method: 'POST', + body: JSON.stringify(data), + headers: { + 'X-CSRFToken': csrfToken, + 'Content-Type': 'application/json', + }, + credentials: 'include', + }) + .then(requestResponseHandler) +} + +export const deleteRegistrationTemplates = (fileId,csrfToken) => { + return fetch(`${BE_SUBSCRIPTION_REGISTRATION_TEMPLATES_URL}/${fileId}`, { + method: 'DELETE', + headers: { + 'X-CSRFToken': csrfToken, + }, + credentials: 'include', + }) +} + +export const fetchRegistrationTemplateMaster = (id = null) => { + let url = `${BE_SUBSCRIPTION_REGISTRATION_TEMPLATE_MASTER_URL}`; + if(id){ + url = `${BE_SUBSCRIPTION_REGISTRATION_TEMPLATE_MASTER_URL}/${id}`; + } + const request = new Request( + `${url}`, + { + method:'GET', + headers: { + 'Content-Type':'application/json' + }, + } + ); + return fetch(request).then(requestResponseHandler) +}; + +export const createRegistrationTemplateMaster = (data,csrfToken) => { + + return fetch(`${BE_SUBSCRIPTION_REGISTRATION_TEMPLATE_MASTER_URL}`, { + method: 'POST', + body: JSON.stringify(data), + headers: { + 'X-CSRFToken': csrfToken, + 'Content-Type':'application/json' + }, + credentials: 'include', + }) + .then(requestResponseHandler) +} + +export const deleteRegistrationTemplateMaster = (fileId,csrfToken) => { + return fetch(`${BE_SUBSCRIPTION_REGISTRATION_TEMPLATE_MASTER_URL}/${fileId}`, { + method: 'DELETE', + headers: { + 'X-CSRFToken': csrfToken, + }, + credentials: 'include', + }) +} + +export const editRegistrationTemplateMaster = (fileId, data, csrfToken) => { + return fetch(`${BE_SUBSCRIPTION_REGISTRATION_TEMPLATE_MASTER_URL}/${fileId}`, { + method: 'PUT', + body: JSON.stringify(data), + headers: { + 'X-CSRFToken': csrfToken, + 'Content-Type':'application/json' + }, + credentials: 'include', + }) + .then(requestResponseHandler) } \ No newline at end of file diff --git a/Front-End/src/app/actions/subscriptionAction.js b/Front-End/src/app/actions/subscriptionAction.js index f65004e..cbbc94d 100644 --- a/Front-End/src/app/actions/subscriptionAction.js +++ b/Front-End/src/app/actions/subscriptionAction.js @@ -2,9 +2,7 @@ import { BE_SUBSCRIPTION_STUDENTS_URL, BE_SUBSCRIPTION_CHILDRENS_URL, BE_SUBSCRIPTION_REGISTERFORMS_URL, - BE_SUBSCRIPTION_REGISTRATION_TEMPLATE_MASTER_URL, - BE_SUBSCRIPTION_LAST_GUARDIAN_ID_URL, - BE_SUBSCRIPTION_REGISTRATION_TEMPLATES_URL + BE_SUBSCRIPTION_LAST_GUARDIAN_ID_URL } from '@/utils/Url'; export const PENDING = 'pending'; @@ -101,112 +99,6 @@ export const archiveRegisterForm = (id) => { }).then(requestResponseHandler) } -export const fetchRegistrationTemplates = (id = null) => { - let url = `${BE_SUBSCRIPTION_REGISTRATION_TEMPLATES_URL}` - if (id) { - url = `${BE_SUBSCRIPTION_REGISTRATION_TEMPLATES_URL}/${id}`; - } - const request = new Request( - `${url}`, - { - method:'GET', - headers: { - 'Content-Type':'application/json' - }, - } - ); - return fetch(request).then(requestResponseHandler) -}; - -export const editRegistrationTemplates= (fileId, data, csrfToken) => { - return fetch(`${BE_SUBSCRIPTION_REGISTRATION_TEMPLATES_URL}/${fileId}`, { - method: 'PUT', - body: data, - headers: { - 'X-CSRFToken': csrfToken, - }, - credentials: 'include', - }) - .then(requestResponseHandler) -} - -export const createRegistrationTemplates = (data,csrfToken) => { - - return fetch(`${BE_SUBSCRIPTION_REGISTRATION_TEMPLATES_URL}`, { - method: 'POST', - body: JSON.stringify(data), - headers: { - 'X-CSRFToken': csrfToken, - 'Content-Type': 'application/json', - }, - credentials: 'include', - }) - .then(requestResponseHandler) -} - -export const deleteRegistrationTemplates= (fileId,csrfToken) => { - return fetch(`${BE_SUBSCRIPTION_REGISTRATION_TEMPLATES_URL}/${fileId}`, { - method: 'DELETE', - headers: { - 'X-CSRFToken': csrfToken, - }, - credentials: 'include', - }) -} - -export const fetchRegistrationTemplateMaster = (id = null) => { - let url = `${BE_SUBSCRIPTION_REGISTRATION_TEMPLATE_MASTER_URL}`; - if(id){ - url = `${BE_SUBSCRIPTION_REGISTRATION_TEMPLATE_MASTER_URL}/${id}`; - } - const request = new Request( - `${url}`, - { - method:'GET', - headers: { - 'Content-Type':'application/json' - }, - } - ); - return fetch(request).then(requestResponseHandler) -}; - -export const createRegistrationTemplateMaster = (data,csrfToken) => { - - return fetch(`${BE_SUBSCRIPTION_REGISTRATION_TEMPLATE_MASTER_URL}`, { - method: 'POST', - body: JSON.stringify(data), - headers: { - 'X-CSRFToken': csrfToken, - 'Content-Type':'application/json' - }, - credentials: 'include', - }) - .then(requestResponseHandler) -} - -export const deleteRegistrationTemplateMaster = (fileId,csrfToken) => { - return fetch(`${BE_SUBSCRIPTION_REGISTRATION_TEMPLATE_MASTER_URL}/${fileId}`, { - method: 'DELETE', - headers: { - 'X-CSRFToken': csrfToken, - }, - credentials: 'include', - }) -} - -export const editRegistrationTemplateMaster = (fileId, data, csrfToken) => { - return fetch(`${BE_SUBSCRIPTION_REGISTRATION_TEMPLATE_MASTER_URL}/${fileId}`, { - method: 'PUT', - body: data, - headers: { - 'X-CSRFToken': csrfToken, - }, - credentials: 'include', - }) - .then(requestResponseHandler) -} - export const fetchStudents = (id) => { const url = (id)?`${BE_SUBSCRIPTION_STUDENTS_URL}/${id}`:`${BE_SUBSCRIPTION_STUDENTS_URL}`; const request = new Request( diff --git a/Front-End/src/components/Structure/Files/FileUpload.js b/Front-End/src/components/Structure/Files/FileUpload.js index ac10d84..542213d 100644 --- a/Front-End/src/components/Structure/Files/FileUpload.js +++ b/Front-End/src/components/Structure/Files/FileUpload.js @@ -1,15 +1,15 @@ import React, { useState, useEffect } from 'react'; import ToggleSwitch from '@/components/ToggleSwitch'; // Import du composant ToggleSwitch import { fetchRegistrationFileGroups } from '@/app/actions/registerFileGroupAction'; -import DocusealBuilder from '@/components/DocusealBuilder'; // Import du composant wrapper +import { DocusealBuilder } from '@docuseal/react'; import logger from '@/utils/logger'; import { BE_DOCUSEAL_GET_JWT, BASE_URL } from '@/utils/Url'; import Button from '@/components/Button'; // Import du composant Button import MultiSelect from '@/components/MultiSelect'; // Import du composant MultiSelect -import { createRegistrationTemplates } from '@/app/actions/subscriptionAction'; // Import de la fonction createRegistrationTemplates +import { createRegistrationTemplates } from '@/app/actions/registerFileGroupAction'; import { useCsrfToken } from '@/context/CsrfContext'; -export default function FileUpload({ handleCreateTemplateMaster, fileToEdit = null }) { +export default function FileUpload({ handleCreateTemplateMaster, handleEditTemplateMaster, fileToEdit = null, onSuccess }) { const [isRequired, setIsRequired] = useState(false); // État pour le toggle isRequired const [order, setOrder] = useState(0); const [groups, setGroups] = useState([]); @@ -75,7 +75,12 @@ export default function FileUpload({ handleCreateTemplateMaster, fileToEdit = nu const handleLoad = (detail) => { const templateId = detail?.id; setTemplateMaster(detail); - logger.debug('Master template created with ID:', templateId); + if (fileToEdit) { + logger.debug('Editing master ID :', templateId); + } + else { + logger.debug('Opening master ID :', templateId); + } } const handleUpload = (detail) => { @@ -84,41 +89,53 @@ export default function FileUpload({ handleCreateTemplateMaster, fileToEdit = nu }; const handleSubmit = () => { - logger.debug('Création du template master:', templateMaster?.id); - handleCreateTemplateMaster({ - name: uploadedFileName, - group_ids: selectedGroups.map(group => group.id), - template_id: templateMaster?.id - }); - - guardianEmails.forEach((email, index) => { - cloneTemplate(templateMaster?.id, email) - .then(clonedDocument => { - - // Sauvegarde des templates clonés dans la base de données - const data = { - name: `clone_${clonedDocument.id}`, - template_id: clonedDocument.id, - master: templateMaster?.id, - registration_form: registrationFormIds[index] - }; - - createRegistrationTemplates(data, csrfToken) - .then(response => { - logger.debug('Template enregistré avec succès:', response); - }) - .catch(error => { - logger.error('Erreur lors de l\'enregistrement du template:', error); - }); - - - // Logique pour envoyer chaque template au submitter - logger.debug('Sending template to:', email); - }) - .catch(error => { - logger.error('Error during cloning or sending:', error); - }); - }); + if (fileToEdit) { + logger.debug('Modification du template master:', templateMaster?.id); + handleEditTemplateMaster({ + name: uploadedFileName, + group_ids: selectedGroups.map(group => group.id), + template_id: templateMaster?.id + }); + } + else { + logger.debug('Création du template master:', templateMaster?.id); + handleCreateTemplateMaster({ + name: uploadedFileName, + group_ids: selectedGroups.map(group => group.id), + template_id: templateMaster?.id + }); + + guardianEmails.forEach((email, index) => { + cloneTemplate(templateMaster?.id, email) + .then(clonedDocument => { + + // Sauvegarde des templates clonés dans la base de données + const data = { + name: `clone_${clonedDocument.id}`, + template_id: clonedDocument.id, + master: templateMaster?.id, + registration_form: registrationFormIds[index] + }; + + createRegistrationTemplates(data, csrfToken) + .then(response => { + logger.debug('Template enregistré avec succès:', response); + onSuccess(); + }) + .catch(error => { + logger.error('Erreur lors de l\'enregistrement du template:', error); + }); + + + // Logique pour envoyer chaque template au submitter + logger.debug('Sending template to:', email); + }) + .catch(error => { + logger.error('Error during cloning or sending:', error); + }); + }); + } + }; const cloneTemplate = (templateId, email) => { @@ -161,7 +178,7 @@ export default function FileUpload({ handleCreateTemplateMaster, fileToEdit = nu errorMsg={null} /> -
+
{token && ( )}
-
-
); diff --git a/Front-End/src/components/Structure/Files/FilesGroupsManagement.js b/Front-End/src/components/Structure/Files/FilesGroupsManagement.js index e9867dd..af8851a 100644 --- a/Front-End/src/components/Structure/Files/FilesGroupsManagement.js +++ b/Front-End/src/components/Structure/Files/FilesGroupsManagement.js @@ -1,27 +1,26 @@ import React, { useState, useEffect } from 'react'; -import { Plus, Download, Edit, Trash2, FolderPlus, Signature } from 'lucide-react'; +import { Plus, Download, Edit3, Trash2, FolderPlus, Signature } from 'lucide-react'; import Modal from '@/components/Modal'; import Table from '@/components/Table'; import FileUpload from '@/components/Structure/Files/FileUpload'; -import { formatDate } from '@/utils/Date'; import { BASE_URL } from '@/utils/Url'; -import { - fetchRegistrationTemplateMaster, - createRegistrationTemplateMaster, - editRegistrationTemplateMaster, - deleteRegistrationTemplateMaster, - getRegisterFormFileTemplate -} from '@/app/actions/subscriptionAction'; import { fetchRegistrationFileGroups, createRegistrationFileGroup, deleteRegistrationFileGroup, - editRegistrationFileGroup + editRegistrationFileGroup, + fetchRegistrationTemplateMaster, + createRegistrationTemplateMaster, + editRegistrationTemplateMaster, + deleteRegistrationTemplateMaster, + fetchRegistrationTemplates } from '@/app/actions/registerFileGroupAction'; import RegistrationFileGroupForm from '@/components/Structure/Files/RegistrationFileGroupForm'; +import logger from '@/utils/logger'; export default function FilesGroupsManagement({ csrfToken }) { - const [fichiers, setFichiers] = useState([]); + const [templateMasters, setTemplateMasters] = useState([]); + const [templates, setTemplates] = useState([]); const [groups, setGroups] = useState([]); const [selectedGroup, setSelectedGroup] = useState(null); const [isModalOpen, setIsModalOpen] = useState(false); @@ -29,6 +28,11 @@ export default function FilesGroupsManagement({ csrfToken }) { const [fileToEdit, setFileToEdit] = useState(null); const [isGroupModalOpen, setIsGroupModalOpen] = useState(false); const [groupToEdit, setGroupToEdit] = useState(null); + const [reloadTemplates, setReloadTemplates] = useState(false); + + const handleReloadTemplates = () => { + setReloadTemplates(true); + } const transformFileData = (file, groups) => { const groupInfos = file.groups.map(groupId => groups.find(g => g.id === groupId) || { id: groupId, name: 'Groupe inconnu' }); @@ -41,38 +45,91 @@ export default function FilesGroupsManagement({ csrfToken }) { useEffect(() => { Promise.all([ fetchRegistrationTemplateMaster(), - fetchRegistrationFileGroups() - ]).then(([filesData, groupsData]) => { + fetchRegistrationFileGroups(), + fetchRegistrationTemplates() + ]).then(([filesTemplateMasters, groupsData, filesTemplates]) => { setGroups(groupsData); + setTemplates(filesTemplates); + console.log("coucou : ", filesTemplates) // Sélectionner automatiquement le premier groupe s'il existe if (groupsData.length > 0) { setSelectedGroup(groupsData[0].id.toString()); } // Transformer chaque fichier pour inclure les informations complètes du groupe - const transformedFiles = filesData.map(file => transformFileData(file, groupsData)); - setFichiers(transformedFiles); + const transformedFiles = filesTemplateMasters.map(file => transformFileData(file, groupsData)); + setTemplateMasters(transformedFiles); }).catch(err => { console.log(err.message); + }).finally(() => { + setReloadTemplates(false); }); - }, []); + }, [reloadTemplates]); - const handleFileDelete = (fileId) => { - deleteRegistrationTemplateMaster(fileId, csrfToken) - .then(response => { - if (response.ok) { - setFichiers(fichiers.filter(fichier => fichier.id !== fileId)); - alert('Fichier supprimé avec succès.'); + const deleteTemplateMaster = (templateMaster) => { + // Supprimer les clones associés via l'API DocuSeal + console.log(templates) + const removeClonesPromises = templates + .filter(template => template.master === templateMaster.template_id) + .map(template => removeTemplate(template.template_id)); + + // Ajouter la suppression du master à la liste des promesses + removeClonesPromises.push(removeTemplate(templateMaster.template_id)); + + // Attendre que toutes les suppressions dans DocuSeal soient terminées + Promise.all(removeClonesPromises) + .then(responses => { + const allSuccessful = responses.every(response => response.ok); + if (allSuccessful) { + logger.debug('Master et clones supprimés avec succès de DocuSeal.'); + + // Supprimer le template master de la base de données + deleteRegistrationTemplateMaster(templateMaster.template_id, csrfToken) + .then(response => { + if (response.ok) { + setTemplateMasters(templateMasters.filter(fichier => fichier.template_id !== templateMaster.template_id)); + alert('Fichier supprimé avec succès.'); + } else { + alert('Erreur lors de la suppression du fichier dans la base de données.'); + } + }) + .catch(error => { + console.error('Error deleting file from database:', error); + alert('Erreur lors de la suppression du fichier dans la base de données.'); + }); } else { - alert('Erreur lors de la suppression du fichier.'); + alert('Erreur lors de la suppression du master ou des clones dans DocuSeal.'); } }) .catch(error => { - console.error('Error deleting file:', error); - alert('Erreur lors de la suppression du fichier.'); + console.error('Error removing template from DocuSeal:', error); + alert('Erreur lors de la suppression du master ou des clones dans DocuSeal.'); }); }; - const handleFileEdit = (file) => { + const removeTemplate = (templateId) => { + return fetch('/api/docuseal/removeTemplate/', { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + 'X-CSRFToken': csrfToken + }, + body: JSON.stringify({ + templateId + }) + }) + .then(response => { + if (!response.ok) { + return response.json().then(err => { throw new Error(err.message); }); + } + return response; + }) + .catch(error => { + console.error('Error removing template:', error); + throw error; + }); + }; + + const editTemplateMaster = (file) => { setIsEditing(true); setFileToEdit(file); setIsModalOpen(true); @@ -84,87 +141,40 @@ export default function FilesGroupsManagement({ csrfToken }) { template_id: template_id, groups: group_ids }; - console.log(data); - - if (isEditing && fileToEdit) { - editRegistrationTemplateMaster(fileToEdit.id, data, csrfToken) - .then(data => { - // Transformer le fichier mis à jour avec les informations du groupe - const transformedFile = transformFileData(data, groups); - setFichiers(prevFichiers => - prevFichiers.map(f => f.id === fileToEdit.id ? transformedFile : f) - ); - setIsModalOpen(false); - setFileToEdit(null); - setIsEditing(false); - }) - .catch(error => { - console.error('Error editing file:', error); - alert('Erreur lors de la modification du fichier'); - }); - } else { - createRegistrationTemplateMaster(data, csrfToken) - .then(data => { - // Transformer le nouveau fichier avec les informations du groupe - const transformedFile = transformFileData(data, groups); - setFichiers(prevFiles => [...prevFiles, transformedFile]); - setIsModalOpen(false); - }) - .catch(error => { - console.error('Error uploading file:', error); - }); - } + logger.debug(data); + + createRegistrationTemplateMaster(data, csrfToken) + .then(data => { + // Transformer le nouveau fichier avec les informations du groupe + const transformedFile = transformFileData(data, groups); + setTemplateMasters(prevFiles => [...prevFiles, transformedFile]); + setIsModalOpen(false); + }) + .catch(error => { + console.error('Error uploading file:', error); + }); }; - const handleTemplate = ({name, is_required, order, groupId, document_id}) => { - if (!name) { - alert('Veuillez entrer un nom de fichier.'); - return; - } + const handleEditTemplateMaster = ({name, group_ids, template_id}) => { + const data = { + name: name, + template_id: template_id, + groups: group_ids + }; + logger.debug(data); - const formData = new FormData(); - if(file) { - formData.append('file', file); - } - formData.append('name', name); - formData.append('is_required', is_required); - formData.append('order', order); - formData.append('document_id', document_id); - - // Modification ici : vérifier si groupId existe et n'est pas vide - if (groupId && groupId !== '') { - formData.append('group', groupId); // Notez que le nom du champ est 'group' et non 'group_id' - } - - - if (isEditing && fileToEdit) { - editRegistrationTemplateMaster(fileToEdit.id, formData, csrfToken) - .then(data => { - // Transformer le fichier mis à jour avec les informations du groupe - const transformedFile = transformFileData(data, groups); - setFichiers(prevFichiers => - prevFichiers.map(f => f.id === fileToEdit.id ? transformedFile : f) - ); - setIsModalOpen(false); - setFileToEdit(null); - setIsEditing(false); - }) - .catch(error => { - console.error('Error editing file:', error); - alert('Erreur lors de la modification du fichier'); - }); - } else { - createRegistrationTemplateMaster(formData, csrfToken) - .then(data => { - // Transformer le nouveau fichier avec les informations du groupe - const transformedFile = transformFileData(data, groups); - setFichiers(prevFiles => [...prevFiles, transformedFile]); - setIsModalOpen(false); - }) - .catch(error => { - console.error('Error uploading file:', error); - }); - } + editRegistrationTemplateMaster(template_id, data, csrfToken) + .then(data => { + // Transformer le fichier mis à jour avec les informations du groupe + const transformedFile = transformFileData(data, groups); + setTemplateMasters(prevFichiers => + prevFichiers.map(f => f.id === template_id ? transformedFile : f) + ); + }) + .catch(error => { + console.error('Error editing file:', error); + alert('Erreur lors de la modification du fichier'); + }); }; const handleGroupSubmit = (groupData) => { @@ -198,10 +208,10 @@ export default function FilesGroupsManagement({ csrfToken }) { }; const handleGroupDelete = (groupId) => { - // Vérifier si des fichiers utilisent ce groupe - const filesInGroup = fichiers.filter(file => file.group && file.group.id === groupId); + // Vérifier si des templateMasters utilisent ce groupe + const filesInGroup = templateMasters.filter(file => file.group && file.group.id === groupId); if (filesInGroup.length > 0) { - alert('Impossible de supprimer ce groupe car il contient des fichiers. Veuillez d\'abord retirer tous les fichiers de ce groupe.'); + alert('Impossible de supprimer ce groupe car il contient des templateMasters. Veuillez d\'abord retirer tous les templateMasters de ce groupe.'); return; } @@ -224,7 +234,7 @@ export default function FilesGroupsManagement({ csrfToken }) { } }; - const filteredFiles = fichiers.filter(file => { + const filteredFiles = templateMasters.filter(file => { if (!selectedGroup) return true; return file.groups && file.groups.some(group => group.id === parseInt(selectedGroup)); }); @@ -236,14 +246,14 @@ export default function FilesGroupsManagement({ csrfToken }) {
{row.file && ( - + )} - -
)} @@ -255,10 +265,10 @@ export default function FilesGroupsManagement({ csrfToken }) { { name: 'Actions', transform: (row) => (
)} @@ -278,7 +288,9 @@ export default function FilesGroupsManagement({ csrfToken }) { ContentComponent={() => ( )} modalClassName='w-4/5 h-4/5' @@ -286,7 +298,7 @@ export default function FilesGroupsManagement({ csrfToken }) { (
-

Groupes de fichiers

+

Groupes de templateMasters