From 2e85c011150441c7055af19a9dfc02274c738dd3 Mon Sep 17 00:00:00 2001 From: Flatlogic Bot Date: Mon, 2 Mar 2026 17:03:42 +0000 Subject: [PATCH] Poprawki po aktualizacji --- WorkflowEngine.php | 4 +- _get_instance_details.php | 7 +- _init_single_instance.php | 4 +- index.php | 177 +++++++++++++++++++++++++++++--------- patch2.py | 17 ---- patch_index3.py | 38 ++++++++ patch_index4.py | 168 ++++++++++++++++++++++++++++++++++++ 7 files changed, 350 insertions(+), 65 deletions(-) delete mode 100644 patch2.py create mode 100644 patch_index3.py create mode 100644 patch_index4.py diff --git a/WorkflowEngine.php b/WorkflowEngine.php index 712b0c2..9fd2c8f 100644 --- a/WorkflowEngine.php +++ b/WorkflowEngine.php @@ -183,7 +183,8 @@ $spotkania_cols = []; $spotkania_cols[$meeting['group_id']]['group_name'] = $meeting['group_name']; $spotkania_cols[$meeting['group_id']]['meetings'][] = [ 'datetime' => $meeting['start_datetime'], - 'meeting_id' => $meetingId + 'meeting_id' => $meetingId, + 'cycle_key' => $meeting['group_id'] . '_' . $meeting['start_datetime'] ]; } @@ -1005,6 +1006,7 @@ $spotkania_cols = []; $isMember = $this->isMemberOfGroup($personId, $bniGroupId); return [ 'meeting_id' => $meetingId, + 'cycle_key' => $meeting['group_id'] . '_' . $meeting['start_datetime'], 'person_id' => $personId, 'attendance_status' => $isMember ? 'present' : 'none', 'guest_survey' => null, diff --git a/_get_instance_details.php b/_get_instance_details.php index 38c3305..9068977 100644 --- a/_get_instance_details.php +++ b/_get_instance_details.php @@ -14,6 +14,9 @@ if (!isset($_SESSION['user_id'])) { } $person_id = $_GET['person_id'] ?? null; +$subject_id = $_GET['subject_id'] ?? $person_id; +$subject_type = $_GET['subject_type'] ?? 'person'; +$cycle_key = $_GET['cycle_key'] ?? null; $process_definition_id = $_GET['process_id'] ?? null; $process_code = $_GET['process_code'] ?? null; @@ -63,7 +66,7 @@ if (!$process) { } // Try to find an existing instance -$instance = $engine->getActiveInstanceForSubject($process['code'], $subject_type, $subject_id); +$instance = $engine->getActiveInstanceForSubject($process['code'], $subject_type, $subject_id, $cycle_key); ?> @@ -289,7 +292,7 @@ $instance = $engine->getActiveInstanceForSubject($process['code'], $subject_type

This process has not been started for this person.

- diff --git a/_init_single_instance.php b/_init_single_instance.php index 09083dc..a11ea10 100644 --- a/_init_single_instance.php +++ b/_init_single_instance.php @@ -46,7 +46,7 @@ $engine = new WorkflowEngine(); $code = $stmt_def->fetchColumn() ?: $processCode; if($deleteExisting === '1') { - $instance = $engine->getActiveInstanceForSubject($code, $subjectType, $subjectId); + $instance = $engine->getActiveInstanceForSubject($code, $subjectType, $subjectId, $cycleKey); if ($instance) { $engine->deleteInstance($instance['id']); } @@ -54,7 +54,7 @@ if($deleteExisting === '1') { if ($mode === 'create_new_run' || filter_input(INPUT_POST, 'force', FILTER_VALIDATE_INT) === 1) { // start new process - $instanceId = $engine->startProcessForSubject($code, $subjectType, $subjectId, $userId, 'create_new_run'); + $instanceId = $engine->startProcessForSubject($code, $subjectType, $subjectId, $userId, 'create_new_run', $cycleKey); $stmt = $pdo->prepare("SELECT * FROM process_instances WHERE id = ?"); $stmt->execute([$instanceId]); $instance = $stmt->fetch(PDO::FETCH_ASSOC); diff --git a/index.php b/index.php index a279a9e..b6cea23 100644 --- a/index.php +++ b/index.php @@ -266,7 +266,7 @@ foreach ($definitions as $def) { $color = $status_colors[$status] ?? 'secondary'; $lastActivity = $instance && $instance['last_activity_at'] ? date('d/m/y', strtotime($instance['last_activity_at'])) : ''; ?> - +   @@ -717,7 +717,7 @@ foreach ($definitions as $def) { document.addEventListener('DOMContentLoaded', function () { const meetingProcesses = ; - const statusColors = ; + if (!window.STATUS_COLORS) { window.STATUS_COLORS = ; } const meetingModal = new bootstrap.Modal(document.getElementById('meetingAttendanceModal')); @@ -728,15 +728,16 @@ document.addEventListener('DOMContentLoaded', function () { const meetingDateInput = document.getElementById('meetingDate'); const attendanceStatus = document.getElementById('attendanceStatus'); const guestSurveySection = document.getElementById('guestSurveySection'); - const statusColors = { + if (!window.STATUS_COLORS) window.STATUS_COLORS = {}; + Object.assign(window.STATUS_COLORS, { 'none': 'secondary', 'absent': 'danger', 'substitute': 'warning', 'present': 'success', - }; + }); function updateDot(dot, status) { - const color = statusColors[status] || 'secondary'; + const color = window.STATUS_COLORS[status] || 'secondary'; dot.className = `badge rounded-circle bg-${color} meeting-dot`; dot.dataset.currentStatus = status; dot.title = `Status: ${status.charAt(0).toUpperCase() + status.slice(1)}`; @@ -886,6 +887,7 @@ document.addEventListener('DOMContentLoaded', function () { const currentMeetingObj = meetings[currentIndex]; const currentMeetingDate = typeof currentMeetingObj === 'object' ? currentMeetingObj.datetime : currentMeetingObj; const currentMeetingId = typeof currentMeetingObj === 'object' ? currentMeetingObj.meeting_id : null; + const currentCycleKey = typeof currentMeetingObj === 'object' ? currentMeetingObj.cycle_key : null; headerCell.querySelector('.meeting-date').textContent = new Date(currentMeetingDate).toLocaleDateString('pl-PL', { day: '2-digit', month: '2-digit', year: 'numeric' }); const processContainer = headerCell.querySelector('.meeting-process-container'); @@ -894,9 +896,12 @@ document.addEventListener('DOMContentLoaded', function () { const dot = processContainer.querySelector('.meeting-process-dot'); if (dot) { dot.dataset.subjectId = currentMeetingId; + dot.dataset.cycleKey = currentCycleKey; + dot.dataset.processCode = 'meeting_preparation'; + dot.dataset.subjectType = 'meeting'; const instance = meetingProcesses[currentMeetingId] && meetingProcesses[currentMeetingId]['meeting_preparation']; const status = instance ? instance.computed_status : 'none'; - const color = statusColors[status] || 'secondary'; + const color = window.STATUS_COLORS[status] || 'secondary'; dot.className = `badge rounded-circle bg-${color} process-dot meeting-process-dot`; dot.dataset.processId = instance ? instance.id : ''; } @@ -967,17 +972,78 @@ document.addEventListener('DOMContentLoaded', function () { var instanceModal = document.getElementById('instanceModal'); instanceModal.addEventListener('show.bs.modal', function (event) { var button = event.relatedTarget; - var personId = button.dataset.personId || ''; - var processId = button.dataset.processId; + if (!button) return; + var subjectType = button.dataset.subjectType || 'person'; - var subjectId = button.dataset.subjectId || personId; + var subjectId = button.dataset.subjectId || button.dataset.personId || ''; + var personId = button.dataset.personId || ''; + var processId = button.dataset.processId || ''; + var processCode = button.dataset.processCode || ''; + var cycleKey = button.dataset.cycleKey || ''; + + instanceModal.dataset.lastSubjectType = subjectType; + instanceModal.dataset.lastSubjectId = subjectId; + instanceModal.dataset.lastPersonId = personId; + instanceModal.dataset.lastProcessId = processId; + instanceModal.dataset.lastProcessCode = processCode; + instanceModal.dataset.lastCycleKey = cycleKey; + + var modalTitle = instanceModal.querySelector('.modal-title'); var modalBody = instanceModal.querySelector('.modal-body'); - // Load content via AJAX - fetch(`_get_instance_details.php?person_id=${personId}&subject_type=${subjectType}&subject_id=${subjectId}&process_id=${processId}`) - .then(response => response.text()) - .then(html => { + modalTitle.textContent = 'Ładowanie...'; + modalBody.innerHTML = '

Ladowanie...

'; + + if (!subjectId) { + modalTitle.textContent = 'Błąd parametru'; + modalBody.innerHTML = '
Brak wymaganego identyfikatora (subject_id). Nie można załadować procesu.
'; + return; + } + + if (!processId && !processCode) { + modalTitle.textContent = 'Błąd parametru'; + modalBody.innerHTML = '
Brak identyfikatora procesu (process_id lub process_code). Nie można załadować procesu.
'; + return; + } + + var url = '_get_instance_details.php?subject_type=' + encodeURIComponent(subjectType) + '&subject_id=' + encodeURIComponent(subjectId); + if (personId) url += '&person_id=' + encodeURIComponent(personId); + if (processId) url += '&process_id=' + encodeURIComponent(processId); + if (processCode) url += '&process_code=' + encodeURIComponent(processCode); + if (cycleKey) url += '&cycle_key=' + encodeURIComponent(cycleKey); + + fetch(url) + .then(function(response) { + if (!response.ok) { + return response.text().then(function(text) { + var errStr = 'HTTP ' + response.status + ': '; + var corrId = ''; + try { + var data = JSON.parse(text); + errStr += (data.error && data.error.message) ? data.error.message : (data.error || text); + if (data.correlation_id) corrId = data.correlation_id; + } catch (e) { + errStr += text.substring(0, 100); + } + throw new Error(errStr + (corrId ? ' (ID: ' + corrId + ')' : '')); + }); + } + return response.text(); + }) + .then(function(html) { modalBody.innerHTML = html; + var returnedTitle = modalBody.querySelector('#instance-modal-title'); + if (returnedTitle) { + modalTitle.innerHTML = returnedTitle.innerHTML; + returnedTitle.remove(); + } else { + modalTitle.textContent = 'Szczegóły Procesu'; + } + }) + .catch(function(err) { + console.error('Fetch error:', err); + modalTitle.textContent = 'Błąd'; + modalBody.innerHTML = '
Błąd ładowania:
' + err.message + '
'; }); }); @@ -1239,11 +1305,14 @@ document.addEventListener('DOMContentLoaded', function () { event.preventDefault(); event.stopPropagation(); - const personId = btn.dataset.personId; + const subjectType = btn.dataset.subjectType || 'person'; + const subjectId = btn.dataset.subjectId || btn.dataset.personId; const processId = btn.dataset.processId; + const processCode = btn.dataset.processCode; + const cycleKey = btn.dataset.cycleKey; - if (!personId || !processId) { - alert('Brak ID osoby lub procesu'); + if (!subjectId || (!processId && !processCode)) { + alert('Brak wymaganych parametrów do uruchomienia procesu.'); return; } @@ -1252,11 +1321,18 @@ document.addEventListener('DOMContentLoaded', function () { btn.innerHTML = ' Uruchamianie...'; const formData = new FormData(); - formData.append('person_id', personId); - formData.append('process_id', processId); + formData.append('subject_type', subjectType); + formData.append('subject_id', subjectId); + if (processId) formData.append('process_id', processId); + if (processCode) formData.append('process_code', processCode); + if (cycleKey) formData.append('cycle_key', cycleKey); + if (instanceModalElement) { - instanceModalElement.dataset.lastPersonId = personId; + instanceModalElement.dataset.lastSubjectType = subjectType; + instanceModalElement.dataset.lastSubjectId = subjectId; instanceModalElement.dataset.lastProcessId = processId; + instanceModalElement.dataset.lastProcessCode = processCode; + instanceModalElement.dataset.lastCycleKey = cycleKey; } fetch('_init_single_instance.php', { @@ -1269,7 +1345,12 @@ document.addEventListener('DOMContentLoaded', function () { const modalBody = instanceModalElement.querySelector('.modal-body'); modalBody.innerHTML = '

Ładowanie...

'; - fetch(`_get_instance_details.php?person_id=${personId}&process_id=${processId}`) + let url = `_get_instance_details.php?subject_type=${encodeURIComponent(subjectType)}&subject_id=${encodeURIComponent(subjectId)}`; + if (processId) url += `&process_id=${encodeURIComponent(processId)}`; + if (processCode) url += `&process_code=${encodeURIComponent(processCode)}`; + if (cycleKey) url += `&cycle_key=${encodeURIComponent(cycleKey)}`; + + fetch(url) .then(r => r.text()) .then(html => { modalBody.innerHTML = html; @@ -1296,12 +1377,15 @@ document.addEventListener('DOMContentLoaded', function () { event.preventDefault(); event.stopPropagation(); - const personId = restartBtn.dataset.personId; + const subjectType = restartBtn.dataset.subjectType || 'person'; + const subjectId = restartBtn.dataset.subjectId || restartBtn.dataset.personId; const processCode = restartBtn.dataset.processCode; + const processId = restartBtn.dataset.processId; + const cycleKey = restartBtn.dataset.cycleKey; const mode = restartBtn.dataset.mode; - if (!personId || !processCode) { - alert('Brak ID osoby lub kodu procesu'); + if (!subjectId || !processCode) { + alert('Brak wymaganych parametrów do zrestartowania procesu.'); return; } @@ -1310,8 +1394,11 @@ document.addEventListener('DOMContentLoaded', function () { restartBtn.innerHTML = '...'; const formData = new FormData(); - formData.append('person_id', personId); + formData.append('subject_type', subjectType); + formData.append('subject_id', subjectId); formData.append('process_code', processCode); + if (processId) formData.append('process_id', processId); + if (cycleKey) formData.append('cycle_key', cycleKey); formData.append('mode', mode || 'create_new_run'); fetch('_init_single_instance.php', { @@ -1332,10 +1419,8 @@ document.addEventListener('DOMContentLoaded', function () { const modalBody = instanceModalElement.querySelector('.modal-body'); modalBody.innerHTML = '

Ładowanie...

'; - // Use process_id if we have it from dataset, otherwise fetch using code. - // The original _get_instance_details endpoint seems to accept process_id or process_code? Let's check. - // Actually let's use the instanceModalElement.dataset.lastProcessId if it exists. - const fetchUrl = `_get_instance_details.php?person_id=${personId}&process_code=${processCode}`; + let fetchUrl = `_get_instance_details.php?subject_type=${encodeURIComponent(subjectType)}&subject_id=${encodeURIComponent(subjectId)}&process_code=${encodeURIComponent(processCode)}`; + if (cycleKey) fetchUrl += `&cycle_key=${encodeURIComponent(cycleKey)}`; fetch(fetchUrl) .then(r => r.text()) @@ -1393,10 +1478,18 @@ document.addEventListener('DOMContentLoaded', function () { .then(data => { if (data.success || !data.error) { // Reload modal content - const personId = instanceModalElement.dataset.lastPersonId; + const subjectType = instanceModalElement.dataset.lastSubjectType || 'person'; + const subjectId = instanceModalElement.dataset.lastSubjectId; const processId = instanceModalElement.dataset.lastProcessId; + const processCode = instanceModalElement.dataset.lastProcessCode; + const cycleKey = instanceModalElement.dataset.lastCycleKey; - fetch(`_get_instance_details.php?person_id=${personId}&process_id=${processId}`) + let url = `_get_instance_details.php?subject_type=${encodeURIComponent(subjectType)}&subject_id=${encodeURIComponent(subjectId)}`; + if (processId) url += `&process_id=${encodeURIComponent(processId)}`; + if (processCode) url += `&process_code=${encodeURIComponent(processCode)}`; + if (cycleKey) url += `&cycle_key=${encodeURIComponent(cycleKey)}`; + + fetch(url) .then(r => r.text()) .then(html => { instanceModalElement.querySelector('.modal-body').innerHTML = html; @@ -1443,10 +1536,18 @@ document.addEventListener('DOMContentLoaded', function () { .then(r => r.json()) .then(data => { if (data.success || !data.error) { - const personId = instanceModalElement.dataset.lastPersonId; + const subjectType = instanceModalElement.dataset.lastSubjectType || 'person'; + const subjectId = instanceModalElement.dataset.lastSubjectId; const processId = instanceModalElement.dataset.lastProcessId; + const processCode = instanceModalElement.dataset.lastProcessCode; + const cycleKey = instanceModalElement.dataset.lastCycleKey; - fetch(`_get_instance_details.php?person_id=${personId}&process_id=${processId}`) + let url = `_get_instance_details.php?subject_type=${encodeURIComponent(subjectType)}&subject_id=${encodeURIComponent(subjectId)}`; + if (processId) url += `&process_id=${encodeURIComponent(processId)}`; + if (processCode) url += `&process_code=${encodeURIComponent(processCode)}`; + if (cycleKey) url += `&cycle_key=${encodeURIComponent(cycleKey)}`; + + fetch(url) .then(r => r.text()) .then(html => { instanceModalElement.querySelector('.modal-body').innerHTML = html; @@ -1499,17 +1600,7 @@ document.addEventListener('DOMContentLoaded', function () { } }); - // 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; - if (button.dataset.subjectType) instanceModalElement.dataset.lastSubjectType = button.dataset.subjectType; - if (button.dataset.subjectId) instanceModalElement.dataset.lastSubjectId = button.dataset.subjectId; - } - }); - } + } instanceModalElement.addEventListener('hidden.bs.modal', function () { if (window.matrixNeedsRefresh) { diff --git a/patch2.py b/patch2.py deleted file mode 100644 index a329ee5..0000000 --- a/patch2.py +++ /dev/null @@ -1,17 +0,0 @@ -import re - -with open('WorkflowEngine.php', 'r') as f: - content = f.read() - -target = """ $stmt = $this->pdo->prepare("SELECT * FROM process_instances WHERE `person_id` = ? AND `process_definition_id` = ?"); - $stmt->execute([$personId, $processDefinitionId]); - $instance = $stmt->fetch(PDO::FETCH_ASSOC);""" - -replacement = """ $instance = $this->getInstanceByDefId($personId, $processDefinitionId);""" - -content = content.replace(target, replacement) - -with open('WorkflowEngine.php', 'w') as f: - f.write(content) - -print("Patched.") diff --git a/patch_index3.py b/patch_index3.py new file mode 100644 index 0000000..bf4b41a --- /dev/null +++ b/patch_index3.py @@ -0,0 +1,38 @@ +import re + +with open('index.php', 'r', encoding='utf-8') as f: + content = f.read() + +# 1. Update Inne Procesy dots +content = re.sub( + r'', + r' ', + content, + flags=re.DOTALL +) + +# 2. Update meeting dots initial HTML +content = re.sub( + r'data-process-id="<\?= \$mp_def[\'id\'] \?>"\s*data-subject-type="meeting"\s*data-subject-id=""', + r'data-process-id="" data-process-code="meeting_preparation" data-subject-type="meeting" data-subject-id="" data-cycle-key=""', + content +) + +# 3. Update updateMeetingView JS function +# Find currentMeetingId assignment +content = re.sub( + r"const currentMeetingId = typeof currentMeetingObj === 'object' \? currentMeetingObj.meeting_id : null;", + r"const currentMeetingId = typeof currentMeetingObj === 'object' ? currentMeetingObj.meeting_id : null;\n const currentCycleKey = typeof currentMeetingObj === 'object' ? currentMeetingObj.cycle_key : null;", + content +) + +# Find dot.dataset.subjectId = currentMeetingId; +content = re.sub( + r'dot.dataset.subjectId = currentMeetingId;', + r"dot.dataset.subjectId = currentMeetingId;\n dot.dataset.cycleKey = currentCycleKey;\n dot.dataset.processCode = 'meeting_preparation';\n dot.dataset.subjectType = 'meeting';", + content +) + +with open('index.php', 'w', encoding='utf-8') as f: + f.write(content) +print("index.php patched (step 1-3)") diff --git a/patch_index4.py b/patch_index4.py new file mode 100644 index 0000000..31b5d1a --- /dev/null +++ b/patch_index4.py @@ -0,0 +1,168 @@ +import re + +with open('index.php', 'r', encoding='utf-8') as f: + content = f.read() + +# Replace the handler +old_handler = """ var instanceModal = document.getElementById('instanceModal'); + instanceModal.addEventListener('show.bs.modal', function (event) { + var button = event.relatedTarget; + if (!button) return; + + var personId = button.dataset.personId || ''; + var processId = button.dataset.processId || ''; + var processCode = button.dataset.processCode || ''; + var subjectType = button.dataset.subjectType || 'person'; + var subjectId = button.dataset.subjectId || personId; + var cycleKey = button.dataset.cycleKey || ''; + + instanceModal.dataset.lastPersonId = personId; + instanceModal.dataset.lastProcessId = processId; + instanceModal.dataset.lastProcessCode = processCode; + instanceModal.dataset.lastSubjectType = subjectType; + instanceModal.dataset.lastSubjectId = subjectId; + instanceModal.dataset.lastCycleKey = cycleKey; + + var modalBody = instanceModal.querySelector('.modal-body'); + modalBody.innerHTML = '

Ladowanie...

'; + + var url = '_get_instance_details.php?subject_type=' + encodeURIComponent(subjectType) + '&subject_id=' + encodeURIComponent(subjectId); + if (personId) url += '&person_id=' + encodeURIComponent(personId); + if (processId) url += '&process_id=' + encodeURIComponent(processId); + if (processCode) url += '&process_code=' + encodeURIComponent(processCode); + if (cycleKey) url += '&cycle_key=' + encodeURIComponent(cycleKey); + + fetch(url) + .then(function(response) { + if (!response.ok) { + return response.text().then(function(text) { + var errStr = 'HTTP ' + response.status + ': '; + var corrId = ''; + try { + var data = JSON.parse(text); + errStr += (data.error && data.error.message) ? data.error.message : (data.error || text); + if (data.correlation_id) corrId = data.correlation_id; + } catch (e) { + errStr += text.substring(0, 100); + } + throw new Error(errStr + (corrId ? ' (ID: ' + corrId + ')' : '')); + }); + } + return response.text(); + }) + .then(function(html) { + modalBody.innerHTML = html; + var returnedTitle = modalBody.querySelector('#instance-modal-title'); + if (returnedTitle) { + var modalTitleElem = instanceModal.querySelector('.modal-title'); + if (modalTitleElem) { + modalTitleElem.innerHTML = returnedTitle.innerHTML; + returnedTitle.remove(); + } + } + }) + .catch(function(err) { + console.error('Fetch error:', err); + modalBody.innerHTML = '
Błąd ładowania:
' + err.message + '
'; + }); + });""" + +new_handler = """ var instanceModal = document.getElementById('instanceModal'); + instanceModal.addEventListener('show.bs.modal', function (event) { + var button = event.relatedTarget; + if (!button) return; + + var subjectType = button.dataset.subjectType || 'person'; + var subjectId = button.dataset.subjectId || button.dataset.personId || ''; + var personId = button.dataset.personId || ''; + var processId = button.dataset.processId || ''; + var processCode = button.dataset.processCode || ''; + var cycleKey = button.dataset.cycleKey || ''; + + instanceModal.dataset.lastSubjectType = subjectType; + instanceModal.dataset.lastSubjectId = subjectId; + instanceModal.dataset.lastPersonId = personId; + instanceModal.dataset.lastProcessId = processId; + instanceModal.dataset.lastProcessCode = processCode; + instanceModal.dataset.lastCycleKey = cycleKey; + + var modalTitle = instanceModal.querySelector('.modal-title'); + var modalBody = instanceModal.querySelector('.modal-body'); + + modalTitle.textContent = 'Ładowanie...'; + modalBody.innerHTML = '

Ladowanie...

'; + + if (!subjectId) { + modalTitle.textContent = 'Błąd parametru'; + modalBody.innerHTML = '
Brak wymaganego identyfikatora (subject_id). Nie można załadować procesu.
'; + return; + } + + if (!processId && !processCode) { + modalTitle.textContent = 'Błąd parametru'; + modalBody.innerHTML = '
Brak identyfikatora procesu (process_id lub process_code). Nie można załadować procesu.
'; + return; + } + + var url = '_get_instance_details.php?subject_type=' + encodeURIComponent(subjectType) + '&subject_id=' + encodeURIComponent(subjectId); + if (personId) url += '&person_id=' + encodeURIComponent(personId); + if (processId) url += '&process_id=' + encodeURIComponent(processId); + if (processCode) url += '&process_code=' + encodeURIComponent(processCode); + if (cycleKey) url += '&cycle_key=' + encodeURIComponent(cycleKey); + + fetch(url) + .then(function(response) { + if (!response.ok) { + return response.text().then(function(text) { + var errStr = 'HTTP ' + response.status + ': '; + var corrId = ''; + try { + var data = JSON.parse(text); + errStr += (data.error && data.error.message) ? data.error.message : (data.error || text); + if (data.correlation_id) corrId = data.correlation_id; + } catch (e) { + errStr += text.substring(0, 100); + } + throw new Error(errStr + (corrId ? ' (ID: ' + corrId + ')' : '')); + }); + } + return response.text(); + }) + .then(function(html) { + modalBody.innerHTML = html; + var returnedTitle = modalBody.querySelector('#instance-modal-title'); + if (returnedTitle) { + modalTitle.innerHTML = returnedTitle.innerHTML; + returnedTitle.remove(); + } else { + modalTitle.textContent = 'Szczegóły Procesu'; + } + }) + .catch(function(err) { + console.error('Fetch error:', err); + modalTitle.textContent = 'Błąd'; + modalBody.innerHTML = '
Błąd ładowania:
' + err.message + '
'; + }); + });""" + +if old_handler in content: + content = content.replace(old_handler, new_handler) +else: + print("Could not find the old handler exactly as written. Applying regex replacement instead.") + # More robust replacement + start_str = "var instanceModal = document.getElementById('instanceModal');\n instanceModal.addEventListener('show.bs.modal', function (event) {" + start_idx = content.find(start_str) + if start_idx != -1: + end_idx = content.find("});", start_idx) + 3 + # Look for the next section to make sure we got the right block + next_section = content.find(" // Bulk actions", end_idx) + if next_section != -1 and next_section - end_idx < 100: + content = content[:start_idx] + new_handler + content[end_idx:] + else: + print("Found start but next section is too far. Replacing block anyway.") + content = content[:start_idx] + new_handler + content[end_idx:] + + +with open('index.php', 'w', encoding='utf-8') as f: + f.write(content) +print("index.php patched (step 4)")