Poprawki po aktualizacji
This commit is contained in:
parent
9ea7b9d268
commit
2e85c01115
@ -183,7 +183,8 @@ $spotkania_cols = [];
|
|||||||
$spotkania_cols[$meeting['group_id']]['group_name'] = $meeting['group_name'];
|
$spotkania_cols[$meeting['group_id']]['group_name'] = $meeting['group_name'];
|
||||||
$spotkania_cols[$meeting['group_id']]['meetings'][] = [
|
$spotkania_cols[$meeting['group_id']]['meetings'][] = [
|
||||||
'datetime' => $meeting['start_datetime'],
|
'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);
|
$isMember = $this->isMemberOfGroup($personId, $bniGroupId);
|
||||||
return [
|
return [
|
||||||
'meeting_id' => $meetingId,
|
'meeting_id' => $meetingId,
|
||||||
|
'cycle_key' => $meeting['group_id'] . '_' . $meeting['start_datetime'],
|
||||||
'person_id' => $personId,
|
'person_id' => $personId,
|
||||||
'attendance_status' => $isMember ? 'present' : 'none',
|
'attendance_status' => $isMember ? 'present' : 'none',
|
||||||
'guest_survey' => null,
|
'guest_survey' => null,
|
||||||
|
|||||||
@ -14,6 +14,9 @@ if (!isset($_SESSION['user_id'])) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$person_id = $_GET['person_id'] ?? null;
|
$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_definition_id = $_GET['process_id'] ?? null;
|
||||||
$process_code = $_GET['process_code'] ?? null;
|
$process_code = $_GET['process_code'] ?? null;
|
||||||
|
|
||||||
@ -63,7 +66,7 @@ if (!$process) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to find an existing instance
|
// 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
|
|||||||
<?php if ($eligibility['is_eligible']): ?>
|
<?php if ($eligibility['is_eligible']): ?>
|
||||||
<h4><?= t('modal.process_not_started', 'Proces nie został uruchomiony') ?></h4>
|
<h4><?= t('modal.process_not_started', 'Proces nie został uruchomiony') ?></h4>
|
||||||
<p>This process has not been started for this person.</p>
|
<p>This process has not been started for this person.</p>
|
||||||
<button id="startProcessBtn" class="btn btn-primary" data-subject-type="<?= $subject_type ?>" data-subject-id="<?= $subject_id ?>" data-person-id="<?= $person_id ?>" data-process-id="<?= $process_definition_id ?>">
|
<button id="startProcessBtn" class="btn btn-primary" data-subject-type="<?= $subject_type ?>" data-subject-id="<?= $subject_id ?>" data-process-id="<?= $process_definition_id ?>" data-process-code="<?= $process_code ?>" data-cycle-key="<?= $cycle_key ?>">
|
||||||
<?= t('modal.start_process', 'Uruchom proces') ?>
|
<?= t('modal.start_process', 'Uruchom proces') ?>
|
||||||
</button>
|
</button>
|
||||||
<?php else: ?>
|
<?php else: ?>
|
||||||
|
|||||||
@ -46,7 +46,7 @@ $engine = new WorkflowEngine();
|
|||||||
$code = $stmt_def->fetchColumn() ?: $processCode;
|
$code = $stmt_def->fetchColumn() ?: $processCode;
|
||||||
|
|
||||||
if($deleteExisting === '1') {
|
if($deleteExisting === '1') {
|
||||||
$instance = $engine->getActiveInstanceForSubject($code, $subjectType, $subjectId);
|
$instance = $engine->getActiveInstanceForSubject($code, $subjectType, $subjectId, $cycleKey);
|
||||||
if ($instance) {
|
if ($instance) {
|
||||||
$engine->deleteInstance($instance['id']);
|
$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) {
|
if ($mode === 'create_new_run' || filter_input(INPUT_POST, 'force', FILTER_VALIDATE_INT) === 1) {
|
||||||
// start new process
|
// 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 = $pdo->prepare("SELECT * FROM process_instances WHERE id = ?");
|
||||||
$stmt->execute([$instanceId]);
|
$stmt->execute([$instanceId]);
|
||||||
$instance = $stmt->fetch(PDO::FETCH_ASSOC);
|
$instance = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|||||||
177
index.php
177
index.php
@ -266,7 +266,7 @@ foreach ($definitions as $def) {
|
|||||||
$color = $status_colors[$status] ?? 'secondary';
|
$color = $status_colors[$status] ?? 'secondary';
|
||||||
$lastActivity = $instance && $instance['last_activity_at'] ? date('d/m/y', strtotime($instance['last_activity_at'])) : '';
|
$lastActivity = $instance && $instance['last_activity_at'] ? date('d/m/y', strtotime($instance['last_activity_at'])) : '';
|
||||||
?>
|
?>
|
||||||
<td class="text-center align-middle" data-bs-toggle="modal" data-bs-target="#instanceModal" data-person-id="<?= $person['id'] ?>" data-process-id="<?= $process['id'] ?>">
|
<td class="text-center align-middle" data-bs-toggle="modal" data-bs-target="#instanceModal" data-subject-type="person" data-subject-id="<?= $person['id'] ?>" data-person-id="<?= $person['id'] ?>" data-process-id="<?= $process['id'] ?>">
|
||||||
<span class="badge rounded-circle bg-<?= $color ?>" style="width: 20px; height: 20px; display: inline-block;" title="<?= ucfirst($status) ?>"> </span>
|
<span class="badge rounded-circle bg-<?= $color ?>" style="width: 20px; height: 20px; display: inline-block;" title="<?= ucfirst($status) ?>"> </span>
|
||||||
<small class="text-muted d-block"><?= $lastActivity ?></small>
|
<small class="text-muted d-block"><?= $lastActivity ?></small>
|
||||||
</td>
|
</td>
|
||||||
@ -717,7 +717,7 @@ foreach ($definitions as $def) {
|
|||||||
document.addEventListener('DOMContentLoaded', function () {
|
document.addEventListener('DOMContentLoaded', function () {
|
||||||
|
|
||||||
const meetingProcesses = <?= json_encode($meeting_processes ?? []) ?>;
|
const meetingProcesses = <?= json_encode($meeting_processes ?? []) ?>;
|
||||||
const statusColors = <?= json_encode($status_colors ?? []) ?>;
|
if (!window.STATUS_COLORS) { window.STATUS_COLORS = <?= json_encode($status_colors ?? []) ?>; }
|
||||||
|
|
||||||
|
|
||||||
const meetingModal = new bootstrap.Modal(document.getElementById('meetingAttendanceModal'));
|
const meetingModal = new bootstrap.Modal(document.getElementById('meetingAttendanceModal'));
|
||||||
@ -728,15 +728,16 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
const meetingDateInput = document.getElementById('meetingDate');
|
const meetingDateInput = document.getElementById('meetingDate');
|
||||||
const attendanceStatus = document.getElementById('attendanceStatus');
|
const attendanceStatus = document.getElementById('attendanceStatus');
|
||||||
const guestSurveySection = document.getElementById('guestSurveySection');
|
const guestSurveySection = document.getElementById('guestSurveySection');
|
||||||
const statusColors = {
|
if (!window.STATUS_COLORS) window.STATUS_COLORS = {};
|
||||||
|
Object.assign(window.STATUS_COLORS, {
|
||||||
'none': 'secondary',
|
'none': 'secondary',
|
||||||
'absent': 'danger',
|
'absent': 'danger',
|
||||||
'substitute': 'warning',
|
'substitute': 'warning',
|
||||||
'present': 'success',
|
'present': 'success',
|
||||||
};
|
});
|
||||||
|
|
||||||
function updateDot(dot, status) {
|
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.className = `badge rounded-circle bg-${color} meeting-dot`;
|
||||||
dot.dataset.currentStatus = status;
|
dot.dataset.currentStatus = status;
|
||||||
dot.title = `Status: ${status.charAt(0).toUpperCase() + status.slice(1)}`;
|
dot.title = `Status: ${status.charAt(0).toUpperCase() + status.slice(1)}`;
|
||||||
@ -886,6 +887,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
const currentMeetingObj = meetings[currentIndex];
|
const currentMeetingObj = meetings[currentIndex];
|
||||||
const currentMeetingDate = typeof currentMeetingObj === 'object' ? currentMeetingObj.datetime : currentMeetingObj;
|
const currentMeetingDate = typeof currentMeetingObj === 'object' ? currentMeetingObj.datetime : currentMeetingObj;
|
||||||
const currentMeetingId = typeof currentMeetingObj === 'object' ? currentMeetingObj.meeting_id : null;
|
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' });
|
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');
|
const processContainer = headerCell.querySelector('.meeting-process-container');
|
||||||
@ -894,9 +896,12 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
const dot = processContainer.querySelector('.meeting-process-dot');
|
const dot = processContainer.querySelector('.meeting-process-dot');
|
||||||
if (dot) {
|
if (dot) {
|
||||||
dot.dataset.subjectId = currentMeetingId;
|
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 instance = meetingProcesses[currentMeetingId] && meetingProcesses[currentMeetingId]['meeting_preparation'];
|
||||||
const status = instance ? instance.computed_status : 'none';
|
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.className = `badge rounded-circle bg-${color} process-dot meeting-process-dot`;
|
||||||
dot.dataset.processId = instance ? instance.id : '';
|
dot.dataset.processId = instance ? instance.id : '';
|
||||||
}
|
}
|
||||||
@ -967,17 +972,78 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
var instanceModal = document.getElementById('instanceModal');
|
var instanceModal = document.getElementById('instanceModal');
|
||||||
instanceModal.addEventListener('show.bs.modal', function (event) {
|
instanceModal.addEventListener('show.bs.modal', function (event) {
|
||||||
var button = event.relatedTarget;
|
var button = event.relatedTarget;
|
||||||
var personId = button.dataset.personId || '';
|
if (!button) return;
|
||||||
var processId = button.dataset.processId;
|
|
||||||
var subjectType = button.dataset.subjectType || 'person';
|
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');
|
var modalBody = instanceModal.querySelector('.modal-body');
|
||||||
|
|
||||||
// Load content via AJAX
|
modalTitle.textContent = 'Ładowanie...';
|
||||||
fetch(`_get_instance_details.php?person_id=${personId}&subject_type=${subjectType}&subject_id=${subjectId}&process_id=${processId}`)
|
modalBody.innerHTML = '<div class="text-center mt-4"><div class="spinner-border text-primary" role="status"></div><p class="mt-2">Ladowanie...</p></div>';
|
||||||
.then(response => response.text())
|
|
||||||
.then(html => {
|
if (!subjectId) {
|
||||||
|
modalTitle.textContent = 'Błąd parametru';
|
||||||
|
modalBody.innerHTML = '<div class="alert alert-danger m-3">Brak wymaganego identyfikatora (subject_id). Nie można załadować procesu.</div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!processId && !processCode) {
|
||||||
|
modalTitle.textContent = 'Błąd parametru';
|
||||||
|
modalBody.innerHTML = '<div class="alert alert-danger m-3">Brak identyfikatora procesu (process_id lub process_code). Nie można załadować procesu.</div>';
|
||||||
|
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;
|
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 = '<div class="alert alert-danger m-3"><strong>Błąd ładowania:</strong><br>' + err.message + '</div>';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -1239,11 +1305,14 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
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 processId = btn.dataset.processId;
|
||||||
|
const processCode = btn.dataset.processCode;
|
||||||
|
const cycleKey = btn.dataset.cycleKey;
|
||||||
|
|
||||||
if (!personId || !processId) {
|
if (!subjectId || (!processId && !processCode)) {
|
||||||
alert('Brak ID osoby lub procesu');
|
alert('Brak wymaganych parametrów do uruchomienia procesu.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1252,11 +1321,18 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
btn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Uruchamianie...';
|
btn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Uruchamianie...';
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('person_id', personId);
|
formData.append('subject_type', subjectType);
|
||||||
formData.append('process_id', processId);
|
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) {
|
if (instanceModalElement) {
|
||||||
instanceModalElement.dataset.lastPersonId = personId;
|
instanceModalElement.dataset.lastSubjectType = subjectType;
|
||||||
|
instanceModalElement.dataset.lastSubjectId = subjectId;
|
||||||
instanceModalElement.dataset.lastProcessId = processId;
|
instanceModalElement.dataset.lastProcessId = processId;
|
||||||
|
instanceModalElement.dataset.lastProcessCode = processCode;
|
||||||
|
instanceModalElement.dataset.lastCycleKey = cycleKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch('_init_single_instance.php', {
|
fetch('_init_single_instance.php', {
|
||||||
@ -1269,7 +1345,12 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
const modalBody = instanceModalElement.querySelector('.modal-body');
|
const modalBody = instanceModalElement.querySelector('.modal-body');
|
||||||
modalBody.innerHTML = '<div class="text-center mt-4"><div class="spinner-border text-primary" role="status"></div><p class="mt-2">Ładowanie...</p></div>';
|
modalBody.innerHTML = '<div class="text-center mt-4"><div class="spinner-border text-primary" role="status"></div><p class="mt-2">Ładowanie...</p></div>';
|
||||||
|
|
||||||
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(r => r.text())
|
||||||
.then(html => {
|
.then(html => {
|
||||||
modalBody.innerHTML = html;
|
modalBody.innerHTML = html;
|
||||||
@ -1296,12 +1377,15 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
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 processCode = restartBtn.dataset.processCode;
|
||||||
|
const processId = restartBtn.dataset.processId;
|
||||||
|
const cycleKey = restartBtn.dataset.cycleKey;
|
||||||
const mode = restartBtn.dataset.mode;
|
const mode = restartBtn.dataset.mode;
|
||||||
|
|
||||||
if (!personId || !processCode) {
|
if (!subjectId || !processCode) {
|
||||||
alert('Brak ID osoby lub kodu procesu');
|
alert('Brak wymaganych parametrów do zrestartowania procesu.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1310,8 +1394,11 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
restartBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>...';
|
restartBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>...';
|
||||||
|
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('person_id', personId);
|
formData.append('subject_type', subjectType);
|
||||||
|
formData.append('subject_id', subjectId);
|
||||||
formData.append('process_code', processCode);
|
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');
|
formData.append('mode', mode || 'create_new_run');
|
||||||
|
|
||||||
fetch('_init_single_instance.php', {
|
fetch('_init_single_instance.php', {
|
||||||
@ -1332,10 +1419,8 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
const modalBody = instanceModalElement.querySelector('.modal-body');
|
const modalBody = instanceModalElement.querySelector('.modal-body');
|
||||||
modalBody.innerHTML = '<div class="text-center mt-4"><div class="spinner-border text-primary" role="status"></div><p class="mt-2">Ładowanie...</p></div>';
|
modalBody.innerHTML = '<div class="text-center mt-4"><div class="spinner-border text-primary" role="status"></div><p class="mt-2">Ładowanie...</p></div>';
|
||||||
|
|
||||||
// Use process_id if we have it from dataset, otherwise fetch using code.
|
let fetchUrl = `_get_instance_details.php?subject_type=${encodeURIComponent(subjectType)}&subject_id=${encodeURIComponent(subjectId)}&process_code=${encodeURIComponent(processCode)}`;
|
||||||
// The original _get_instance_details endpoint seems to accept process_id or process_code? Let's check.
|
if (cycleKey) fetchUrl += `&cycle_key=${encodeURIComponent(cycleKey)}`;
|
||||||
// Actually let's use the instanceModalElement.dataset.lastProcessId if it exists.
|
|
||||||
const fetchUrl = `_get_instance_details.php?person_id=${personId}&process_code=${processCode}`;
|
|
||||||
|
|
||||||
fetch(fetchUrl)
|
fetch(fetchUrl)
|
||||||
.then(r => r.text())
|
.then(r => r.text())
|
||||||
@ -1393,10 +1478,18 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.success || !data.error) {
|
if (data.success || !data.error) {
|
||||||
// Reload modal content
|
// 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 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(r => r.text())
|
||||||
.then(html => {
|
.then(html => {
|
||||||
instanceModalElement.querySelector('.modal-body').innerHTML = html;
|
instanceModalElement.querySelector('.modal-body').innerHTML = html;
|
||||||
@ -1443,10 +1536,18 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
.then(r => r.json())
|
.then(r => r.json())
|
||||||
.then(data => {
|
.then(data => {
|
||||||
if (data.success || !data.error) {
|
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 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(r => r.text())
|
||||||
.then(html => {
|
.then(html => {
|
||||||
instanceModalElement.querySelector('.modal-body').innerHTML = 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 () {
|
instanceModalElement.addEventListener('hidden.bs.modal', function () {
|
||||||
if (window.matrixNeedsRefresh) {
|
if (window.matrixNeedsRefresh) {
|
||||||
|
|||||||
17
patch2.py
17
patch2.py
@ -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.")
|
|
||||||
38
patch_index3.py
Normal file
38
patch_index3.py
Normal file
@ -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'<td class="text-center align-middle" data-bs-toggle="modal" data-bs-target="#instanceModal" data-person-id="<\?= \$person[\'id\'] \?>" data-process-id="<\?= \$process[\'id\'] \?>(.*?)">',
|
||||||
|
r'<td class="text-center align-middle" data-bs-toggle="modal" data-bs-target="#instanceModal" data-subject-type="person" data-subject-id="<?= $person[\'id\'] ?>" data-process-id="<?= $process[\'id\'] ?>"\1> ',
|
||||||
|
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="<?= $mp_def[\'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)")
|
||||||
168
patch_index4.py
Normal file
168
patch_index4.py
Normal file
@ -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 = '<div class="text-center mt-4"><div class="spinner-border text-primary" role="status"></div><p class="mt-2">Ladowanie...</p></div>';
|
||||||
|
|
||||||
|
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 = '<div class="alert alert-danger m-3"><strong>Błąd ładowania:</strong><br>' + err.message + '</div>';
|
||||||
|
});
|
||||||
|
});"""
|
||||||
|
|
||||||
|
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 = '<div class="text-center mt-4"><div class="spinner-border text-primary" role="status"></div><p class="mt-2">Ladowanie...</p></div>';
|
||||||
|
|
||||||
|
if (!subjectId) {
|
||||||
|
modalTitle.textContent = 'Błąd parametru';
|
||||||
|
modalBody.innerHTML = '<div class="alert alert-danger m-3">Brak wymaganego identyfikatora (subject_id). Nie można załadować procesu.</div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!processId && !processCode) {
|
||||||
|
modalTitle.textContent = 'Błąd parametru';
|
||||||
|
modalBody.innerHTML = '<div class="alert alert-danger m-3">Brak identyfikatora procesu (process_id lub process_code). Nie można załadować procesu.</div>';
|
||||||
|
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 = '<div class="alert alert-danger m-3"><strong>Błąd ładowania:</strong><br>' + err.message + '</div>';
|
||||||
|
});
|
||||||
|
});"""
|
||||||
|
|
||||||
|
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)")
|
||||||
Loading…
x
Reference in New Issue
Block a user