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
26 changes: 26 additions & 0 deletions ProcessMaker/Http/Controllers/Process/ModelerController.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use ProcessMaker\Managers\ModelerManager;
use ProcessMaker\Managers\SignalManager;
use ProcessMaker\Models\Process;
use ProcessMaker\Models\ProcessRequest;
use ProcessMaker\PackageHelper;
use ProcessMaker\Traits\HasControllerAddons;

Expand Down Expand Up @@ -41,4 +42,29 @@ public function show(ModelerManager $manager, Process $process, Request $request
'isDraft' => $draft !== null,
]);
}

/**
* Invokes the Modeler for In-flight Process Map rendering.
*/
public function inflight(ModelerManager $manager, Process $process, Request $request)
{
event(new ModelerStarting($manager));

$bpmn = $process->bpmn;

// Use the process version that was active when the request was started.
$processRequest = ProcessRequest::find($request->request_id);
if ($processRequest) {
$bpmn = $process->versions()
->where('id', $processRequest->process_version_id)
->firstOrFail()
->bpmn;
}

return view('processes.modeler.inflight', [
'manager' => $manager,
'process' => $process,
'bpmn' => $bpmn,
]);
}
}
139 changes: 139 additions & 0 deletions resources/js/process-map-layout.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import moment from "moment";

require("bootstrap");

const { Vue } = window;
if (window.ProcessMaker && window.ProcessMaker.user) {
moment.tz.setDefault(window.ProcessMaker.user.timezone);
moment.defaultFormat = window.ProcessMaker.user.datetime_format;
moment.defaultFormatUtc = window.ProcessMaker.user.datetime_format;
}
if (document.documentElement.lang) {
moment.locale(document.documentElement.lang);
window.ProcessMaker.user.lang = document.documentElement.lang;
}

Vue.prototype.moment = moment;
window.moment = moment;

// Event bus ProcessMaker.
window.ProcessMaker.events = new Vue();

window.ProcessMaker.nodeTypes = [];
window.ProcessMaker.nodeTypes.get = function (id) {
return this.find((node) => node.id === id);
};

window.ProcessMaker.navbar = new Vue({
el: "#navbar",
data() {
return {
alerts: [],
};
},
});

window.ProcessMaker.closeSessionModal = () => {
ProcessMaker.navbar.sessionShow = false;
};

// Set our own specific alert function at the ProcessMaker global object that could
// potentially be overwritten by some custom theme support
window.ProcessMaker.alert = (
msg,
variant,
showValue = 5,
stayNextScreen = false,
showLoader = false,
) => {
let updatedShowValue = showValue;
if (showValue === 0) {
// Just show it indefinitely, no countdown.
updatedShowValue = true;
}
// amount of items allowed in array
if (ProcessMaker.navbar.alerts.length > 5) {
ProcessMaker.navbar.alerts.shift();
}
ProcessMaker.navbar.alerts.push({
alertText: msg,
alertShow: updatedShowValue,
alertVariant: String(variant),
showLoader,
stayNextScreen,
timestamp: Date.now(),
});
};

// flags print forms
window.ProcessMaker.apiClient.requestCount = 0;
window.ProcessMaker.apiClient.requestCountFlag = false;

window.ProcessMaker.apiClient.interceptors.request.use((request) => {
// flags print forms
if (window.ProcessMaker.apiClient.requestCountFlag) {
window.ProcessMaker.apiClient.requestCount += 1;
}

window.ProcessMaker.EventBus.$emit("api-client-loading", request);
return request;
});

window.ProcessMaker.apiClient.interceptors.response.use(
(response) => {
window.ProcessMaker.EventBus.$emit("api-client-done", response);
// flags print forms
if (
window.ProcessMaker.apiClient.requestCountFlag
&& window.ProcessMaker.apiClient.requestCount > 0
) {
window.ProcessMaker.apiClient.requestCount -= 1;
}
return response;
},
(error) => {
window.ProcessMaker.EventBus.$emit("api-client-error", error);
if (
error.response
&& error.response.status
&& error.response.status === 401
) {
// stop 401 error consuming endpoints with data-sources
const { url } = error.config;
if (url.includes("/data_sources/")) {
if (url.includes("requests/") || url.includes("/test")) {
throw error;
}
}
window.location = "/login";
} else if (_.has(error, "config.url") && !error.config.url.match("/debug")) {
window.ProcessMaker.apiClient.post("/debug", {
name: "Javascript ProcessMaker.apiClient Error",
message: JSON.stringify({
message: error.message,
code: error.code,
config: error.config,
}),
});
}
return Promise.reject(error);
},
);

// Display any uncaught promise rejections from axios in the Process Maker alert box
window.addEventListener("unhandledrejection", (event) => {
const error = event.reason;
// eslint-disable-next-line no-underscore-dangle
if (error.config && error.config._defaultErrorShown) {
// Already handeled
event.preventDefault(); // stops the unhandled rejection error
} else if (
error.response
&& error.response.data
&& error.response.data.message
) {
window.ProcessMaker.alert(error.response.data.message, "danger");
} else if (error.message) {
window.ProcessMaker.alert(error.message, "danger");
}
});
55 changes: 55 additions & 0 deletions resources/js/processes/modeler/components/ProcessMap.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<template>
<div>
<div class="h-100">
<div
class="overflow-hidden position-relative p-0 vh-100"
data-test="body-container"
>
<ModelerReadonly
ref="modeler"
:owner="self"
:decorations="decorations"
@set-xml-manager="xmlManager = $event"
@click="handleClick"
/>
</div>
</div>
</div>
</template>

<script>
import { ModelerReadonly } from "@processmaker/modeler";

export default {
name: "ProcessMap",
components: {
ModelerReadonly,
},
data() {
return {
self: this,
validationBar: [],
process: window.ProcessMaker.modeler.process,
xmlManager: null,
decorations: {
borderOutline: {},
},
};
},
mounted() {
ProcessMaker.$modeler = this.$refs.modeler;
},
methods: {
refreshSession: _.throttle(() => {
ProcessMaker.apiClient({
method: "POST",
url: "/keep-alive",
baseURL: "/",
});
}, 60000),
handleClick() {
//
},
},
};
</script>
8 changes: 8 additions & 0 deletions resources/js/processes/modeler/process-map.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Vue from "vue";
import ProcessMap from "./components/ProcessMap";

window.ProcessMaker.i18nPromise.then(() => {
new Vue({
render: (h) => h(ProcessMap),
}).$mount("#modeler-app");
});
14 changes: 7 additions & 7 deletions resources/js/requests/show.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import Vue from "vue";
import MonacoEditor from "vue-monaco";
import debounce from "lodash/debounce";
import VueFormRenderer from "@processmaker/screen-builder";
import DataSummary from "./components/DataSummary";
import RequestDetail from "./components/RequestDetail";
import AvatarImage from "../components/AvatarImage";
import RequestErrors from "./components/RequestErrors";
import Timeline from "../components/Timeline";
import TimelineItem from "../components/TimelineItem";
import RequestScreens from "../requests/components/RequestScreens";
import DataSummary from "./components/DataSummary.vue";
import RequestDetail from "./components/RequestDetail.vue";
import AvatarImage from "../components/AvatarImage.vue";
import RequestErrors from "./components/RequestErrors.vue";
import Timeline from "../components/Timeline.vue";
import TimelineItem from "../components/TimelineItem.vue";
import RequestScreens from "./components/RequestScreens.vue";

Vue.component("DataSummary", DataSummary);
Vue.component("RequestDetail", RequestDetail);
Expand Down
8 changes: 4 additions & 4 deletions resources/js/tasks/show.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import Vuex from "vuex";
import Task from "@processmaker/screen-builder";
import MonacoEditor from "vue-monaco";
import debounce from "lodash/debounce";
import TaskView from "./components/TaskView";
import AvatarImage from "../components/AvatarImage";
import Timeline from "../components/Timeline";
import TimelineItem from "../components/TimelineItem";
import TaskView from "./components/TaskView.vue";
import AvatarImage from "../components/AvatarImage.vue";
import Timeline from "../components/Timeline.vue";
import TimelineItem from "../components/TimelineItem.vue";

Vue.use(Vuex);
Vue.use("task", Task);
Expand Down
113 changes: 113 additions & 0 deletions resources/views/layouts/process-map.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">

<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta http-equiv="Content-Security-Policy" content="script-src * 'unsafe-inline' 'unsafe-eval'; object-src 'none';">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="app-url" content="{{ config('app.url') }}">
<meta name="i18n-mdate" content='{!! json_encode(ProcessMaker\i18nHelper::mdates()) !!}'>
@if (Auth::user())
<meta name="user-id" content="{{ Auth::user()->id }}">
<meta name="datetime-format" content="{{ Auth::user()->datetime_format ?: config('app.dateformat') }}">
<meta name="timezone" content="{{ Auth::user()->timezone ?: config('app.timezone') }}">
@yield('meta')
@endif
<meta name="timeout-worker" content="{{ mix('js/timeout.js') }}">
<meta name="timeout-length"
content="{{ Session::has('rememberme') && Session::get('rememberme') ? 'Number.MAX_SAFE_INTEGER' : config('session.lifetime') }}">
<meta name="timeout-warn-seconds" content="{{ config('session.expire_warning') }}">
@if (Session::has('_alert'))
<meta name="alert" content="show">
@php
[$type, $message] = json_decode(Session::get('_alert'));
Session::forget('_alert');
@endphp
<meta name="alertVariant" content="{{ $type }}">
<meta name="alertMessage" content="{{ $message }}">
@endif

<title>@yield('title', __('Welcome')) - {{ __('ProcessMaker') }}</title>

<link rel="icon" type="image/png" sizes="16x16" href="{{ \ProcessMaker\Models\Setting::getFavicon() }}">
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
<link href="/css/bpmn-symbols/css/bpmn.css" rel="stylesheet">
@yield('css')
<script type="text/javascript">
@if (Auth::user())
window.Processmaker = {
csrfToken: "{{ csrf_token() }}",
userId: "{{ \Auth::user()->id }}",
messages: [],
apiTimeout: {{ config('app.api_timeout') }}
};
@if (config('broadcasting.default') == 'redis')
window.Processmaker.broadcasting = {
broadcaster: "socket.io",
host: "{{ config('broadcasting.connections.redis.host') }}",
key: "{{ config('broadcasting.connections.redis.key') }}"
};
@endif
@if (config('broadcasting.default') == 'pusher')
window.Processmaker.broadcasting = {
broadcaster: "pusher",
key: "{{ config('broadcasting.connections.pusher.key') }}",
cluster: "{{ config('broadcasting.connections.pusher.options.cluster') }}",
forceTLS: {{ config('broadcasting.connections.pusher.options.use_tls') ? 'true' : 'false' }},
debug: {{ config('broadcasting.connections.pusher.options.debug') ? 'true' : 'false' }}
};
@endif
@endif
</script>
@isset($addons)
<script>
var addons = [];
</script>
@foreach ($addons as $addon)
@if (!empty($addon['script']))
{!! $addon['script'] !!}
@endif
@endforeach
@endisset

@if (config('global_header'))
{!! config('global_header') !!}
@endif
</head>

<body>
<div id="app-container" class="d-flex w-100 mw-100 h-100 mh-100">
<div class="d-flex flex-grow-1 flex-column overflow-hidden">
<div class="flex-grow-1">
<div id="navbar"></div>
</div>
<div class="flex-grow-1 d-flex flex-column h-100 overflow-hidden" id="mainbody">
<div id="main" class="main flex-grow-1 h-100 overflow-hidden">
@yield('content')
</div>
</div>
</div>
</div>

<!-- Scripts -->
@if (config('broadcasting.default') == 'redis')
<script src="{{ config('broadcasting.connections.redis.host') }}/socket.io/socket.io.js"></script>
@endif
<script src="{{ mix('js/manifest.js') }}"></script>
<script src="{{ mix('js/vendor.js') }}"></script>
<script src="{{ mix('js/app.js') }}"></script>
<script>
window.ProcessMaker.packages = @json(\App::make(ProcessMaker\Managers\PackageManager::class)->listPackages());
</script>
<script src="{{ mix('js/process-map-layout.js') }}"></script>

@foreach (GlobalScripts::getScripts() as $script)
<script src="{{ $script }}"></script>
@endforeach

@yield('js')
</body>

</html>
Loading