diff --git a/ProcessMaker/Http/Controllers/Api/ProcessController.php b/ProcessMaker/Http/Controllers/Api/ProcessController.php
index a133c85064..cd1efe76c1 100644
--- a/ProcessMaker/Http/Controllers/Api/ProcessController.php
+++ b/ProcessMaker/Http/Controllers/Api/ProcessController.php
@@ -998,6 +998,49 @@ public function import(Process $process, Request $request)
]);
}
+ /**
+ * Download the BPMN definition of a process
+ *
+ * @param $process
+ *
+ * @return Response
+ *
+ * @OA\Get(
+ * path="/processes/{processId}/bpmn",
+ * summary="Download the BPMN definition of a process",
+ * operationId="processBpmn",
+ * tags={"Processes"},
+ * @OA\Parameter(
+ * description="ID of process",
+ * in="path",
+ * name="processId",
+ * required=true,
+ * @OA\Schema(
+ * type="integer",
+ * )
+ * ),
+ * @OA\Response(
+ * response=200,
+ * description="Successfully built the process for export",
+ * @OA\JsonContent(
+ * type="object",
+ * @OA\Property(
+ * property="url",
+ * type="string",
+ * ),
+ * ),
+ * ),
+ * )
+ */
+ public function downloadBpmn(Request $request, Process $process)
+ {
+ $bpmn = $process->bpmn;
+ $filename = 'bpmnProcess.bpmn';
+ return response()->streamDownload(function () use ($bpmn) {
+ echo $bpmn;
+ }, $filename);
+ }
+
/**
* Check if the import is ready
*
diff --git a/resources/js/components/shared/EllipsisMenu.vue b/resources/js/components/shared/EllipsisMenu.vue
index c9dca6791f..6057c3399c 100644
--- a/resources/js/components/shared/EllipsisMenu.vue
+++ b/resources/js/components/shared/EllipsisMenu.vue
@@ -56,21 +56,24 @@
-
-
-
- {{ $t(action.content) }}
-
-
+
+
+
+
+
+ {{ $t(action.content) }}
+
+
+
+
diff --git a/resources/js/processes/components/ProcessesListing.vue b/resources/js/processes/components/ProcessesListing.vue
index 0a9f1cb8f1..6ab1c8d833 100644
--- a/resources/js/processes/components/ProcessesListing.vue
+++ b/resources/js/processes/components/ProcessesListing.vue
@@ -51,7 +51,7 @@
:permission="permission"
:data="props.rowData"
:is-documenter-installed="isDocumenterInstalled"
- :divider="true"
+ :divider="false"
/>
@@ -95,9 +95,11 @@
{ value: "create-pm-block", content: "Save as PM Block", permission: "create-pm-blocks", icon: "fas nav-icon fa-cube" },
{ value: "edit-item", content: "Configure", link: true, href:"/processes/{{id}}/edit", permission: "edit-processes", icon: "fas fa-cog", conditional: "if(status == 'ACTIVE' or status == 'INACTIVE', true, false)"},
{ value: "view-documentation", content: "View Documentation", link: true, href:"/modeler/{{id}}/print", permission: "view-processes", icon: "fas fa-sign", conditional: "isDocumenterInstalled"},
+ { value: "remove-item", content: "Archive", permission: "archive-processes", icon: "fas fa-archive", conditional: "if(status == 'ACTIVE' or status == 'INACTIVE', true, false)" },
+ { value: "divider" },
{ value: "export-item", content: "Export", link: true, href:"/processes/{{id}}/export", permission: "export-processes", icon: "fas fa-file-export"},
- { value: "remove-item", content: "Archive", permission: "archive-processes", icon: "fas fa-download", conditional: "if(status == 'ACTIVE' or status == 'INACTIVE', true, false)" },
{ value: "restore-item", content: "Restore", permission: "archive-processes", icon: "fas fa-upload", conditional: "if(status == 'ARCHIVED', true, false)" },
+ { value: "download-bpmn", content: "Download BPMN", permission: "view-processes", icon: "fas fa-file-download"},
],
orderBy: "name",
processId: null,
@@ -235,6 +237,33 @@
}
);
break;
+
+ case "download-bpmn":
+ ProcessMaker.confirmModal(
+ this.$t("Caution!"),
+ this.$t("Are you sure you want to download the BPMN definition of the process?"),
+ "",
+ () => {
+ ProcessMaker.apiClient
+ .get("processes/" + data.id + "/bpmn")
+ .then(response => {
+
+ const link = document.createElement("a");
+ const file = new Blob([response.data], { type: 'text/plain' });
+
+ link.href = URL.createObjectURL(file);
+ link.download = "bpmnProcess.xml";
+ link.click();
+ URL.revokeObjectURL(link.href);
+
+ ProcessMaker.alert(
+ this.$t("The process BPMN has been downloaded."),
+ "success"
+ );
+ });
+ }
+ );
+ break;
}
},
formatStatus(status) {
diff --git a/resources/js/processes/modeler/components/ModelerApp.vue b/resources/js/processes/modeler/components/ModelerApp.vue
index 428839886c..d0baa89850 100644
--- a/resources/js/processes/modeler/components/ModelerApp.vue
+++ b/resources/js/processes/modeler/components/ModelerApp.vue
@@ -15,6 +15,7 @@
ref="modeler"
:owner="self"
:decorations="decorations"
+ :validationBar="validationBar"
@validate="validationErrors = $event"
@warnings="warnings = $event"
@saveBpmn="emitSaveEvent"
@@ -25,22 +26,12 @@
@set-xml-manager="xmlManager = $event"
/>
-
-
-
-
-
+ />
name('processes.index')->middleware('can:view-processes');
Route::get('processes/{process}', [ProcessController::class, 'show'])->name('processes.show')->middleware('can:view-processes');
Route::post('processes/{process}/export', [ProcessController::class, 'export'])->name('processes.export')->middleware('can:export-processes');
+ Route::get('processes/{process}/bpmn', [ProcessController::class, 'downloadBpmn'])->name('processes.export')->middleware('can:view-processes');
Route::post('processes/import', [ProcessController::class, 'import'])->name('processes.import')->middleware('can:import-processes');
Route::post('processes/import/validation', [ProcessController::class, 'preimportValidation'])->name('processes.preimportValidation')->middleware('can:import-processes');
Route::get('processes/import/{code}/is_ready', [ProcessController::class, 'import_ready'])->name('processes.import_is_ready')->middleware('can:import-processes');