Skip to content

Commit f85fec3

Browse files
authored
Merge pull request #7451 from ProcessMaker/task/FOUR-18749
task/FOUR-18749: Added print-pdf Blade layout
2 parents 3bab753 + 54be2b8 commit f85fec3

File tree

3 files changed

+334
-0
lines changed

3 files changed

+334
-0
lines changed

resources/js/print-layout.js

Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
import { BNavbar } from "bootstrap-vue";
2+
import { Multiselect } from "@processmaker/vue-multiselect";
3+
import moment from "moment-timezone";
4+
import { sanitizeUrl } from "@braintree/sanitize-url";
5+
import VueHtml2Canvas from "vue-html2canvas";
6+
import Sidebaricon from "./components/Sidebaricon";
7+
import SelectStatus from "./components/SelectStatus";
8+
import SelectUser from "./components/SelectUser";
9+
import SelectUserGroup from "./components/SelectUserGroup";
10+
import CategorySelect from "./processes/categories/components/CategorySelect";
11+
import ProjectSelect from "./components/shared/ProjectSelect";
12+
import SelectFromApi from "./components/SelectFromApi";
13+
import Breadcrumbs from "./components/Breadcrumbs";
14+
import TimelineItem from "./components/TimelineItem";
15+
import Required from "./components/shared/Required";
16+
import { FileUpload, FileDownload } from "./processes/screen-builder/components";
17+
import RequiredCheckbox from "./processes/screen-builder/components/inspector/RequiredCheckbox";
18+
import WelcomeModal from "./Mobile/WelcomeModal";
19+
/** ****
20+
* Global adjustment parameters for moment.js.
21+
*/
22+
import __ from "./modules/lang";
23+
24+
require("bootstrap");
25+
26+
const { Vue } = window;
27+
28+
Vue.use(VueHtml2Canvas);
29+
30+
if (window.ProcessMaker && window.ProcessMaker.user) {
31+
moment.tz.setDefault(window.ProcessMaker.user.timezone);
32+
moment.defaultFormat = window.ProcessMaker.user.datetime_format;
33+
moment.defaultFormatUtc = window.ProcessMaker.user.datetime_format;
34+
}
35+
if (document.documentElement.lang) {
36+
moment.locale(document.documentElement.lang);
37+
window.ProcessMaker.user.lang = document.documentElement.lang;
38+
}
39+
Vue.prototype.moment = moment;
40+
// initializing global instance of a moment object
41+
window.moment = moment;
42+
/** ***** */
43+
44+
Vue.prototype.$sanitize = sanitizeUrl;
45+
46+
Vue.component("Multiselect", Multiselect);
47+
Vue.component("Sidebaricon", Sidebaricon);
48+
Vue.component("SelectStatus", SelectStatus);
49+
Vue.component("SelectUser", SelectUser);
50+
Vue.component("SelectUserGroup", SelectUserGroup);
51+
Vue.component("CategorySelect", CategorySelect);
52+
Vue.component("ProjectSelect", ProjectSelect);
53+
Vue.component("SelectFromApi", SelectFromApi);
54+
Vue.component("FileUpload", FileUpload);
55+
Vue.component("FileDownload", FileDownload);
56+
Vue.component("RequiredCheckbox", RequiredCheckbox);
57+
Vue.component("Breadcrumbs", Breadcrumbs);
58+
Vue.component("TimelineItem", TimelineItem);
59+
Vue.component("Required", Required);
60+
Vue.component("Welcome", WelcomeModal);
61+
62+
// Event bus ProcessMaker
63+
window.ProcessMaker.events = new Vue();
64+
65+
window.ProcessMaker.nodeTypes = [];
66+
window.ProcessMaker.nodeTypes.get = function (id) {
67+
return this.find((node) => node.id === id);
68+
};
69+
70+
// Assign our navbar component to our global ProcessMaker object
71+
window.ProcessMaker.navbar = {};
72+
73+
// Set our own specific alert function at the ProcessMaker global object that could
74+
// potentially be overwritten by some custom theme support
75+
window.ProcessMaker.navbar.alerts = [];
76+
window.ProcessMaker.alert = function (msg, variant, showValue = 5, stayNextScreen = false, showLoader = false, msgLink = "", msgTitle = "") {
77+
if (showValue === 0) {
78+
// Just show it indefinitely, no countdown
79+
showValue = true;
80+
}
81+
// amount of items allowed in array
82+
if (ProcessMaker.navbar.alerts.length > 5) {
83+
ProcessMaker.navbar.alerts.shift();
84+
}
85+
ProcessMaker.navbar.alerts.push({
86+
alertText: msg,
87+
alertLink: msgLink,
88+
alertTitle: msgTitle,
89+
alertShow: showValue,
90+
alertVariant: String(variant),
91+
showLoader,
92+
stayNextScreen,
93+
timestamp: Date.now(),
94+
});
95+
};
96+
97+
// Set out own specific confirm modal.
98+
window.ProcessMaker.confirmModal = function (title, message, variant, callback, size = "md", dataTestClose = "confirm-btn-close", dataTestOk = "confirm-btn-ok") {
99+
ProcessMaker.navbar.confirmTitle = title || __("Confirm");
100+
ProcessMaker.navbar.confirmMessage = message || __("Are you sure you want to delete?");
101+
ProcessMaker.navbar.confirmVariant = variant;
102+
ProcessMaker.navbar.confirmCallback = callback;
103+
ProcessMaker.navbar.confirmShow = true;
104+
ProcessMaker.navbar.confirmSize = size;
105+
ProcessMaker.navbar.confirmDataTestClose = dataTestClose;
106+
ProcessMaker.navbar.confirmDataTestOk = dataTestOk;
107+
};
108+
109+
// Set out own specific message modal.
110+
window.ProcessMaker.messageModal = function (title, message, variant, callback) {
111+
ProcessMaker.navbar.messageTitle = title || __("Message");
112+
ProcessMaker.navbar.messageMessage = message || __("");
113+
ProcessMaker.navbar.messageVariant = variant;
114+
ProcessMaker.navbar.messageCallback = callback;
115+
ProcessMaker.navbar.messageShow = true;
116+
};
117+
118+
// flags print forms
119+
window.ProcessMaker.apiClient.requestCount = 0;
120+
window.ProcessMaker.apiClient.requestCountFlag = false;
121+
122+
window.ProcessMaker.apiClient.interceptors.request.use((request) => {
123+
// flags print forms
124+
if (window.ProcessMaker.apiClient.requestCountFlag) {
125+
window.ProcessMaker.apiClient.requestCount++;
126+
}
127+
128+
window.ProcessMaker.EventBus.$emit("api-client-loading", request);
129+
return request;
130+
});
131+
132+
window.ProcessMaker.apiClient.interceptors.response.use((response) => {
133+
// TODO: this could be used to show a default "created/upated/deleted resource" alert
134+
// response.config.method (PUT, POST, DELETE)
135+
// response.config.url (extract resource name)
136+
window.ProcessMaker.EventBus.$emit("api-client-done", response);
137+
// flags print forms
138+
if (window.ProcessMaker.apiClient.requestCountFlag && window.ProcessMaker.apiClient.requestCount > 0) {
139+
window.ProcessMaker.apiClient.requestCount--;
140+
}
141+
return response;
142+
}, (error) => {
143+
// Set in your .catch to false to not show the alert inside window.ProcessMaker.apiClient
144+
if (!error?.response?.showAlert) {
145+
return Promise.reject(error);
146+
}
147+
148+
if (error.code && error.code === "ERR_CANCELED") {
149+
return Promise.reject(error);
150+
}
151+
window.ProcessMaker.EventBus.$emit("api-client-error", error);
152+
if (error.response && error.response.status && error.response.status === 401) {
153+
// stop 401 error consuming endpoints with data-sources
154+
const { url } = error.config;
155+
if (url.includes("/data_sources/")) {
156+
if (url.includes("requests/") || url.includes("/test")) {
157+
throw error;
158+
}
159+
}
160+
window.location = "/login";
161+
} else {
162+
if (_.has(error, "config.url") && !error.config.url.match("/debug")) {
163+
window.ProcessMaker.apiClient.post("/debug", {
164+
name: "Javascript ProcessMaker.apiClient Error",
165+
message: JSON.stringify({
166+
message: error.message,
167+
code: error.code,
168+
config: error.config,
169+
}),
170+
});
171+
}
172+
return Promise.reject(error);
173+
}
174+
});
175+
176+
// Display any uncaught promise rejections from axios in the Process Maker alert box
177+
window.addEventListener("unhandledrejection", (event) => {
178+
const error = event.reason;
179+
if (error.config && error.config._defaultErrorShown) {
180+
// Already handeled
181+
event.preventDefault(); // stops the unhandled rejection error
182+
} else if (error.response && error.response.data && error.response.data.message) {
183+
if (!(error.code && error.code === "ECONNABORTED")) {
184+
window.ProcessMaker.alert(error.response.data.message, "danger");
185+
}
186+
} else if (error.message) {
187+
if (!(error.code && error.code === "ECONNABORTED")) {
188+
window.ProcessMaker.alert(error.message, "danger");
189+
}
190+
}
191+
});
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
<!DOCTYPE html>
2+
<html lang="{{ app()->getLocale() }}">
3+
<head>
4+
<meta charset="utf-8">
5+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
6+
<meta http-equiv="Content-Security-Policy"
7+
content="script-src * 'unsafe-inline' 'unsafe-eval';
8+
object-src 'self';
9+
worker-src 'self' blob:;">
10+
<meta name="viewport" content="width=device-width, initial-scale=1">
11+
<meta name="csrf-token" content="{{ csrf_token() }}">
12+
<meta name="is-prod" content="{{ config('app.env') == 'production' ? 'true' : 'false' }}">
13+
<meta name="app-url" content="{{ config('app.url') }}">
14+
<meta name="open-ai-nlq-to-pmql" content="{{ config('app.open_ai_nlq_to_pmql') }}">
15+
<meta name="i18n-mdate" content='{!! json_encode(ProcessMaker\i18nHelper::mdates()) !!}'>
16+
<meta name="screen-cache-enabled" content="{{ config('app.screen.cache_enabled') ? 'true' : 'false' }}">
17+
<meta name="screen-cache-timeout" content="{{ config('app.screen.cache_timeout') }}">
18+
@if(Auth::user())
19+
<meta name="user-id" content="{{ Auth::user()->id }}">
20+
<meta name="user-full-name" content="{{ Auth::user()->fullname }}">
21+
<meta name="user-avatar" content="{{ Auth::user()->avatar }}">
22+
<meta name="datetime-format" content="{{ Auth::user()->datetime_format ?: config('app.dateformat') }}">
23+
<meta name="timezone" content="{{ Auth::user()->timezone ?: config('app.timezone') }}">
24+
@yield('meta')
25+
@endif
26+
<meta name="timeout-worker" content="{{ mix('js/timeout.js') }}">
27+
<meta name="timeout-length" content="{{ Session::has('rememberme') && Session::get('rememberme') ? "Number.MAX_SAFE_INTEGER" : config('session.lifetime') }}">
28+
<meta name="timeout-warn-seconds" content="{{ config('session.expire_warning') }}">
29+
@if(Session::has('_alert'))
30+
<meta name="alert" content="show">
31+
@php
32+
list($type,$message) = json_decode(Session::get('_alert'));
33+
Session::forget('_alert');
34+
@endphp
35+
<meta name="alertVariant" content="{{$type}}">
36+
<meta name="alertMessage" content="{{$message}}">
37+
@endif
38+
<title>@yield('title',__('Welcome')) - {{ __('ProcessMaker') }}</title>
39+
<link rel="icon" type="image/png" sizes="16x16" href="{{ \ProcessMaker\Models\Setting::getFavicon() }}">
40+
<link href="{{ mix('css/app.css') }}" rel="stylesheet">
41+
<link href="/css/bpmn-symbols/css/bpmn.css" rel="stylesheet">
42+
@yield('css')
43+
<script type="text/javascript">
44+
@if(Auth::user())
45+
window.Processmaker = {
46+
csrfToken: "{{csrf_token()}}",
47+
userId: "{{\Auth::user()->id}}",
48+
messages: [],
49+
apiTimeout: {{config('app.api_timeout')}}
50+
};
51+
@if(config('broadcasting.default') == 'redis')
52+
window.Processmaker.broadcasting = {
53+
broadcaster: "socket.io",
54+
host: "{{config('broadcasting.connections.redis.host')}}",
55+
key: "{{config('broadcasting.connections.redis.key')}}"
56+
};
57+
@endif
58+
@if(config('broadcasting.default') == 'pusher')
59+
window.Processmaker.broadcasting = {
60+
broadcaster: "pusher",
61+
key: "{{config('broadcasting.connections.pusher.key')}}",
62+
cluster: "{{config('broadcasting.connections.pusher.options.cluster')}}",
63+
forceTLS: {{config('broadcasting.connections.pusher.options.use_tls') ? 'true' : 'false'}},
64+
debug: {{config('broadcasting.connections.pusher.options.debug') ? 'true' : 'false'}},
65+
enabledTransports: ['ws', 'wss'],
66+
disableStats: true,
67+
};
68+
@if(config('broadcasting.connections.pusher.options.host'))
69+
window.Processmaker.broadcasting.wsHost = "{{config('broadcasting.connections.pusher.options.host')}}";
70+
window.Processmaker.broadcasting.wsPort = "{{config('broadcasting.connections.pusher.options.port')}}";
71+
window.Processmaker.broadcasting.wssPort = "{{config('broadcasting.connections.pusher.options.port')}}";
72+
@endif
73+
@endif
74+
@endif
75+
</script>
76+
@isset($addons)
77+
<script>
78+
var addons = [];
79+
</script>
80+
@foreach ($addons as $addon)
81+
@if (!empty($addon['script']))
82+
{!! $addon['script'] !!}
83+
@endif
84+
@endforeach
85+
@endisset
86+
@if (config('global_header'))
87+
<!-- Start Global Header -->
88+
{!! config('global_header') !!}
89+
<!-- End Global Header -->
90+
@endif
91+
</head>
92+
<body>
93+
<a class="skip-navigation alert alert-info" role="link" href="#main" tabindex="1">{{ __('Skip to Content') }}</a>
94+
<div class="d-flex w-100 mw-100 h-100 mh-100" id="app-container">
95+
<div class="d-flex flex-grow-1 flex-column overflow-hidden">
96+
<div class="flex-grow-1 d-flex flex-column overflow-hidden h-100" id="mainbody">
97+
<div
98+
id="main"
99+
class="main flex-grow-1 h-100
100+
{{$content_margin ?? 'overflow-auto'}}
101+
{{$content_margin ?? 'py-3'}}">
102+
@yield('content')
103+
</div>
104+
</div>
105+
</div>
106+
</div>
107+
<div id="navbar" style="display: none;"></div>
108+
<div id="api-error" class="error-content">
109+
<div>
110+
<h1>{{__('Sorry! API failed to load')}}</h1>
111+
<p>{{__('Something went wrong. Try refreshing the application')}}</p>
112+
</div>
113+
</div>
114+
<!-- Scripts -->
115+
@if(config('broadcasting.default') == 'redis')
116+
<script src="{{config('broadcasting.connections.redis.host')}}/socket.io/socket.io.js"></script>
117+
@endif
118+
<script src="{{ mix('js/manifest.js') }}"></script>
119+
<script src="{{ mix('js/vendor.js') }}"></script>
120+
<script src="{{ mix('js/app.js') }}"></script>
121+
<script>
122+
window.ProcessMaker.packages = @json(\App::make(ProcessMaker\Managers\PackageManager::class)->listPackages());
123+
</script>
124+
<script src="{{ mix('js/print-layout.js') }}"></script>
125+
@include('shared.monaco')
126+
@foreach(GlobalScripts::getScripts() as $script)
127+
<script src="{{$script}}"></script>
128+
@endforeach
129+
@isset($addons)
130+
@foreach ($addons as $addon)
131+
@if (!empty($addon['script_mix']))
132+
<script type="text/javascript" src="{{ mix($addon['script_mix'][0], $addon['script_mix'][1]) }}"></script>
133+
@endif
134+
@if (!empty($addon['script_mix_module']))
135+
<script type="module" src="{{ mix($addon['script_mix_module'][0], $addon['script_mix_module'][1]) }}"></script>
136+
@endif
137+
@endforeach
138+
@endisset
139+
<!--javascript!-->
140+
@yield('js')
141+
</body>
142+
</html>

webpack.mix.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ mix
7272
.copy("node_modules/bpmn-font/dist", "public/css/bpmn-symbols");
7373

7474
mix
75+
.js("resources/js/print-layout.js", "public/js")
7576
.js("resources/js/app-layout.js", "public/js")
7677
.js("resources/js/process-map-layout.js", "public/js")
7778
.js("resources/js/processes/modeler/index.js", "public/js/processes/modeler")

0 commit comments

Comments
 (0)