diff --git a/index.php b/index.php
index 1795b07..9f3392d 100644
--- a/index.php
+++ b/index.php
@@ -1208,6 +1208,10 @@ document.addEventListener('DOMContentLoaded', function () {
const formData = new FormData();
formData.append('person_id', personId);
formData.append('process_id', processId);
+ if (instanceModalElement) {
+ instanceModalElement.dataset.lastPersonId = personId;
+ instanceModalElement.dataset.lastProcessId = processId;
+ }
fetch('_init_single_instance.php', {
method: 'POST',
@@ -1225,7 +1229,7 @@ document.addEventListener('DOMContentLoaded', function () {
modalBody.innerHTML = html;
});
} else {
- alert('Błąd: ' + (data.error || 'Nieznany błąd'));
+ alert('Błąd: ' + (data.error?.message || data.error || 'Nieznany błąd'));
btn.disabled = false;
btn.innerHTML = originalText;
}
@@ -1238,6 +1242,156 @@ document.addEventListener('DOMContentLoaded', function () {
});
});
}
+ // --- Actions inside Instance Modal ---
+ if (instanceModalElement) {
+ instanceModalElement.addEventListener('click', function(event) {
+ // Apply Transition Button
+ if (event.target.classList.contains('apply-transition-btn')) {
+ event.preventDefault();
+ const btn = event.target;
+ const instanceId = btn.dataset.instanceId;
+ const transitionId = btn.dataset.transitionId;
+
+ // Get form data if transition form exists
+ const form = instanceModalElement.querySelector('#transition-form');
+ const formData = new FormData();
+ formData.append('instanceId', instanceId);
+ formData.append('transitionId', transitionId);
+
+ if (form) {
+ const formElements = new FormData(form);
+ for (let [key, value] of formElements.entries()) {
+ formData.append('payload[' + key + ']', value);
+ }
+ }
+
+ const originalText = btn.innerHTML;
+ btn.disabled = true;
+ btn.innerHTML = '...';
+
+ fetch('_apply_transition.php', {
+ method: 'POST',
+ body: formData
+ })
+ .then(r => r.json())
+ .then(data => {
+ if (data.success || !data.error) {
+ // Reload modal content
+ const personId = instanceModalElement.dataset.lastPersonId;
+ const processId = instanceModalElement.dataset.lastProcessId;
+
+ fetch(`_get_instance_details.php?person_id=${personId}&process_id=${processId}`)
+ .then(r => r.text())
+ .then(html => {
+ instanceModalElement.querySelector('.modal-body').innerHTML = html;
+ });
+ } else {
+ alert('Błąd: ' + (data.error?.message || 'Nieznany błąd'));
+ btn.disabled = false;
+ btn.innerHTML = originalText;
+ }
+ })
+ .catch(err => {
+ console.error(err);
+ alert('Błąd sieci');
+ btn.disabled = false;
+ btn.innerHTML = originalText;
+ });
+ }
+
+ // Add Note Button
+ if (event.target.id === 'addNoteBtn') {
+ event.preventDefault();
+ const btn = event.target;
+ const instanceId = btn.dataset.instanceId;
+ const noteMessage = instanceModalElement.querySelector('#noteMessage').value.trim();
+
+ if (!noteMessage) {
+ alert('Treść notatki nie może być pusta.');
+ return;
+ }
+
+ const formData = new FormData();
+ formData.append('instanceId', instanceId);
+ formData.append('transitionId', 'note');
+ formData.append('payload[message]', noteMessage);
+
+ const originalText = btn.innerHTML;
+ btn.disabled = true;
+ btn.innerHTML = '...';
+
+ fetch('_apply_transition.php', {
+ method: 'POST',
+ body: formData
+ })
+ .then(r => r.json())
+ .then(data => {
+ if (data.success || !data.error) {
+ const personId = instanceModalElement.dataset.lastPersonId;
+ const processId = instanceModalElement.dataset.lastProcessId;
+
+ fetch(`_get_instance_details.php?person_id=${personId}&process_id=${processId}`)
+ .then(r => r.text())
+ .then(html => {
+ instanceModalElement.querySelector('.modal-body').innerHTML = html;
+ });
+ } else {
+ alert('Błąd: ' + (data.error?.message || 'Nieznany błąd'));
+ btn.disabled = false;
+ btn.innerHTML = originalText;
+ }
+ })
+ .catch(err => {
+ console.error(err);
+ alert('Błąd sieci');
+ btn.disabled = false;
+ btn.innerHTML = originalText;
+ });
+ }
+ });
+
+ instanceModalElement.addEventListener('change', function(event) {
+ // Task Checkbox
+ if (event.target.classList.contains('task-checkbox-modal')) {
+ const checkbox = event.target;
+ const container = checkbox.closest('.checklist-modal-container');
+ const instanceId = container.dataset.instanceId;
+ const taskCode = checkbox.dataset.taskCode;
+ const isChecked = checkbox.checked;
+
+ fetch('_update_training_checklist_status.php', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({
+ instance_id: instanceId,
+ task_code: taskCode,
+ is_checked: isChecked
+ })
+ })
+ .then(r => r.json())
+ .then(data => {
+ if (data.error) {
+ alert('Błąd: ' + (data.error?.message || 'Nieznany błąd'));
+ checkbox.checked = !isChecked; // revert
+ }
+ })
+ .catch(err => {
+ console.error(err);
+ alert('Błąd sieci');
+ checkbox.checked = !isChecked; // revert
+ });
+ }
+ });
+
+ // Save personId and processId on modal show so we can use it to reload later
+ instanceModalElement.addEventListener('show.bs.modal', function (event) {
+ var button = event.relatedTarget;
+ if(button && button.dataset) {
+ if (button.dataset.personId) instanceModalElement.dataset.lastPersonId = button.dataset.personId;
+ if (button.dataset.processId) instanceModalElement.dataset.lastProcessId = button.dataset.processId;
+ }
+ });
+ }
});
diff --git a/lib/WorkflowExceptions.php b/lib/WorkflowExceptions.php
index dbcac1d..d6fdc54 100644
--- a/lib/WorkflowExceptions.php
+++ b/lib/WorkflowExceptions.php
@@ -5,7 +5,7 @@ class WorkflowException extends Exception {
protected $details;
public function __construct($message = "", $httpCode = 500, $details = [], Throwable $previous = null) {
- parent::__construct($message, 0, $previous);
+ parent::__construct($message, $httpCode, $previous);
$this->httpCode = $httpCode;
$this->details = $details;
}
@@ -19,19 +19,33 @@ class WorkflowException extends Exception {
}
}
-class WorkflowNotFoundException extends Exception {}
-class WorkflowNotAllowedException extends Exception {}
-class WorkflowRuleFailedException extends Exception {}
+class WorkflowNotFoundException extends WorkflowException {
+ public function __construct($message = "") {
+ parent::__construct($message, 404);
+ }
+}
-class WorkflowEligibilityException extends Exception {
+class WorkflowNotAllowedException extends WorkflowException {
+ public function __construct($message = "") {
+ parent::__construct($message, 403);
+ }
+}
+
+class WorkflowRuleFailedException extends WorkflowException {
+ public function __construct($message = "") {
+ parent::__construct($message, 400);
+ }
+}
+
+class WorkflowEligibilityException extends WorkflowException {
private $reasons;
- public function __construct($message = "", $reasons = [], $code = 0, Throwable $previous = null) {
- parent::__construct($message, $code, $previous);
+ public function __construct($message = "", $reasons = []) {
+ parent::__construct($message, 422, ['reasons' => $reasons]);
$this->reasons = $reasons;
}
public function getReasons() {
return $this->reasons;
}
-}
+}
\ No newline at end of file