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
13 changes: 10 additions & 3 deletions ProcessMaker/Http/Controllers/Api/ProcessRequestController.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Contracts\Routing\ResponseFactory;
use Illuminate\Database\QueryException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
Expand Down Expand Up @@ -639,6 +640,7 @@ public function getRequestToken(Request $httpRequest, ProcessRequest $request)
]);

$elementId = null;
$countFlag = false;
$maxTokenId = $this->getMaxTokenId($request, $httpRequest->element_id);
if ($maxTokenId === null) {
$bpmn = $request->process->versions()
Expand All @@ -660,6 +662,8 @@ public function getRequestToken(Request $httpRequest, ProcessRequest $request)

// Get the minimum repeated node ID.
$elementId = ($sourceTokensCount < $targetTokensCount) ? $sourceRef : $targetRef;
// Get a Flag to adjust the repeat quantity
$countFlag = $this->getCountFlag($sourceTokensCount, $targetTokensCount, $sourceRef, $request);
}

// Get the maximum node ID.
Expand All @@ -671,7 +675,7 @@ public function getRequestToken(Request $httpRequest, ProcessRequest $request)
->where('id', $maxTokenId)
->select('user_id', 'element_id', 'element_name', 'created_at', 'completed_at', 'status')
->with([
'user' => fn ($query) => $query->select('id', 'username'),
'user' => fn ($query) => $query->select('id', 'username', 'firstname', 'lastname'),
])
->firstOrFail();

Expand All @@ -684,15 +688,18 @@ public function getRequestToken(Request $httpRequest, ProcessRequest $request)
default => $token->status,
};
$token->status_translation = $translatedStatus;
$token->completed_by = $token->completed_at ? ($token->user['username'] ?? '-') : '-';
$token->completed_by = $token->completed_at ? ($token->user['fullname'] ?? '-') : '-';

// Get the number of times the flow has run.
$tokensCount = $request->tokens()
->where([
'element_id' => $httpRequest->element_id,
'process_request_id'=> $request->id,
])->count();
$token->count = $tokensCount;
$token->count = $countFlag ? $tokensCount - 1 : $tokensCount;
if ($token->count === 0) {
throw new ModelNotFoundException();
}

return new ApiResource($token);
}
Expand Down
15 changes: 8 additions & 7 deletions ProcessMaker/Http/Controllers/Process/ModelerController.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace ProcessMaker\Http\Controllers\Process;

use Illuminate\Http\Request;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Http;
use ProcessMaker\Events\ModelerStarting;
use ProcessMaker\Http\Controllers\Controller;
Expand All @@ -14,7 +13,6 @@
use ProcessMaker\PackageHelper;
use ProcessMaker\Traits\HasControllerAddons;
use ProcessMaker\Traits\ProcessMapTrait;
use SimpleXMLElement;

class ModelerController extends Controller
{
Expand Down Expand Up @@ -51,17 +49,17 @@ public function show(ModelerManager $manager, Process $process, Request $request
/**
* Invokes the Modeler for In-flight Process Map rendering.
*/
public function inflight(ModelerManager $manager, Process $process, Request $request)
public function inflight(ModelerManager $manager, Process $process, ProcessRequest $request)
{
event(new ModelerStarting($manager));

$bpmn = $process->bpmn;
$requestCompletedNodes = [];
$filteredCompletedNodes = [];
$requestInProgressNodes = [];
$requestIdleNodes = [];

// Use the process version that was active when the request was started.
$processRequest = ProcessRequest::find($request->request_id);
$processRequest = ProcessRequest::find($request->id);
if ($processRequest) {
$bpmn = $process->versions()
->where('id', $processRequest->process_version_id)
Expand All @@ -73,13 +71,16 @@ public function inflight(ModelerManager $manager, Process $process, Request $req
// Remove any node that is 'ACTIVE' from the completed list.
$filteredCompletedNodes = $requestCompletedNodes->diff($requestInProgressNodes)->values();

// Obtain In-Progress nodes that were completed before
$matchingNodes = $requestInProgressNodes->intersect($requestCompletedNodes);

// Get idle nodes.
$xml = $this->loadAndPrepareXML($bpmn);
$nodeIds = $this->getNodeIds($xml);
$requestIdleNodes = $nodeIds->diff($filteredCompletedNodes)->diff($requestInProgressNodes)->values();

// Add completed sequence flow to the list of completed nodes.
$sequenceFlowNodes = $this->getCompletedSequenceFlow($xml, $filteredCompletedNodes->implode(' '), $requestInProgressNodes->implode(' '));
$sequenceFlowNodes = $this->getCompletedSequenceFlow($xml, $filteredCompletedNodes->implode(' '), $requestInProgressNodes->implode(' '), $matchingNodes->implode(' '));
$filteredCompletedNodes = $filteredCompletedNodes->merge($sequenceFlowNodes);
}

Expand All @@ -89,7 +90,7 @@ public function inflight(ModelerManager $manager, Process $process, Request $req
'requestCompletedNodes' => $filteredCompletedNodes,
'requestInProgressNodes' => $requestInProgressNodes,
'requestIdleNodes' => $requestIdleNodes,
'requestId' => $request->request_id,
'requestId' => $request->id,
]);
}

Expand Down
15 changes: 13 additions & 2 deletions ProcessMaker/Traits/ProcessMapTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,14 @@ private function getNodeIds(SimpleXMLElement $xml): Collection
/**
* Performs an XPath query to get sequenceFlow elements
* whose 'sourceRef' attribute is in the string of completed nodes
* and 'targetRef' attribute is in the string of in-progress and completed nodes.
* and 'targetRef' attribute is in the string of in-progress and completed nodes
* also validates Nodes in progress that were completed before to obtain their paths.
*/
private function getCompletedSequenceFlow(SimpleXMLElement $xml, string $completedNodesStr, string $inProgressNodesStr): Collection
private function getCompletedSequenceFlow(SimpleXMLElement $xml, string $completedNodesStr, string $inProgressNodesStr, string $completedInProgressNode): Collection
{
$inProgressAndCompletedNodes = $completedNodesStr . ' ' . $inProgressNodesStr;
$query = '//bpmn:sequenceFlow[contains("' . $completedNodesStr . '", @sourceRef) and contains("' . $inProgressAndCompletedNodes . '", @targetRef)]/@id';
$query = $query. ' | //bpmn:sequenceFlow[contains("' . $completedInProgressNode . '", @sourceRef) and contains("' . $inProgressAndCompletedNodes . '", @targetRef)]/@id';

return $this->filterXML($xml, $query);
}
Expand All @@ -96,4 +98,13 @@ private function getRefNodes(SimpleXMLElement $xml, string $sequenceFlowId): Col
'sourceRef' => (string) $sequenceFlowNode[0]['sourceRef'],
]);
}
/**
* Validates if the sourceRef token is in progress when the repeat count is the same as the targetRef
*/
private function getCountFlag(int $sourceCount, int $targetCount,string $sourceRef, ProcessRequest $request) :bool
{
$maxToken = $request->tokens()->find($this->getMaxTokenId($request, $sourceRef));

return $maxToken->status === 'ACTIVE' && $sourceCount === $targetCount;
}
}
27 changes: 20 additions & 7 deletions resources/js/processes/modeler/components/ProcessMap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
data-test="body-container"
>
<ProcessMapTooltip
v-show="tooltip.isActive"
v-show="showTooltip"
ref="tooltip"
:node-id="tooltip.nodeId"
:node-name="tooltip.nodeName"
Expand All @@ -15,15 +15,16 @@
left: `${tooltip.newX}px`,
top: `${tooltip.newY}px`
}"
@is-loading="getIsLoading"
@is-loading="getIsLoading()"
/>
<ModelerReadonly
<Modeler
ref="modeler"
:owner="self"
:decorations="decorations"
:request-completed-nodes="requestCompletedNodes"
:request-in-progress-nodes="requestInProgressNodes"
:request-idle-nodes="requestIdleNodes"
:read-only="true"
@set-xml-manager="xmlManager = $event"
@click="handleClick"
/>
Expand All @@ -33,13 +34,13 @@
</template>

<script>
import { ModelerReadonly } from "@processmaker/modeler";
import { Modeler } from "@processmaker/modeler";
import ProcessMapTooltip from "./ProcessMapTooltip.vue";

export default {
name: "ProcessMap",
components: {
ModelerReadonly,
Modeler,
ProcessMapTooltip,
},
data() {
Expand Down Expand Up @@ -72,11 +73,21 @@ export default {
requestId: window.ProcessMaker.modeler.requestId,
};
},
computed: {
isMappingActive() {
return window.ProcessMaker.modeler.enableProcessMapping !== undefined
? window.ProcessMaker.modeler.enableProcessMapping
: true;
},
showTooltip() {
return this.tooltip.isActive;
},
},
watch: {
"tooltip.isLoading": {
handler(value) {
if (!value) {
this.$nextTick().then(() => {
this.$nextTick(() => {
this.calculateTooltipPosition();
});
}
Expand All @@ -96,7 +107,9 @@ export default {
});
}, 60000),
handleClick(payload) {
this.setupTooltip(payload);
if (this.isMappingActive) {
this.setupTooltip(payload);
}
},
setupTooltip({ event, node }) {
const isNodeTooltipAllowed = this.tooltip.allowedNodes.includes(node.$type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default {
},
},
requestId: {
type: String,
type: Number,
default() {
return null;
},
Expand Down
2 changes: 1 addition & 1 deletion resources/js/processes/modeler/process-map.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Vue from "vue";
import ProcessMap from "./components/ProcessMap";
import ProcessMap from "./components/ProcessMap.vue";

window.ProcessMaker.i18nPromise.then(() => {
new Vue({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
const breadcrumbData = [];
window.ProcessMaker.modeler = {
xml: @json($bpmn),
enableProcessMapping: false,
}

window.ProcessMaker.EventBus.$on('modeler-start', ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@

@section('css')
<style>
/* See node_modules/@processmaker/modeler/src/components/highlightColors.js */
:root {
--color-line-in-progress: #1572C2;
--color-line-completed: #00875A;
--color-line-in-progress: #3FA6FF;
--color-line-completed: #00BA7C;
}

#map-legend.map-legend-card {
Expand Down Expand Up @@ -48,7 +49,7 @@
}

.in-progress-line {
border-right-style: dashed;
border-right-style: solid;
border-right-color: var(--color-line-in-progress);
}

Expand Down
2 changes: 1 addition & 1 deletion resources/views/requests/show.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ class="tab-pane card card-body border-top-0 p-3">
</div>
<div v-show="!iframeLoading">
<iframe class="card"
src="{{ route('modeler.inflight', ['process' => $request->process->id, 'request_id' => $request->id]) }}"
src="{{ route('modeler.inflight', ['process' => $request->process->id, 'request' => $request->id]) }}"
width="100%" height="640px" frameborder="0" style="border-radius: 4px;"
@load="onLoadIframe"></iframe>
@include('processes.modeler.partials.map-legend')
Expand Down
4 changes: 2 additions & 2 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@

Route::get('script-executors', [ScriptExecutorController::class, 'index'])->name('script-executors.index');

//temporary, should be removed
// temporary, should be removed
Route::get('security-logs/download/all', [\ProcessMaker\Http\Controllers\Api\SecurityLogController::class, 'downloadForAllUsers'])->middleware('can:view-security-logs');
Route::get('security-logs/download/{user}', [\ProcessMaker\Http\Controllers\Api\SecurityLogController::class, 'downloadForUser'])->middleware('can:view-security-logs');
});
Expand Down Expand Up @@ -106,7 +106,7 @@
Route::get('profile/{id}', [ProfileController::class, 'show'])->name('profile.show');
// Ensure our modeler loads at a distinct url
Route::get('modeler/{process}', [ModelerController::class, 'show'])->name('modeler.show')->middleware('can:edit-processes');
Route::get('modeler/{process}/inflight', [ModelerController::class, 'inflight'])->name('modeler.inflight')->middleware('can:edit-processes');
Route::get('modeler/{process}/inflight/{request?}', [ModelerController::class, 'inflight'])->name('modeler.inflight')->middleware('can:view,request');

Route::get('/', [HomeController::class, 'index'])->name('home');

Expand Down