diff --git a/src/main/java/com/primefactorsolutions/service/DocumentService.java b/src/main/java/com/primefactorsolutions/service/DocumentService.java index 78f5717..3e808b0 100644 --- a/src/main/java/com/primefactorsolutions/service/DocumentService.java +++ b/src/main/java/com/primefactorsolutions/service/DocumentService.java @@ -23,6 +23,10 @@ public class DocumentService { documentRepository.save(newDocument); } + public void deleteDocument(final UUID id) { + documentRepository.deleteById(id); + } + public List getAllDocuments() { return documentRepository.findAll(); } @@ -53,7 +57,10 @@ public class DocumentService { return employees.subList(start, end); } - public List findDocumentBy(DocumentType documentType, Employee employee, int start, int pageSize) { + public List findDocumentBy(final DocumentType documentType, + final Employee employee, + final int start, + final int pageSize) { List documents = documentRepository.findAll(); if (documentType != null) { documents = documents.stream() diff --git a/src/main/java/com/primefactorsolutions/views/DocumentView.java b/src/main/java/com/primefactorsolutions/views/DocumentView.java index fe8d8a5..e78a8a5 100644 --- a/src/main/java/com/primefactorsolutions/views/DocumentView.java +++ b/src/main/java/com/primefactorsolutions/views/DocumentView.java @@ -10,11 +10,15 @@ import com.vaadin.flow.component.button.Button; import com.vaadin.flow.component.combobox.ComboBox; import com.vaadin.flow.component.html.H2; import com.vaadin.flow.component.notification.Notification; +import com.vaadin.flow.component.orderedlayout.HorizontalLayout; import com.vaadin.flow.component.textfield.TextField; import com.vaadin.flow.component.upload.Upload; import com.vaadin.flow.component.upload.receivers.MemoryBuffer; import com.vaadin.flow.router.*; import com.vaadin.flow.spring.annotation.SpringComponent; +import elemental.json.Json; +import elemental.json.JsonArray; +import elemental.json.JsonObject; import jakarta.annotation.security.PermitAll; import org.springframework.context.annotation.Scope; import org.springframework.security.core.userdetails.UserDetails; @@ -22,6 +26,7 @@ import org.vaadin.firitin.form.BeanValidationForm; import com.vaadin.flow.spring.security.AuthenticationContext; import java.io.IOException; +import java.util.Base64; import java.util.List; import java.util.UUID; @@ -41,8 +46,10 @@ public class DocumentView extends BeanValidationForm implements HasUrl private final DocumentService documentService; private final EmployeeService employeeService; private final AuthenticationContext authContext; + private boolean fileUploaded = false; private Button saveButton; + private Button viewDocumentButton; public DocumentView(final DocumentService documentService, final EmployeeService employeeService, @@ -55,10 +62,14 @@ public class DocumentView extends BeanValidationForm implements HasUrl } private void initializeView() { + configureComponents(); + configureUploadButton(); + } + + private void configureComponents() { setFileNameProperties(); setDocumentTypeProperties(); setEmployeeComboBoxProperties(); - setUploadButtonProperties(); } private void setFileNameProperties() { @@ -77,24 +88,53 @@ public class DocumentView extends BeanValidationForm implements HasUrl employeeComboBox.setWidthFull(); } - private void setUploadButtonProperties() { + private void configureUploadButton() { uploadButton.setMaxFiles(1); uploadButton.setAcceptedFileTypes(".pdf"); uploadButton.addSucceededListener(event -> handleUploadSuccess()); } - protected Button createSaveButton() { + protected Button createSaveButton() { saveButton = new Button("Save"); saveButton.addClickListener(event -> saveDocument()); return saveButton; } - protected Button createCloseButton() { + protected Button createCloseButton() { Button closeButton = new Button("Close"); closeButton.addClickListener(event -> closeForm()); return closeButton; } + protected Button createViewDocumentButton() { + viewDocumentButton = new Button("View Document"); + viewDocumentButton.setEnabled(false); + viewDocumentButton.addClickListener(event -> viewDocument()); + return viewDocumentButton; + } + + private void viewDocument() { + Document document = getEntity(); + if (document.getFileData() != null && document.getFileData().length > 0) { + String base64Data = Base64.getEncoder().encodeToString(document.getFileData()); + String jsCode = createJsCodeForDocument(base64Data); + getElement().executeJs(jsCode); + } else { + Notification.show("No file data available to view."); + } + } + + private String createJsCodeForDocument(final String base64Data) { + return "var byteCharacters = atob('" + base64Data + "');" + + "var byteNumbers = new Array(byteCharacters.length);" + + "for (var i = 0; i < byteCharacters.length; i++) {" + + " byteNumbers[i] = byteCharacters.charCodeAt(i);" + + "}" + + "var byteArray = new Uint8Array(byteNumbers);" + + "var blob = new Blob([byteArray], { type: 'application/pdf' });" + + "var url = URL.createObjectURL(blob);" + + "window.open(url, '_blank');"; + } private void closeForm() { navigateToDocumentsListView(); @@ -107,22 +147,19 @@ public class DocumentView extends BeanValidationForm implements HasUrl private void handleUploadSuccess() { fileUploaded = true; Notification.show("File uploaded successfully."); + viewDocumentButton.setEnabled(true); } private void saveDocument() { if (isFormValid()) { - Document document = getEntity(); // Obtenemos el documento actual del formulario + Document document = getEntity(); document.setFileName(fileName.getValue()); document.setDocumentType(documentType.getValue()); document.setEmployee(employeeComboBox.getValue()); - document.setFileData(readFileData()); // Actualizamos el archivo si es necesario + document.setFileData(readFileData()); + setDocumentCreator(document); - authContext.getAuthenticatedUser(UserDetails.class).ifPresent(user -> { - String creator = user.getUsername(); - document.setCreator(creator); // Asignar el nombre del creador al documento si corresponde - }); - - documentService.saveDocument(document); // Guardamos el documento actualizado + documentService.saveDocument(document); Notification.show("File saved successfully."); clearForm(); } else { @@ -130,6 +167,12 @@ public class DocumentView extends BeanValidationForm implements HasUrl } } + private void setDocumentCreator(final Document document) { + authContext.getAuthenticatedUser(UserDetails.class).ifPresent(user -> { + document.setCreator(user.getUsername()); + }); + } + private boolean isFormValid() { return !fileName.isEmpty() && documentType.getValue() != null @@ -137,14 +180,6 @@ public class DocumentView extends BeanValidationForm implements HasUrl && fileUploaded; } - private Document createDocument() { - Document document = new Document(); - document.setFileName(fileName.getValue()); - document.setDocumentType(documentType.getValue()); - document.setFileData(readFileData()); - return document; - } - private byte[] readFileData() { try { return buffer.getInputStream().readAllBytes(); @@ -159,41 +194,8 @@ public class DocumentView extends BeanValidationForm implements HasUrl documentType.clear(); employeeComboBox.clear(); fileUploaded = false; - } - - private void checkFormModifications() { - boolean hasModifications = !fileName.isEmpty() - && documentType.getValue() != null - && employeeComboBox.getValue() != null; - - if (hasModifications || fileUploaded) { - saveButton.setEnabled(true); - } else { - saveButton.setEnabled(false); - } - } - - - @Override - public void setParameter(final BeforeEvent beforeEvent, final String action) { - final RouteParameters params = beforeEvent.getRouteParameters(); - final String s = params.get("documentId").orElse(null); - - if ("new".equals(action)) { - setEntityWithEnabledSave(new Document()); - } else { - UUID documentId = UUID.fromString(s); - var document = documentService.getDocument(documentId); - setEntity(document); - employeeComboBox.setValue(document.getEmployee()); - - if ("edit".equals(action) && !s.isEmpty()) { - setFieldsReadOnly(false); - } else if ("view".equals(action) && !s.isEmpty()) { - setFieldsReadOnly(true); - } - } - checkFormModifications(); + uploadButton.getElement().setPropertyJson("files", Json.createArray()); + viewDocumentButton.setEnabled(false); } private void setFieldsReadOnly(final boolean option) { @@ -202,8 +204,49 @@ public class DocumentView extends BeanValidationForm implements HasUrl employeeComboBox.setReadOnly(option); } + private void preLoadFile(final Document document) { + JsonArray jsonArray = Json.createArray(); + JsonObject jsonObject = Json.createObject(); + jsonObject.put("name", document.getFileName()); + jsonObject.put("progress", 100); + jsonObject.put("complete", true); + jsonArray.set(0, jsonObject); + uploadButton.getElement().setPropertyJson("files", jsonArray); + } + + @Override + public void setParameter(final BeforeEvent beforeEvent, final String action) { + final RouteParameters params = beforeEvent.getRouteParameters(); + final String documentIdString = params.get("documentId").orElse(null); + + if ("new".equals(action)) { + setEntityWithEnabledSave(new Document()); + } else { + UUID documentId = UUID.fromString(documentIdString); + Document document = documentService.getDocument(documentId); + setEntity(document); + employeeComboBox.setValue(document.getEmployee()); + preLoadFile(document); + configureViewOrEditAction(action, documentIdString); + } + } + + private void configureViewOrEditAction(final String action, final String documentIdString) { + if ("edit".equals(action) && !documentIdString.isEmpty()) { + setFieldsReadOnly(false); + preLoadFile(getEntity()); + } else if ("view".equals(action) && !documentIdString.isEmpty()) { + setFieldsReadOnly(true); + saveButton.setEnabled(false); + viewDocumentButton.setEnabled(true); + } + } + @Override protected List getFormComponents() { - return List.of(title, fileName, documentType, employeeComboBox, uploadButton, createCloseButton()); + HorizontalLayout buttonLayout = new HorizontalLayout(); + buttonLayout.add(uploadButton, createViewDocumentButton()); + buttonLayout.setSpacing(true); + return List.of(title, fileName, documentType, employeeComboBox, buttonLayout, createCloseButton()); } } diff --git a/src/main/java/com/primefactorsolutions/views/DocumentsListView.java b/src/main/java/com/primefactorsolutions/views/DocumentsListView.java index c786ca6..c95e917 100644 --- a/src/main/java/com/primefactorsolutions/views/DocumentsListView.java +++ b/src/main/java/com/primefactorsolutions/views/DocumentsListView.java @@ -11,7 +11,6 @@ import com.vaadin.flow.component.combobox.ComboBox; import com.vaadin.flow.component.grid.GridSortOrder; import com.vaadin.flow.component.html.Main; import com.vaadin.flow.component.html.Span; -import com.vaadin.flow.component.notification.Notification; import com.vaadin.flow.data.provider.SortDirection; import com.vaadin.flow.router.PageTitle; import com.vaadin.flow.router.Route; @@ -112,7 +111,7 @@ public class DocumentsListView extends Main { return allEmployeesOption; } - private String getEmployeeLabel(Employee employee) { + private String getEmployeeLabel(final Employee employee) { return employee.getFirstName().equals("All") ? "All" : employee.getFirstName() + " " + employee.getLastName(); } @@ -137,26 +136,29 @@ public class DocumentsListView extends Main { documentGrid.setPageSize(5); } - private void updateDocumentGrid(DocumentType documentType, Employee employee) { + private void updateDocumentGrid(final DocumentType documentType, final Employee employee) { DocumentType finalDocumentType = isValidDocumentType(documentType) ? documentType : null; Employee finalEmployee = isValidEmployee(employee) ? employee : null; documentGrid.setPagingDataProvider((page, pageSize) -> - (finalDocumentType == null && finalEmployee == null) ? - fetchDocuments((int) page, pageSize) : - fetchFilteredDocuments((int) page, pageSize, finalDocumentType, finalEmployee) + (finalDocumentType == null && finalEmployee == null) + ? fetchDocuments((int) page, pageSize) + : fetchFilteredDocuments((int) page, pageSize, finalDocumentType, finalEmployee) ); documentGrid.getDataProvider().refreshAll(); } - private boolean isValidDocumentType(DocumentType documentType) { + private boolean isValidDocumentType(final DocumentType documentType) { return documentType != null && !"All".equals(documentType.name()); } - private boolean isValidEmployee(Employee employee) { + private boolean isValidEmployee(final Employee employee) { return employee != null && !"All".equals(employee.getFirstName()); } - private List fetchFilteredDocuments(int page, int pageSize, final DocumentType documentType, final Employee employee) { + private List fetchFilteredDocuments(final int page, + final int pageSize, + final DocumentType documentType, + final Employee employee) { return documentService.findDocumentBy(documentType, employee, page, pageSize); } @@ -191,7 +193,7 @@ public class DocumentsListView extends Main { return resource; } - private void openDocumentStream(StreamResource resource, UI ui) { + private void openDocumentStream(final StreamResource resource, final UI ui) { StreamRegistration registration = ui.getSession().getResourceRegistry().registerResource(resource); ui.getPage().open(registration.getResourceUri().toString()); }