Mechanizm obsługi procesów
This commit is contained in:
parent
82b98582c4
commit
a141f60df0
@ -1,12 +1,6 @@
|
||||
<?php
|
||||
require_once __DIR__ . '/db/config.php';
|
||||
|
||||
/**
|
||||
* Class WorkflowEngine
|
||||
*
|
||||
* Centralny serwis do zarządzania logiką procesów.
|
||||
* Interfejs użytkownika nie powinien bezpośrednio zmieniać statusów ani instancji; wszystkie operacje muszą przechodzić przez ten silnik.
|
||||
*/
|
||||
class WorkflowEngine {
|
||||
|
||||
private $pdo;
|
||||
@ -15,11 +9,6 @@ class WorkflowEngine {
|
||||
$this->pdo = db();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pobiera wszystkie dane niezbędne dla głównej macierzy pulpitu procesów.
|
||||
*
|
||||
* @return array Tablica zawierająca 'people', 'definitions' i zmapowaną tablicę 'instances'.
|
||||
*/
|
||||
public function getDashboardMatrix(): array {
|
||||
// Get all people (potential assignees)
|
||||
$stmt_people = $this->pdo->prepare("SELECT id, firstName, lastName, companyName, role, email, phone FROM people ORDER BY lastName, firstName");
|
||||
@ -48,216 +37,179 @@ class WorkflowEngine {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Rozpoczyna nową instancję procesu dla danej osoby.
|
||||
*
|
||||
* @param string $processCode Unikalny kod definicji procesu.
|
||||
* @param int $personId ID osoby.
|
||||
* @param int $userId ID użytkownika inicjującego akcję.
|
||||
* @return int|null ID nowo utworzonej instancji lub null w przypadku niepowodzenia.
|
||||
*/
|
||||
public function startProcess(string $processCode, int $personId, int $userId): ?int {
|
||||
// 1. Znajdź aktywną definicję procesu po kodzie.
|
||||
// 2. Pobierz start_node_id z definicji.
|
||||
// 3. Utwórz nową instancję procesu ze statusem 'in_progress' i current_node_id.
|
||||
// 4. Utwórz zdarzenie systemowe dla rozpoczęcia procesu.
|
||||
// TODO: Implementacja logiki.
|
||||
return null;
|
||||
error_log("startProcess: processCode=$processCode, personId=$personId, userId=$userId");
|
||||
$this->pdo->beginTransaction();
|
||||
try {
|
||||
// 1. Find active process definition by code.
|
||||
$stmt_def = $this->pdo->prepare("SELECT * FROM process_definitions WHERE code = ? AND active = 1");
|
||||
$stmt_def->execute([$processCode]);
|
||||
$definition = $stmt_def->fetch(PDO::FETCH_ASSOC);
|
||||
error_log("startProcess: definition=" . print_r($definition, true));
|
||||
|
||||
if (!$definition) {
|
||||
throw new Exception("Active process definition with code '$processCode' not found.");
|
||||
}
|
||||
|
||||
$definition_json = json_decode($definition['definition_json'], true);
|
||||
if (!$definition_json || !isset($definition_json['start_node_id'])) {
|
||||
throw new Exception("Process definition is missing start_node_id.");
|
||||
}
|
||||
$startNodeId = $definition_json['start_node_id'];
|
||||
|
||||
// 2. Create a new process instance.
|
||||
$stmt_insert = $this->pdo->prepare(
|
||||
"INSERT INTO process_instances (personId, processDefinitionId, current_node_id, current_status, lastActivityAt) VALUES (?, ?, ?, 'in_progress', NOW())"
|
||||
);
|
||||
$stmt_insert->execute([$personId, $definition['id'], $startNodeId]);
|
||||
error_log("startProcess: affected rows=" . $stmt_insert->rowCount());
|
||||
$instanceId = $this->pdo->lastInsertId();
|
||||
error_log("startProcess: instanceId=$instanceId");
|
||||
|
||||
// 3. Create a system event for process start.
|
||||
$this->addEvent($instanceId, 'system', 'Process started.', $startNodeId, [], $userId);
|
||||
|
||||
$this->pdo->commit();
|
||||
return (int)$instanceId;
|
||||
} catch (Exception $e) {
|
||||
$this->pdo->rollBack();
|
||||
error_log("Error in startProcess: " . $e->getMessage());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public function getProcessState(int $instanceId): ?array {
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM process_instances WHERE id = ?");
|
||||
$stmt->execute([$instanceId]);
|
||||
$instance = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$instance) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$stmt_def = $this->pdo->prepare("SELECT definition_json FROM process_definitions WHERE id = ?");
|
||||
$stmt_def->execute([$instance['processDefinitionId']]);
|
||||
$definition_json = $stmt_def->fetchColumn();
|
||||
$definition = json_decode($definition_json, true);
|
||||
|
||||
$currentNodeId = $instance['current_node_id'];
|
||||
$nodeInfo = $definition['nodes'][$currentNodeId] ?? null;
|
||||
|
||||
return [
|
||||
'instance' => $instance,
|
||||
'definition' => $definition,
|
||||
'currentNode' => $nodeInfo,
|
||||
];
|
||||
}
|
||||
|
||||
public function applyTransition(int $instanceId, string $transitionId, array $inputPayload, int $userId): bool {
|
||||
$this->pdo->beginTransaction();
|
||||
try {
|
||||
$state = $this->getProcessState($instanceId);
|
||||
if (!$state) {
|
||||
throw new Exception("Process instance not found.");
|
||||
}
|
||||
|
||||
$instance = $state['instance'];
|
||||
$definition = $state['definition'];
|
||||
$currentNodeId = $instance['current_node_id'];
|
||||
|
||||
// Find the transition from the definition
|
||||
$transition = null;
|
||||
foreach ($definition['transitions'] as $t) {
|
||||
if ($t['from'] === $currentNodeId && $t['id'] === $transitionId) {
|
||||
$transition = $t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$transition) {
|
||||
throw new Exception("Transition not found or not allowed from the current node.");
|
||||
}
|
||||
|
||||
// TODO: Add rule validation here
|
||||
|
||||
$newNodeId = $transition['to'];
|
||||
$newNodeInfo = $definition['nodes'][$newNodeId] ?? null;
|
||||
|
||||
// Update instance
|
||||
$stmt_update = $this->pdo->prepare(
|
||||
"UPDATE process_instances SET current_node_id = ?, current_status = ?, current_reason = ?, suggested_next_step = ?, lastActivityAt = NOW() WHERE id = ?"
|
||||
);
|
||||
$stmt_update->execute([
|
||||
$newNodeId,
|
||||
$newNodeInfo['ui_hints']['status'] ?? 'in_progress',
|
||||
$newNodeInfo['ui_hints']['reason'] ?? '',
|
||||
$newNodeInfo['ui_hints']['next_step'] ?? '',
|
||||
$instanceId
|
||||
]);
|
||||
|
||||
// Add event
|
||||
$message = $inputPayload['message'] ?? $transition['name'];
|
||||
$this->addEvent($instanceId, 'transition_applied', $message, $newNodeId, $inputPayload, $userId);
|
||||
|
||||
$this->pdo->commit();
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
$this->pdo->rollBack();
|
||||
error_log("Error in applyTransition: " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private function addEvent(int $instanceId, string $eventType, string $message, ?string $nodeId, array $payload, int $userId): void {
|
||||
$stmt = $this->pdo->prepare(
|
||||
"INSERT INTO process_events (processInstanceId, eventType, message, node_id, payload_json, createdById) VALUES (?, ?, ?, ?, ?, ?)"
|
||||
);
|
||||
$stmt->execute([$instanceId, $eventType, $message, $nodeId, json_encode($payload), $userId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pobiera pojedynczą instancję procesu, tworząc ją, jeśli nie istnieje.
|
||||
*
|
||||
* @param int $personId
|
||||
* @param int $processDefinitionId
|
||||
* @param int $userId Użytkownik inicjujący utworzenie, jeśli to nastąpi.
|
||||
* @return array|null Tablica asocjacyjna z danymi instancji.
|
||||
*/
|
||||
public function getOrCreateInstanceByDefId(int $personId, int $processDefinitionId, int $userId): ?array {
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM process_instances WHERE personId = ? AND processDefinitionId = ?");
|
||||
$stmt->execute([$personId, $processDefinitionId]);
|
||||
$instance = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$instance) {
|
||||
// Fetch the process definition to get the initial status
|
||||
$stmt_def = $this->pdo->prepare("SELECT definition_json FROM process_definitions WHERE id = ?");
|
||||
$stmt_def = $this->pdo->prepare("SELECT code FROM process_definitions WHERE id = ?");
|
||||
$stmt_def->execute([$processDefinitionId]);
|
||||
$definition_raw = $stmt_def->fetchColumn();
|
||||
$definition = $definition_raw ? json_decode($definition_raw, true) : null;
|
||||
$initial_status = $definition['initial_status'] ?? 'none';
|
||||
$processCode = $stmt_def->fetchColumn();
|
||||
|
||||
$stmt_insert = $this->pdo->prepare("INSERT INTO process_instances (personId, processDefinitionId, current_status) VALUES (?, ?, ?)");
|
||||
$stmt_insert->execute([$personId, $processDefinitionId, $initial_status]);
|
||||
$instanceId = $this->pdo->lastInsertId();
|
||||
|
||||
// Utwórz zdarzenie systemowe dla utworzenia instancji
|
||||
$this->addEvent($instanceId, 'system', 'Instancja utworzona.', null, [], $userId);
|
||||
|
||||
// Pobierz ponownie nowo utworzoną instancję
|
||||
$stmt->execute([$personId, $processDefinitionId]);
|
||||
$instance = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
if($processCode) {
|
||||
$instanceId = $this->startProcess($processCode, $personId, $userId);
|
||||
if($instanceId) {
|
||||
$stmt->execute([$personId, $processDefinitionId]);
|
||||
$instance = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $instance;
|
||||
return $instance !== false ? $instance : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dodaje nowe zdarzenie do historii instancji.
|
||||
* To jest wewnętrzna metoda pomocnicza.
|
||||
*/
|
||||
private function addEvent(int $instanceId, string $eventType, string $message, ?string $nodeId, array $payload, int $userId): void {
|
||||
$stmt = $this->pdo->prepare(
|
||||
"INSERT INTO process_events (processInstanceId, event_type, message, node_id, payload_json, createdById) VALUES (?, ?, ?, ?, ?, ?)"
|
||||
);
|
||||
$stmt->execute([$instanceId, $eventType, $message, $nodeId, json_encode($payload), $userId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pobiera historię zdarzeń dla danej instancji.
|
||||
*
|
||||
* @param int $instanceId
|
||||
* @return array
|
||||
*/
|
||||
public function getEvents(int $instanceId): array {
|
||||
$stmt_events = $this->pdo->prepare("SELECT pe.*, p.email as user_email, p.firstName, p.lastName FROM process_events pe JOIN people p ON pe.createdById = p.id WHERE pe.processInstanceId = ? ORDER BY pe.createdAt DESC");
|
||||
$stmt_events->execute([$instanceId]);
|
||||
return $stmt_events->fetchAll(PDO::FETCH_ASSOC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pobiera listę dostępnych przejść z bieżącego węzła instancji.
|
||||
*
|
||||
* @param int $instanceId
|
||||
* @return array Lista dostępnych przejść.
|
||||
*/
|
||||
public function getAvailableTransitions(int $instanceId): array {
|
||||
$stmt = $this->pdo->prepare(
|
||||
'SELECT pi.current_status, pd.definition_json '
|
||||
. 'FROM process_instances pi '
|
||||
. 'JOIN process_definitions pd ON pi.processDefinitionId = pd.id '
|
||||
. 'WHERE pi.id = ?'
|
||||
);
|
||||
$stmt->execute([$instanceId]);
|
||||
$result = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$result || empty($result['definition_json'])) {
|
||||
$state = $this->getProcessState($instanceId);
|
||||
if (!$state) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$definition = json_decode($result['definition_json'], true);
|
||||
if (!$definition || !isset($definition['transitions'])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$current_status = $result['current_status'];
|
||||
$allowed_transitions = $definition['transitions'][$current_status] ?? [];
|
||||
$currentNodeId = $state['instance']['current_node_id'];
|
||||
$definition = $state['definition'];
|
||||
|
||||
$transitions = [];
|
||||
foreach ($allowed_transitions as $target_status) {
|
||||
$transitions[] = [
|
||||
'id' => 'transition_' . str_replace(' ', '_', strtolower($target_status)), // e.g., transition_in_progress
|
||||
'name' => 'Oznacz jako ' . $target_status, // e.g., Oznacz jako In Progress
|
||||
'target_status' => $target_status
|
||||
];
|
||||
if (isset($definition['transitions'])) {
|
||||
foreach ($definition['transitions'] as $t) {
|
||||
if ($t['from'] === $currentNodeId) {
|
||||
$transitions[] = $t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $transitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stosuje przejście do instancji procesu. To jest główna metoda do postępu w przepływie pracy.
|
||||
*
|
||||
* @param int $instanceId ID instancji procesu.
|
||||
* @param string $transitionId ID przejścia do zastosowania (z definition_json).
|
||||
* @param array $inputPayload Dane zebrane od użytkownika dla tego kroku.
|
||||
* @param int $userId ID użytkownika wykonującego akcję.
|
||||
* @return bool True w przypadku sukcesu, false w przypadku porażki.
|
||||
*/
|
||||
public function applyTransition(int $instanceId, string $transitionId, array $inputPayload, int $userId): bool {
|
||||
$this->pdo->beginTransaction();
|
||||
|
||||
try {
|
||||
// 1. Pobierz instancję i dostępne przejścia
|
||||
$stmt = $this->pdo->prepare("SELECT * FROM process_instances WHERE id = ?");
|
||||
$stmt->execute([$instanceId]);
|
||||
$instance = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (!$instance) {
|
||||
// Instancja nie znaleziona
|
||||
$this->pdo->rollBack();
|
||||
return false;
|
||||
}
|
||||
|
||||
$availableTransitions = $this->getAvailableTransitions($instanceId);
|
||||
|
||||
// 2. Sprawdź, czy przejście jest dozwolone
|
||||
$selectedTransition = null;
|
||||
if ($transitionId === 'note') { // Specjalny przypadek dodawania notatki
|
||||
$selectedTransition = ['id' => 'note', 'name' => 'Dodano notatkę', 'target_status' => $instance['current_status']];
|
||||
} else {
|
||||
foreach ($availableTransitions as $trans) {
|
||||
if ($trans['id'] === $transitionId) {
|
||||
$selectedTransition = $trans;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$selectedTransition) {
|
||||
// Nieprawidłowe lub niedozwolone przejście
|
||||
$this->pdo->rollBack();
|
||||
return false;
|
||||
}
|
||||
|
||||
// 3. Utwórz zdarzenie
|
||||
$eventType = ($transitionId === 'note') ? 'note' : 'transition_applied';
|
||||
$message = $inputPayload['message'] ?? $selectedTransition['name'];
|
||||
$this->addEvent($instanceId, $eventType, $message, null, $inputPayload, $userId);
|
||||
|
||||
// 4. Zaktualizuj instancję
|
||||
$stmt_update = $this->pdo->prepare(
|
||||
"UPDATE process_instances SET current_status = ?, lastActivityAt = CURRENT_TIMESTAMP WHERE id = ?"
|
||||
);
|
||||
$stmt_update->execute([$selectedTransition['target_status'], $instanceId]);
|
||||
|
||||
$this->pdo->commit();
|
||||
return true;
|
||||
|
||||
} catch (Exception $e) {
|
||||
$this->pdo->rollBack();
|
||||
error_log("Błąd w applyTransition: " . $e->getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Masowa operacja stosowania tego samego przejścia do wielu osób dla danego procesu.
|
||||
*
|
||||
* @param string $processCode
|
||||
* @param array $personIds
|
||||
* @param string $transitionId
|
||||
* @param array $inputPayload
|
||||
* @param int $userId
|
||||
* @return array Podsumowanie wyników (np. ['success' => count, 'failed' => count]).
|
||||
*/
|
||||
public function bulkApplyTransition(string $processCode, array $personIds, string $transitionId, array $inputPayload, int $userId): array {
|
||||
// 1. Upewnij się, że instancje istnieją dla wszystkich osób (użyj ensureInstances).
|
||||
// 2. Przejdź przez pętlę personIds i wywołaj applyTransition dla każdej z nich.
|
||||
// TODO: Implementacja logiki.
|
||||
return ['success' => 0, 'failed' => 0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Zapewnia, że instancje procesów istnieją dla danego zestawu osób i kodów procesów.
|
||||
* Jeśli instancja brakuje, zostanie utworzona.
|
||||
*
|
||||
* @param array $personIds
|
||||
* @param array $processCodes
|
||||
* @param int $userId
|
||||
* @return array Podsumowanie utworzonych instancji.
|
||||
*/
|
||||
public function ensureInstances(array $personIds, array $processCodes, int $userId): array {
|
||||
// TODO: Implementacja logiki do tworzenia brakujących instancji.
|
||||
return ['created' => 0];
|
||||
}
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
require_once 'WorkflowEngine.php';
|
||||
session_start();
|
||||
|
||||
@ -10,6 +11,8 @@ if (!isset($_SESSION['user_id'])) {
|
||||
$personId = $_GET['personId'] ?? null;
|
||||
$processDefinitionId = $_GET['processId'] ?? null; // Pulpit wysyła processId, który jest ID definicji
|
||||
|
||||
|
||||
|
||||
if (!$personId || !$processDefinitionId) {
|
||||
http_response_code(400);
|
||||
die('Brakujące parametry');
|
||||
@ -20,9 +23,10 @@ $engine = new WorkflowEngine();
|
||||
|
||||
// 1. Pobierz lub utwórz instancję
|
||||
$instance = $engine->getOrCreateInstanceByDefId($personId, $processDefinitionId, $userId);
|
||||
|
||||
if (!$instance) {
|
||||
http_response_code(500);
|
||||
die('Nie można pobrać lub utworzyć instancji procesu.');
|
||||
die("Nie można pobrać lub utworzyć instancji procesu. personId: $personId, processDefinitionId: $processDefinitionId, userId: $userId");
|
||||
}
|
||||
$instanceId = $instance['id'];
|
||||
|
||||
|
||||
5
cookie.txt
Normal file
5
cookie.txt
Normal file
@ -0,0 +1,5 @@
|
||||
# Netscape HTTP Cookie File
|
||||
# https://curl.se/docs/http-cookies.html
|
||||
# This file was generated by libcurl! Edit at your own risk.
|
||||
|
||||
localhost FALSE / FALSE 0 PHPSESSID u19ekrhqoemk4c5avca3umanfb
|
||||
@ -39,6 +39,7 @@ $processes = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||
<td><?= htmlspecialchars($process['name']) ?></td>
|
||||
<td class="text-center">
|
||||
<button class="btn btn-sm btn-secondary edit-process-btn"
|
||||
data-bs-toggle="modal" data-bs-target="#createProcessModal"
|
||||
data-process-id="<?= $process['id'] ?>"
|
||||
data-process-name="<?= htmlspecialchars($process['name']) ?>"
|
||||
data-process-definition='<?= htmlspecialchars($process['definition_json'] ?? '') ?>'>
|
||||
@ -127,22 +128,72 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
const processNameInput = createProcessModal.querySelector('#processName');
|
||||
const definitionJsonTextarea = createProcessModal.querySelector('#definitionJson');
|
||||
|
||||
// Handle create button click
|
||||
const createButton = document.querySelector('button[data-bs-target="#createProcessModal"]');
|
||||
createButton.addEventListener('click', function() {
|
||||
modalTitle.textContent = 'Create Process';
|
||||
form.action = '_save_process_definition.php';
|
||||
processIdInput.value = '';
|
||||
processNameInput.value = '';
|
||||
definitionJsonTextarea.value = '';
|
||||
});
|
||||
function renderProcessDefinition(definition) {
|
||||
const statusesList = document.getElementById('statuses-list');
|
||||
const transitionsList = document.getElementById('transitions-list');
|
||||
const initialStatusSelect = document.getElementById('initialStatus');
|
||||
const fromStatusSelect = document.getElementById('fromStatusSelect');
|
||||
const toStatusSelect = document.getElementById('toStatusSelect');
|
||||
|
||||
// Handle edit button click
|
||||
document.querySelectorAll('.edit-process-btn').forEach(button => {
|
||||
button.addEventListener('click', function() {
|
||||
const processId = this.dataset.processId;
|
||||
const processName = this.dataset.processName;
|
||||
const processDefinition = this.dataset.processDefinition;
|
||||
statusesList.innerHTML = '';
|
||||
transitionsList.innerHTML = '';
|
||||
initialStatusSelect.innerHTML = '';
|
||||
fromStatusSelect.innerHTML = '';
|
||||
toStatusSelect.innerHTML = '';
|
||||
|
||||
if (!definition) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const def = JSON.parse(definition);
|
||||
|
||||
// Populate statuses
|
||||
if (def.nodes) {
|
||||
for (const nodeId in def.nodes) {
|
||||
const node = def.nodes[nodeId];
|
||||
const statusItem = document.createElement('div');
|
||||
statusItem.textContent = node.name;
|
||||
statusesList.appendChild(statusItem);
|
||||
|
||||
const option = document.createElement('option');
|
||||
option.value = node.id;
|
||||
option.textContent = node.name;
|
||||
initialStatusSelect.appendChild(option.cloneNode(true));
|
||||
fromStatusSelect.appendChild(option.cloneNode(true));
|
||||
toStatusSelect.appendChild(option.cloneNode(true));
|
||||
}
|
||||
}
|
||||
|
||||
// Set initial status
|
||||
if (def.start_node_id) {
|
||||
initialStatusSelect.value = def.start_node_id;
|
||||
}
|
||||
|
||||
// Populate transitions
|
||||
if (def.transitions) {
|
||||
def.transitions.forEach(transition => {
|
||||
const transitionItem = document.createElement('div');
|
||||
const fromNode = def.nodes[transition.from] ? def.nodes[transition.from].name : 'N/A';
|
||||
const toNode = def.nodes[transition.to] ? def.nodes[transition.to].name : 'N/A';
|
||||
transitionItem.textContent = `${transition.name}: ${fromNode} => ${toNode}`;
|
||||
transitionsList.appendChild(transitionItem);
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error parsing process definition:', e);
|
||||
// Optionally, display an error message to the user
|
||||
}
|
||||
}
|
||||
|
||||
createProcessModal.addEventListener('show.bs.modal', function (event) {
|
||||
const button = event.relatedTarget;
|
||||
const isEdit = button.classList.contains('edit-process-btn');
|
||||
|
||||
if (isEdit) {
|
||||
const processId = button.dataset.processId;
|
||||
const processName = button.dataset.processName;
|
||||
const processDefinition = button.dataset.processDefinition;
|
||||
|
||||
modalTitle.textContent = 'Edit Process';
|
||||
form.action = '_save_process_definition.php';
|
||||
@ -150,9 +201,15 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
processNameInput.value = processName;
|
||||
definitionJsonTextarea.value = processDefinition;
|
||||
|
||||
const modal = new bootstrap.Modal(createProcessModal);
|
||||
modal.show();
|
||||
});
|
||||
renderProcessDefinition(processDefinition);
|
||||
} else {
|
||||
modalTitle.textContent = 'Create Process';
|
||||
form.action = '_save_process_definition.php';
|
||||
processIdInput.value = '';
|
||||
processNameInput.value = '';
|
||||
definitionJsonTextarea.value = '';
|
||||
renderProcessDefinition(''); // Clear the form
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
1
test_php.php
Normal file
1
test_php.php
Normal file
@ -0,0 +1 @@
|
||||
<?php echo "Hello from PHP"; ?>
|
||||
Loading…
x
Reference in New Issue
Block a user