Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions ProcessMaker/Http/Controllers/Api/ProcessController.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down
33 changes: 18 additions & 15 deletions resources/js/components/shared/EllipsisMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,24 @@
</b-dropdown-item>
</div>
<div v-else>
<b-dropdown-item
v-for="action in filterActions"
:key="action.value"
:href="action.link ? itemLink(action, data) : null"
class="ellipsis-dropdown-item mx-auto"
@click="!action.link ? onClick(action, data) : null"
>
<div class="ellipsis-dropdown-content">
<i
class="pr-1 fa-fw"
:class="action.icon"
/>
<span>{{ $t(action.content) }}</span>
</div>
</b-dropdown-item>
<div v-for="action in filterActions">
<b-dropdown-divider v-if="action.value == 'divider'"/>
<b-dropdown-item v-else
:key="action.value"
:href="action.link ? itemLink(action, data) : null"
class="ellipsis-dropdown-item mx-auto"
@click="!action.link ? onClick(action, data) : null"
>
<div class="ellipsis-dropdown-content">
<i
class="pr-1 fa-fw"
:class="action.icon"
/>
<span>{{ $t(action.content) }}</span>
</div>
</b-dropdown-item>

</div>
</div>
</b-dropdown>
</template>
Expand Down
33 changes: 31 additions & 2 deletions resources/js/processes/components/ProcessesListing.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
:permission="permission"
:data="props.rowData"
:is-documenter-installed="isDocumenterInstalled"
:divider="true"
:divider="false"
/>
</template>
</vuetable>
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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) {
Expand Down
21 changes: 6 additions & 15 deletions resources/js/processes/modeler/components/ModelerApp.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
ref="modeler"
:owner="self"
:decorations="decorations"
:validationBar="validationBar"
@validate="validationErrors = $event"
@warnings="warnings = $event"
@saveBpmn="emitSaveEvent"
Expand All @@ -25,22 +26,12 @@
@set-xml-manager="xmlManager = $event"
/>
</b-card-body>

<validation-status
ref="validationStatus"
:validation-errors="validationErrors"
:warnings="warnings"
<component
:is="component.panel"
v-for="(component, index) in validationBar"
:key="`validation-status-${index}`"
:owner="self"
:xml-manager="xmlManager"
>
<component
:is="component"
v-for="(component, index) in validationBar"
:key="`validation-status-${index}`"
:owner="self"
/>
</validation-status>

/>
<component
:is="component.type"
v-for="(component, index) in external"
Expand Down
1 change: 1 addition & 0 deletions routes/api.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@
Route::get('processes', [ProcessController::class, 'index'])->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');
Expand Down