From 9feeed277ab9576cb4478c939c3c953022682001 Mon Sep 17 00:00:00 2001 From: Pavel Bezliapovich Date: Tue, 3 Dec 2024 14:34:14 +0100 Subject: [PATCH] feat: Added the ability to select a BaselineCollection for bulk export Refs: #285 --- docs/openapi.json | 67 ++++++++++++++---- .../pdf_exporter/converter/PdfConverter.java | 1 - .../rest/PdfExporterRestApplication.java | 4 ++ .../controller/CollectionApiController.java | 19 +++++ .../CollectionInternalController.java | 46 ++++++++++++ .../model/collections/CollectionItem.java | 18 +++++ .../rest/model/conversion/DocumentType.java | 5 +- .../rest/model/conversion/ExportParams.java | 3 - .../service/PdfExporterPolarionService.java | 26 ++++++- .../pdf_exporter/util/DocumentDataHelper.java | 23 ------ .../util/DocumentFileNameHelper.java | 3 - .../pdf_exporter/util/HtmlProcessor.java | 3 - .../widgets/BulkPdfExportWidgetRenderer.java | 37 ++++++++-- .../pdf-exporter/js/bulk-pdf-exporter.js | 70 ++++++++++++------- .../webapp/pdf-exporter/js/export-common.js | 53 ++++++++++++++ .../pdf-exporter/js/modules/ExportParams.js | 7 -- 16 files changed, 299 insertions(+), 86 deletions(-) create mode 100644 src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/controller/CollectionApiController.java create mode 100644 src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/controller/CollectionInternalController.java create mode 100644 src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/model/collections/CollectionItem.java diff --git a/docs/openapi.json b/docs/openapi.json index a621b1b3..0887800f 100644 --- a/docs/openapi.json +++ b/docs/openapi.json @@ -597,6 +597,47 @@ ] } }, + "/api/projects/{projectId}/collections/{collectionId}": { + "get": { + "operationId": "getCollectionItems", + "parameters": [ + { + "description": "Project ID", + "in": "path", + "name": "projectId", + "required": true, + "schema": { + "type": "string" + } + }, + { + "description": "Collection ID", + "in": "path", + "name": "collectionId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollectionItem" + } + } + }, + "description": "List of collection item" + } + }, + "summary": "Get items from collection", + "tags": [ + "Collections" + ] + } + }, "/api/projects/{projectId}/name": { "get": { "operationId": "getProjectName", @@ -1504,6 +1545,20 @@ }, "type": "object" }, + "CollectionItem": { + "description": "Details about the collection item", + "properties": { + "moduleNameWithSpace": { + "description": "The name of the module with spaces", + "type": "string" + }, + "revision": { + "description": "The revision of the module", + "type": "string" + } + }, + "type": "object" + }, "ConfigurationStatus": { "properties": { "details": { @@ -1616,13 +1671,6 @@ }, "type": "array" }, - "collectionId" : { - "type" : "string", - "description" : "The unique identifier for the collection" - }, - "coverPage" : { - "type" : "string", - "description" : "Cover page settings name" "coverPage": { "description": "Cover page settings name", "type": "string" @@ -1644,11 +1692,6 @@ "description": "Local Polarion URLs should be removed from the document", "type": "boolean" }, - "documentType" : { - "type" : "string", - "description" : "Type of the document", - "enum" : [ "LIVE_DOC", "LIVE_REPORT", "TEST_RUN", "WIKI_PAGE", "BASELINE_COLLECTION" ], - "example" : "LIVE_DOC" "documentType": { "description": "Type of the document", "enum": [ diff --git a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/converter/PdfConverter.java b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/converter/PdfConverter.java index 5b6d8837..0b7dc546 100644 --- a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/converter/PdfConverter.java +++ b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/converter/PdfConverter.java @@ -136,7 +136,6 @@ public byte[] convertToPdf(@NotNull ExportParams exportParams, @Nullable ExportM case LIVE_REPORT -> documentDataHelper.getLiveReport(project, exportParams); case TEST_RUN -> documentDataHelper.getTestRun(Objects.requireNonNull(project), exportParams); case WIKI_PAGE -> documentDataHelper.getWikiPage(project, exportParams); - case BASELINE_COLLECTION -> documentDataHelper.getBaselineCollection(Objects.requireNonNull(project), exportParams); }; } diff --git a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/PdfExporterRestApplication.java b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/PdfExporterRestApplication.java index d292eba1..f79c656c 100644 --- a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/PdfExporterRestApplication.java +++ b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/PdfExporterRestApplication.java @@ -3,6 +3,8 @@ import ch.sbb.polarion.extension.generic.rest.GenericRestApplication; import ch.sbb.polarion.extension.generic.settings.NamedSettingsRegistry; import ch.sbb.polarion.extension.pdf_exporter.converter.PdfConverterJobsCleaner; +import ch.sbb.polarion.extension.pdf_exporter.rest.controller.CollectionApiController; +import ch.sbb.polarion.extension.pdf_exporter.rest.controller.CollectionInternalController; import ch.sbb.polarion.extension.pdf_exporter.rest.controller.ConverterApiController; import ch.sbb.polarion.extension.pdf_exporter.rest.controller.ConverterInternalController; import ch.sbb.polarion.extension.pdf_exporter.rest.controller.SettingsApiController; @@ -68,6 +70,8 @@ public PdfExporterRestApplication() { new SettingsInternalController(), new TestRunAttachmentsApiController(), new TestRunAttachmentsInternalController(), + new CollectionApiController(), + new CollectionInternalController(), new UtilityResourcesApiController(), new UtilityResourcesInternalController() ); diff --git a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/controller/CollectionApiController.java b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/controller/CollectionApiController.java new file mode 100644 index 00000000..9d4f17ec --- /dev/null +++ b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/controller/CollectionApiController.java @@ -0,0 +1,19 @@ +package ch.sbb.polarion.extension.pdf_exporter.rest.controller; + +import ch.sbb.polarion.extension.generic.rest.filter.Secured; +import ch.sbb.polarion.extension.generic.service.PolarionService; +import ch.sbb.polarion.extension.pdf_exporter.rest.model.collections.CollectionItem; + +import javax.ws.rs.Path; +import java.util.List; + +@Secured +@Path("/api") +public class CollectionApiController extends CollectionInternalController { + private static final PolarionService polarionService = new PolarionService(); + + @Override + public List getCollectionItems(String projectId, String collectionId) { + return polarionService.callPrivileged(() -> super.getCollectionItems(projectId, collectionId)); + } +} diff --git a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/controller/CollectionInternalController.java b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/controller/CollectionInternalController.java new file mode 100644 index 00000000..5ea4a115 --- /dev/null +++ b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/controller/CollectionInternalController.java @@ -0,0 +1,46 @@ +package ch.sbb.polarion.extension.pdf_exporter.rest.controller; + + +import ch.sbb.polarion.extension.pdf_exporter.rest.model.collections.CollectionItem; +import ch.sbb.polarion.extension.pdf_exporter.service.PdfExporterPolarionService; +import io.swagger.v3.oas.annotations.Hidden; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import java.util.List; + +@Hidden +@Path("/internal") +@Tag(name = "Collections") +public class CollectionInternalController { + private final PdfExporterPolarionService pdfExporterPolarionService; + + public CollectionInternalController() { + pdfExporterPolarionService = new PdfExporterPolarionService(); + } + + @GET + @Path("/projects/{projectId}/collections/{collectionId}") + @Produces(MediaType.APPLICATION_JSON) + @Operation(summary = "Get items from collection", + responses = { + @ApiResponse(responseCode = "200", + description = "List of collection item", + content = @Content(schema = @Schema(implementation = CollectionItem.class)) + ) + } + ) + public List getCollectionItems(@Parameter(description = "Project ID", required = true) @PathParam("projectId") String projectId, + @Parameter(description = "Collection ID", required = true) @PathParam("collectionId") String collectionId) { + return pdfExporterPolarionService.getCollectionItems(projectId, collectionId); + } +} diff --git a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/model/collections/CollectionItem.java b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/model/collections/CollectionItem.java new file mode 100644 index 00000000..494c4496 --- /dev/null +++ b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/model/collections/CollectionItem.java @@ -0,0 +1,18 @@ +package ch.sbb.polarion.extension.pdf_exporter.rest.model.collections; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "Details about the collection item") +public class CollectionItem { + @Schema(description = "The name of the module with spaces") + private String moduleNameWithSpace; + + @Schema(description = "The revision of the module") + private String revision; +} diff --git a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/model/conversion/DocumentType.java b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/model/conversion/DocumentType.java index 6afa2ce4..0f777734 100644 --- a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/model/conversion/DocumentType.java +++ b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/model/conversion/DocumentType.java @@ -15,10 +15,7 @@ public enum DocumentType { TEST_RUN, @Schema(description = "Wiki page") - WIKI_PAGE, - - @Schema(description = "Collection") - BASELINE_COLLECTION; + WIKI_PAGE; @SuppressWarnings("unused") @JsonCreator diff --git a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/model/conversion/ExportParams.java b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/model/conversion/ExportParams.java index 30e93311..e025e582 100644 --- a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/model/conversion/ExportParams.java +++ b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/rest/model/conversion/ExportParams.java @@ -100,9 +100,6 @@ public class ExportParams { @Schema(description = "Internal content") private String internalContent; - @Schema(description = "The unique identifier for the collection") - private String collectionId; - public @NotNull DocumentType getDocumentType() { if (documentType == null) { documentType = DocumentType.LIVE_DOC; diff --git a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/service/PdfExporterPolarionService.java b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/service/PdfExporterPolarionService.java index d7e403c9..a31f0e51 100644 --- a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/service/PdfExporterPolarionService.java +++ b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/service/PdfExporterPolarionService.java @@ -6,17 +6,22 @@ import ch.sbb.polarion.extension.generic.settings.SettingName; import ch.sbb.polarion.extension.generic.util.ScopeUtils; import ch.sbb.polarion.extension.pdf_exporter.rest.model.attachments.TestRunAttachment; +import ch.sbb.polarion.extension.pdf_exporter.rest.model.collections.CollectionItem; import ch.sbb.polarion.extension.pdf_exporter.rest.model.settings.stylepackage.StylePackageModel; import ch.sbb.polarion.extension.pdf_exporter.rest.model.settings.stylepackage.StylePackageWeightInfo; import ch.sbb.polarion.extension.pdf_exporter.settings.StylePackageSettings; import ch.sbb.polarion.extension.pdf_exporter.util.WildcardUtils; import com.polarion.alm.projects.IProjectService; +import com.polarion.alm.shared.api.model.baselinecollection.BaselineCollectionReference; +import com.polarion.alm.shared.api.transaction.TransactionalExecutor; import com.polarion.alm.tracker.ITestManagementService; import com.polarion.alm.tracker.ITrackerService; import com.polarion.alm.tracker.model.IModule; import com.polarion.alm.tracker.model.ITestRun; import com.polarion.alm.tracker.model.ITestRunAttachment; import com.polarion.alm.tracker.model.ITrackerProject; +import com.polarion.alm.tracker.model.baselinecollection.IBaselineCollection; +import com.polarion.alm.tracker.model.baselinecollection.IBaselineCollectionElement; import com.polarion.core.util.StringUtils; import com.polarion.platform.IPlatformService; import com.polarion.platform.persistence.IDataService; @@ -115,7 +120,7 @@ private boolean isStylePackageSuitable(@Nullable String projectId, @NotNull Stri return true; } else { IDataService dataService = getTrackerService().getDataService(); - IPObjectList suitableDocuments = dataService.searchInstances(dataService.getPrototype("Module"), model.getMatchingQuery(), "name"); + IPObjectList suitableDocuments = dataService.searchInstances(dataService.getPrototype("Module"), model.getMatchingQuery(), "name"); for (IModule suitableDocument : suitableDocuments) { if (sameDocument(projectId, spaceId, documentName, suitableDocument)) { return true; @@ -165,4 +170,23 @@ private boolean sameDocument(@Nullable String projectId, @NotNull String spaceId } return testRunAttachment; } + + public @NotNull List getCollectionItems(@NotNull String projectId, @NotNull String collectionId) { + List collectionItemList = new ArrayList<>(); + TransactionalExecutor.executeSafelyInReadOnlyTransaction(transaction -> { + IBaselineCollection collection = new BaselineCollectionReference(projectId, collectionId).get(transaction).getOldApi(); + + collection.getElements() + .stream() + .map(IBaselineCollectionElement::getObjectWithRevision) + .filter(IModule.class::isInstance) + .map(IModule.class::cast) + .forEach(module -> { + collectionItemList.add(new CollectionItem(module.getModuleNameWithSpace().replaceFirst("\\s*/\\s*", "/"), module.getLastRevision())); + }); + + return null; + }); + return collectionItemList; + } } diff --git a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/util/DocumentDataHelper.java b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/util/DocumentDataHelper.java index 7ab9e855..ac808e06 100644 --- a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/util/DocumentDataHelper.java +++ b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/util/DocumentDataHelper.java @@ -135,29 +135,6 @@ public DocumentData getTestRun(@NotNull ITrackerProject project, @NotN }); } - public DocumentData getBaselineCollection(@NotNull ITrackerProject project, @NotNull ExportParams exportParams) { - return TransactionalExecutor.executeSafelyInReadOnlyTransaction(transaction -> { - - String projectId = project.getId(); - String collectionId = exportParams.getCollectionId(); - if (projectId == null || collectionId == null) { - throw new IllegalArgumentException("Project id and collection id are required for export"); - } - - IBaselineCollection collection = new BaselineCollectionReference(projectId, collectionId).get(transaction).getOldApi(); - - return DocumentData.builder(DocumentType.BASELINE_COLLECTION, collection) - .projectName(project.getName()) - .lastRevision(collection.getLastRevision()) - .baselineName(getRevisionBaseline(projectId, collection, exportParams.getRevision())) - .id(collectionId) - .title(collection.getName()) - .content(null) - .build(); - }); - } - - public DocumentData getWikiPage(@Nullable ITrackerProject project, @NotNull ExportParams exportParams) { return getWikiPage(project, exportParams, true); } diff --git a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/util/DocumentFileNameHelper.java b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/util/DocumentFileNameHelper.java index 948c4b26..5cf403d0 100644 --- a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/util/DocumentFileNameHelper.java +++ b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/util/DocumentFileNameHelper.java @@ -50,7 +50,6 @@ public String getDocumentFileName(@NotNull ExportParams exportParams) { case LIVE_REPORT -> documentDataHelper.getLiveReport(project, exportParams, false); case TEST_RUN -> documentDataHelper.getTestRun(project, exportParams, false); case WIKI_PAGE -> documentDataHelper.getWikiPage(project, exportParams, false); - case BASELINE_COLLECTION -> documentDataHelper.getBaselineCollection(project, exportParams); }; FileNameTemplateModel fileNameTemplateModel = getFileNameTemplateModel(ScopeUtils.getScopeFromProject(exportParams.getProjectId())); @@ -81,8 +80,6 @@ public String getDocumentFileName(@NotNull ExportParams exportParams) { yield fileNameTemplateModel.getTestRunNameTemplate(); case WIKI_PAGE: yield fileNameTemplateModel.getWikiNameTemplate(); - case BASELINE_COLLECTION: - yield "Test"; }; } diff --git a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/util/HtmlProcessor.java b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/util/HtmlProcessor.java index ecae91aa..e81b6fac 100644 --- a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/util/HtmlProcessor.java +++ b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/util/HtmlProcessor.java @@ -185,7 +185,6 @@ public String processHtmlForPDF(@NotNull String html, @NotNull ExportParams expo processingHtml = adjustColumnWidthInReports(processingHtml); yield removeFloatLeftFromReports(processingHtml); } - case BASELINE_COLLECTION -> null; }; html = replaceResourcesAsBase64Encoded(html); html = MediaUtils.removeSvgUnsupportedFeatureHint(html); //note that there is one more replacement attempt before replacing images with base64 representation @@ -197,7 +196,6 @@ public String processHtmlForPDF(@NotNull String html, @NotNull ExportParams expo yield new NumberedListsSanitizer().fixNumberedLists(processingHtml); } case LIVE_REPORT, TEST_RUN -> html; - case BASELINE_COLLECTION -> null; }; // ---- @@ -219,7 +217,6 @@ public String processHtmlForPDF(@NotNull String html, @NotNull ExportParams expo html = switch (exportParams.getDocumentType()) { case LIVE_DOC, WIKI_PAGE -> localizeEnums(html, exportParams); case LIVE_REPORT, TEST_RUN -> html; - case BASELINE_COLLECTION -> null; }; if (exportParams.isEnableCommentsRendering()) { diff --git a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/widgets/BulkPdfExportWidgetRenderer.java b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/widgets/BulkPdfExportWidgetRenderer.java index 461d72c6..cf0dffa0 100644 --- a/src/main/java/ch/sbb/polarion/extension/pdf_exporter/widgets/BulkPdfExportWidgetRenderer.java +++ b/src/main/java/ch/sbb/polarion/extension/pdf_exporter/widgets/BulkPdfExportWidgetRenderer.java @@ -3,6 +3,7 @@ import com.polarion.alm.server.api.model.rp.widget.AbstractWidgetRenderer; import com.polarion.alm.server.api.model.rp.widget.BottomQueryLinksBuilder; import com.polarion.alm.shared.api.model.ModelObject; +import com.polarion.alm.shared.api.model.PrototypeEnum; import com.polarion.alm.shared.api.model.rp.parameter.CompositeParameter; import com.polarion.alm.shared.api.model.rp.parameter.DataSet; import com.polarion.alm.shared.api.model.rp.parameter.DataSetParameter; @@ -10,6 +11,7 @@ import com.polarion.alm.shared.api.model.rp.parameter.FieldsParameter; import com.polarion.alm.shared.api.model.rp.parameter.IntegerParameter; import com.polarion.alm.shared.api.model.rp.parameter.SortingParameter; +import com.polarion.alm.shared.api.model.rp.parameter.impl.dataset.FieldImpl; import com.polarion.alm.shared.api.model.rp.widget.RichPageWidgetCommonContext; import com.polarion.alm.shared.api.utils.collections.IterableWithSize; import com.polarion.alm.shared.api.utils.html.HtmlContentBuilder; @@ -20,7 +22,12 @@ import com.polarion.alm.ui.shared.LinearGradientColor; import org.jetbrains.annotations.NotNull; +import java.util.ArrayList; import java.util.Iterator; +import java.util.List; +import java.util.stream.Collectors; + +import static com.polarion.alm.shared.api.model.baselinecollection.BaselineCollectionFieldsEnum.elements; public class BulkPdfExportWidgetRenderer extends AbstractWidgetRenderer { @NotNull @@ -36,16 +43,35 @@ public BulkPdfExportWidgetRenderer(@NotNull RichPageWidgetCommonContext context) super(context); DataSetParameter dataSetParameter = context.parameter("dataSet"); FieldsParameter columnsParameter = dataSetParameter.get("columns"); + + if (PrototypeEnum.BaselineCollection.equals(dataSetParameter.prototype())) { + List fields = columnsParameter.fields().toArrayList(); + if (fields.stream().noneMatch(field -> "elements".equals(field.id()))) { + fields.add(new FieldImpl("elements")); + columnsParameter.set().fields(fields.stream().map(Field::id).collect(Collectors.toList())); + } + } + SortingParameter sortByParameter = dataSetParameter.get("sortBy"); String sort = sortByParameter.asLuceneSortString(); this.dataSet = dataSetParameter.getFor().sort(sort).revision(null); this.items = this.dataSet.items(); switch (dataSetParameter.prototype()) { - case Document: dataType = "Documents"; break; - case RichPage: dataType = "Pages"; break; - case TestRun: dataType = "Test Runs"; break; - case "BaselineCollection": dataType = "Collections"; break; - default: dataType = "Unknown"; break; + case Document: + dataType = "Documents"; + break; + case RichPage: + dataType = "Pages"; + break; + case TestRun: + dataType = "Test Runs"; + break; + case BaselineCollection: + dataType = "Collections"; + break; + default: + dataType = "Unknown"; + break; } this.columns = columnsParameter.fields(); @@ -148,6 +174,7 @@ private void renderItem(@NotNull HtmlContentBuilder builder, @NotNull ModelObjec .byName("data-type", item.getOldApi().getPrototype().getName()) .byName("data-space", getSpace(item)) .byName("data-id", getValue(item, "id")) + .byName("data-name", getValue(item, "name")) .className("export-item"); for (Field column : this.columns) { diff --git a/src/main/resources/webapp/pdf-exporter/js/bulk-pdf-exporter.js b/src/main/resources/webapp/pdf-exporter/js/bulk-pdf-exporter.js index 9bf2da7e..b0fca286 100644 --- a/src/main/resources/webapp/pdf-exporter/js/bulk-pdf-exporter.js +++ b/src/main/resources/webapp/pdf-exporter/js/bulk-pdf-exporter.js @@ -88,7 +88,7 @@ const BulkPdfExporter = { const nameSpan = document.createElement("span"); nameSpan.className = "name"; - nameSpan.innerText = this.getSpace(selectedCheckbox) + selectedCheckbox.dataset["id"]; + nameSpan.innerText = this.getDocumentType(selectedCheckbox.dataset["type"]) === ExportParams.DocumentType.BASELINE_COLLECTION ? selectedCheckbox.dataset["name"] : this.getSpace(selectedCheckbox) + selectedCheckbox.dataset["id"]; titleSpan.appendChild(nameSpan); div.appendChild(titleSpan); @@ -212,38 +212,60 @@ const BulkPdfExporter = { this.exportParams["documentType"] = documentType; const documentId = currentItem.dataset["id"]; if (documentType === ExportParams.DocumentType.TEST_RUN) { - this.exportParams["urlQueryParameters"] = { id: documentId }; + this.exportParams["urlQueryParameters"] = {id: documentId}; ExportCommon.downloadTestRunAttachments(this.exportParams.projectId, documentId, this.exportParams.revision, this.exportParams.attachmentsFilter); } else if (documentType === ExportParams.DocumentType.BASELINE_COLLECTION) { - this.exportParams["collectionId"] = { id: nextItem.dataset["id"] }; + ExportCommon.downloadCollectionItems(this.exportParams, documentId, () => { + currentItem.classList.remove("in-progress"); + currentItem.classList.add("finished"); + BulkPdfExporter.finishedCount += 1; + BulkPdfExporter.updateState(BULK_EXPORT_IN_PROGRESS); + this.startNextItemExport(); + }, + (error) => { + this.errors = true; + currentItem.classList.remove("in-progress"); + currentItem.classList.add("error"); + error.text().then(errorJson => { + const error = errorJson && JSON.parse(errorJson); + const errorMessage = error && (error.message ? error.message : error.errorMessage); + const errorDiv = document.createElement("div"); + errorDiv.className = "error-message"; + errorDiv.innerText = errorMessage; + currentItem.appendChild(errorDiv); + }); + this.startNextItemExport(); + }); } else { this.exportParams["locationPath"] = `${currentItem.dataset["space"]}/${documentId}`; } - ExportCommon.asyncConvertPdf(this.exportParams.toJSON(), (responseBody, fileName) => { - currentItem.classList.remove("in-progress"); - currentItem.classList.add("finished"); + if (documentType !== ExportParams.DocumentType.BASELINE_COLLECTION) { + ExportCommon.asyncConvertPdf(this.exportParams.toJSON(), (responseBody, fileName) => { + currentItem.classList.remove("in-progress"); + currentItem.classList.add("finished"); - BulkPdfExporter.finishedCount += 1; - BulkPdfExporter.updateState(BULK_EXPORT_IN_PROGRESS); - const downloadFileName = fileName || `${currentItem.dataset["space"] ? currentItem.dataset["space"] + "_" : ""}${documentId}.pdf`; // Fallback if file name wasn't received in response - ExportCommon.downloadBlob(responseBody, downloadFileName); - this.startNextItemExport(); - }, errorResponse => { - this.errors = true; - currentItem.classList.remove("in-progress"); - currentItem.classList.add("error"); + BulkPdfExporter.finishedCount += 1; + BulkPdfExporter.updateState(BULK_EXPORT_IN_PROGRESS); + const downloadFileName = fileName || `${currentItem.dataset["space"] ? currentItem.dataset["space"] + "_" : ""}${documentId}.pdf`; // Fallback if file name wasn't received in response + ExportCommon.downloadBlob(responseBody, downloadFileName); + this.startNextItemExport(); + }, errorResponse => { + this.errors = true; + currentItem.classList.remove("in-progress"); + currentItem.classList.add("error"); - errorResponse.text().then(errorJson => { - const error = errorJson && JSON.parse(errorJson); - const errorMessage = error && (error.message ? error.message : error.errorMessage); - const errorDiv = document.createElement("div"); - errorDiv.className = "error-message"; - errorDiv.innerText = errorMessage; - currentItem.appendChild(errorDiv); + errorResponse.text().then(errorJson => { + const error = errorJson && JSON.parse(errorJson); + const errorMessage = error && (error.message ? error.message : error.errorMessage); + const errorDiv = document.createElement("div"); + errorDiv.className = "error-message"; + errorDiv.innerText = errorMessage; + currentItem.appendChild(errorDiv); + }); + this.startNextItemExport(); }); - this.startNextItemExport(); - }); + } } else if (this.state !== BULK_EXPORT_INTERRUPTED) { this.updateState(BULK_EXPORT_FINISHED); } diff --git a/src/main/resources/webapp/pdf-exporter/js/export-common.js b/src/main/resources/webapp/pdf-exporter/js/export-common.js index 2284c1db..b14440e4 100644 --- a/src/main/resources/webapp/pdf-exporter/js/export-common.js +++ b/src/main/resources/webapp/pdf-exporter/js/export-common.js @@ -113,4 +113,57 @@ const ExportCommon = { setTimeout(() => URL.revokeObjectURL(objectURL), 100); }, + downloadCollectionItems: function (exportParams, collectionId, onComplete, onError) { + let url = `/polarion/pdf-exporter/rest/internal/projects/${exportParams.projectId}/collections/${collectionId}`; + SbbCommon.callAsync({ + method: "GET", + url: url, + responseType: "json", + onOk: (responseText, request) => { + const collectionItems = request.response; + + if (!collectionItems || collectionItems.length === 0) { + console.warn("No items found in the collection."); + onComplete && onComplete(); + return; + } + + let completedCount = 0; + let hasErrors = false; + + const handleItem = (item) => { + exportParams["locationPath"] = item.moduleNameWithSpace; + exportParams["revision"] = item.revision; + exportParams["documentType"] = ExportParams.DocumentType.LIVE_DOC; + + this.asyncConvertPdf( + exportParams.toJSON(), + (responseBody, fileName) => { + const downloadFileName = fileName || "downloaded_document.pdf"; + this.downloadBlob(responseBody, downloadFileName); + + completedCount++; + if (completedCount === collectionItems.length && !hasErrors) { + onComplete && onComplete(); + } + }, + (errorResponse) => { + console.error("Error converting item:", errorResponse); + hasErrors = true; + completedCount++; + if (completedCount === collectionItems.length) { + onError && onError(errorResponse); + } + } + ); + }; + + collectionItems.forEach(handleItem); + }, + onError: (status, errorMessage, request) => { + console.error("Error loading collection items:", request.response); + onError && onError(errorMessage); + } + }); + }, } diff --git a/src/main/resources/webapp/pdf-exporter/js/modules/ExportParams.js b/src/main/resources/webapp/pdf-exporter/js/modules/ExportParams.js index 7edcedb0..1be4c235 100644 --- a/src/main/resources/webapp/pdf-exporter/js/modules/ExportParams.js +++ b/src/main/resources/webapp/pdf-exporter/js/modules/ExportParams.js @@ -55,7 +55,6 @@ export default class ExportParams { this.urlQueryParameters = builder.urlQueryParameters; this.attachmentsFilter = builder.attachmentsFilter; this.internalContent = builder.internalContent; - this.collectionId = builder.collectionId; } toJSON() { @@ -105,7 +104,6 @@ export default class ExportParams { this.urlQueryParameters = undefined; this.attachmentsFilter = undefined; this.internalContent = undefined; - this.collectionId = undefined; } setProjectId(projectId) { @@ -238,11 +236,6 @@ export default class ExportParams { return this; } - setCollectionId(collectionId) { - this.collectionId = collectionId; - return this; - } - build() { return new ExportParams(this); }