Rapport-Laravel/resources/views/form/workflow-approval.blade.php

302 lines
12 KiB
PHP

<!DOCTYPE html>
<html lang="en">
<head>
<meta name="csrf-token" content="{{ csrf_token() }}">
@include('layouts.shared/title-meta', ['title' => $form_name ?: 'Workflow Approval'])
@include('layouts.shared/head-css', ["mode" => $mode ?? '', "demo" => $demo ?? ''])
<link href="{{asset('assets/libs/sweetalert2/sweetalert2.min.css')}}" rel="stylesheet" type="text/css" />
<style>
html, body.workflow-approval-body {
height: 100%;
margin: 0;
overflow: hidden;
}
body.workflow-approval-body .account-pages {
min-height: 0;
height: 100%;
padding: 0;
}
body.workflow-approval-body .account-pages > .container,
body.workflow-approval-body .account-pages > .container > .row,
body.workflow-approval-body .account-pages .col-lg-10 {
height: 100%;
min-height: 0;
margin: 0;
padding: 0;
max-width: 100%;
}
.workflow-approval-shell {
box-sizing: border-box;
display: flex;
flex-direction: column;
height: 100vh;
height: 100dvh;
max-width: 1200px;
margin: 0 auto;
padding: 0.5rem 0.75rem 0.75rem;
}
.workflow-approval-shell .card {
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
margin: 0;
border: none;
box-shadow: none;
}
.workflow-approval-shell .card-body {
display: flex;
flex-direction: column;
flex: 1;
min-height: 0;
padding: 0.5rem 0.75rem !important;
}
.workflow-approval-header {
flex: 0 0 auto;
}
.workflow-approval-header .page-title {
font-size: 1.1rem;
margin-bottom: 0.15rem !important;
}
.workflow-approval-header .submitted-by {
font-size: 0.85rem;
margin-bottom: 0.25rem !important;
}
.workflow-approval-header .status-row {
margin-bottom: 0.35rem !important;
}
.workflow-preview-wrap {
flex: 1 1 auto;
min-height: 0;
overflow: hidden;
}
.workflow-preview-frame {
width: 100%;
height: 100%;
min-height: 0;
border: 1px solid #dee2e6;
border-radius: 4px;
display: block;
}
.workflow-actions {
flex: 0 0 auto;
margin-top: 0.5rem;
padding: 0.35rem 0 0;
}
#pageloader {
background: rgba(255, 255, 255, 0.8);
display: none;
height: 100%;
position: fixed;
width: 100%;
z-index: 9999;
}
#pageloader img {
left: 50%;
margin-left: -32px;
margin-top: -32px;
position: absolute;
top: 50%;
}
</style>
</head>
<div id="pageloader">
<img src="http://cdnjs.cloudflare.com/ajax/libs/semantic-ui/0.16.1/images/loader-large.gif" alt="processing..." />
</div>
<body class="loading workflow-approval-body">
<div class="account-pages">
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-10 col-xl-9 p-0">
<div class="workflow-approval-shell">
<div class="card bg-pattern">
<div class="card-body">
<div class="workflow-approval-header">
<h4 class="page-title mb-1">{{ $form_name }}</h4>
@if(!empty($submitted_by))
<p class="text-muted submitted-by mb-1">Submitted by: {{ $submitted_by }}</p>
@endif
<p class="status-row mb-0">
<span id="workflow-status-badge" class="badge bg-secondary text-uppercase">{{ $workflow_status }}</span>
</p>
</div>
<div class="workflow-preview-wrap">
<iframe
class="workflow-preview-frame"
src="{{ $preview_url }}"
title="Form preview"
frameborder="0"
></iframe>
</div>
<div class="workflow-actions text-center" id="workflow-actions">
@if($actions_disabled)
<p class="text-muted mb-0 small">{{ $status_message ?? 'This submission has already been ' . $workflow_status . '.' }}</p>
@else
<button type="button" class="btn btn-success me-2" id="btn-approve">Approve</button>
<button type="button" class="btn btn-danger" id="btn-reject">Reject</button>
@endif
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@include('layouts.shared/footer-script')
<script src="{{asset('assets/libs/sweetalert2/sweetalert2.min.js')}}"></script>
<script>
const approvalParams = {
submission_id: @json($submission_id),
user_id: @json($user_id),
form_id: @json($form_id),
partition: @json($partition),
entity_id: @json($entity_id),
form_name: @json($form_name),
};
function hidePageLoader() {
$("#pageloader").fadeOut();
$("body").removeClass("loading");
}
function resizeWorkflowPreview() {
var $shell = $('.workflow-approval-shell');
var $header = $('.workflow-approval-header');
var $actions = $('.workflow-actions');
var $wrap = $('.workflow-preview-wrap');
var $frame = $('.workflow-preview-frame');
if (!$shell.length || !$wrap.length) {
return;
}
var shellTop = $shell[0].getBoundingClientRect().top;
var actionsH = $actions.outerHeight(true) || 0;
var headerH = $header.outerHeight(true) || 0;
var pad = 12;
var available = window.innerHeight - shellTop - headerH - actionsH - pad;
if (available < 120) {
available = 120;
}
$wrap.height(available);
$frame.height(available);
}
function postApprovalAction(action, reason) {
$("#pageloader").fadeIn();
const payload = Object.assign({}, approvalParams, {
action: action,
_token: $('meta[name="csrf-token"]').attr('content'),
});
if (reason) {
payload.reason = reason;
}
return $.ajax({
url: '/form/workflow-approval/action',
type: 'POST',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content'),
},
data: payload,
}).always(function() {
hidePageLoader();
});
}
function showActionCompletedUI(res, action) {
var label = (res && res.status_label) ? res.status_label : (action === 'approve' ? 'approved' : 'rejected');
var message = (res && res.status_message) ? res.status_message : (res && res.message ? res.message : 'Action completed successfully.');
var $badge = $('#workflow-status-badge');
$badge.removeClass('bg-secondary bg-success bg-danger');
if (label === 'approved') {
$badge.addClass('bg-success');
} else if (label === 'rejected') {
$badge.addClass('bg-danger');
} else {
$badge.addClass('bg-secondary');
}
$badge.text(label);
$('#workflow-actions').empty().append(
$('<p class="text-muted mb-0 small"></p>').text(message)
);
resizeWorkflowPreview();
}
jQuery(document).ready(function($) {
hidePageLoader();
resizeWorkflowPreview();
$(window).on('resize orientationchange', resizeWorkflowPreview);
var $previewFrame = $('.workflow-preview-frame');
$previewFrame.on('load', function() {
hidePageLoader();
resizeWorkflowPreview();
});
if ($previewFrame[0] && $previewFrame[0].complete) {
hidePageLoader();
}
$('#btn-approve').on('click', function() {
Swal.fire({
title: 'Approve submission?',
text: 'Are you sure you want to approve this submission?',
icon: 'question',
showCancelButton: true,
confirmButtonColor: '#28a745',
cancelButtonColor: '#6c757d',
confirmButtonText: 'Yes, approve'
}).then(function(result) {
if (!result.isConfirmed) {
return;
}
postApprovalAction('approve').done(function(res) {
if (res.status === 'success') {
showActionCompletedUI(res, 'approve');
Swal.fire('Approved', res.message, 'success');
} else {
Swal.fire('Error', res.message || 'Could not approve submission.', 'error');
}
}).fail(function(xhr) {
Swal.fire('Error', xhr.responseJSON?.message || 'Could not approve submission.', 'error');
});
});
});
$('#btn-reject').on('click', function() {
Swal.fire({
title: 'Reject submission',
input: 'textarea',
inputLabel: 'Reason for rejection',
inputPlaceholder: 'Enter reason...',
inputAttributes: { 'aria-label': 'Reason for rejection' },
showCancelButton: true,
confirmButtonColor: '#dc3545',
cancelButtonColor: '#6c757d',
confirmButtonText: 'Reject',
inputValidator: function(value) {
if (!value || !value.trim()) {
return 'Reject reason is required';
}
}
}).then(function(result) {
if (!result.isConfirmed) {
return;
}
postApprovalAction('reject', result.value.trim()).done(function(res) {
if (res.status === 'success') {
showActionCompletedUI(res, 'reject');
Swal.fire('Rejected', res.message, 'success');
} else {
Swal.fire('Error', res.message || 'Could not reject submission.', 'error');
}
}).fail(function(xhr) {
Swal.fire('Error', xhr.responseJSON?.message || 'Could not reject submission.', 'error');
});
});
});
});
</script>
</body>
</html>