Mechanizm obsługi procesów
This commit is contained in:
parent
82b98582c4
commit
a141f60df0
@ -1,12 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once __DIR__ . '/db/config.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 {
|
class WorkflowEngine {
|
||||||
|
|
||||||
private $pdo;
|
private $pdo;
|
||||||
@ -15,11 +9,6 @@ class WorkflowEngine {
|
|||||||
$this->pdo = db();
|
$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 {
|
public function getDashboardMatrix(): array {
|
||||||
// Get all people (potential assignees)
|
// Get all people (potential assignees)
|
||||||
$stmt_people = $this->pdo->prepare("SELECT id, firstName, lastName, companyName, role, email, phone FROM people ORDER BY lastName, firstName");
|
$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 {
|
public function startProcess(string $processCode, int $personId, int $userId): ?int {
|
||||||
// 1. Znajdź aktywną definicję procesu po kodzie.
|
error_log("startProcess: processCode=$processCode, personId=$personId, userId=$userId");
|
||||||
// 2. Pobierz start_node_id z definicji.
|
$this->pdo->beginTransaction();
|
||||||
// 3. Utwórz nową instancję procesu ze statusem 'in_progress' i current_node_id.
|
try {
|
||||||
// 4. Utwórz zdarzenie systemowe dla rozpoczęcia procesu.
|
// 1. Find active process definition by code.
|
||||||
// TODO: Implementacja logiki.
|
$stmt_def = $this->pdo->prepare("SELECT * FROM process_definitions WHERE code = ? AND active = 1");
|
||||||
return null;
|
$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 {
|
public function getOrCreateInstanceByDefId(int $personId, int $processDefinitionId, int $userId): ?array {
|
||||||
$stmt = $this->pdo->prepare("SELECT * FROM process_instances WHERE personId = ? AND processDefinitionId = ?");
|
$stmt = $this->pdo->prepare("SELECT * FROM process_instances WHERE personId = ? AND processDefinitionId = ?");
|
||||||
$stmt->execute([$personId, $processDefinitionId]);
|
$stmt->execute([$personId, $processDefinitionId]);
|
||||||
$instance = $stmt->fetch(PDO::FETCH_ASSOC);
|
$instance = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
if (!$instance) {
|
if (!$instance) {
|
||||||
// Fetch the process definition to get the initial status
|
$stmt_def = $this->pdo->prepare("SELECT code FROM process_definitions WHERE id = ?");
|
||||||
$stmt_def = $this->pdo->prepare("SELECT definition_json FROM process_definitions WHERE id = ?");
|
|
||||||
$stmt_def->execute([$processDefinitionId]);
|
$stmt_def->execute([$processDefinitionId]);
|
||||||
$definition_raw = $stmt_def->fetchColumn();
|
$processCode = $stmt_def->fetchColumn();
|
||||||
$definition = $definition_raw ? json_decode($definition_raw, true) : null;
|
|
||||||
$initial_status = $definition['initial_status'] ?? 'none';
|
|
||||||
|
|
||||||
$stmt_insert = $this->pdo->prepare("INSERT INTO process_instances (personId, processDefinitionId, current_status) VALUES (?, ?, ?)");
|
if($processCode) {
|
||||||
$stmt_insert->execute([$personId, $processDefinitionId, $initial_status]);
|
$instanceId = $this->startProcess($processCode, $personId, $userId);
|
||||||
$instanceId = $this->pdo->lastInsertId();
|
if($instanceId) {
|
||||||
|
$stmt->execute([$personId, $processDefinitionId]);
|
||||||
// Utwórz zdarzenie systemowe dla utworzenia instancji
|
$instance = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
$this->addEvent($instanceId, 'system', 'Instancja utworzona.', null, [], $userId);
|
}
|
||||||
|
}
|
||||||
// Pobierz ponownie nowo utworzoną instancję
|
|
||||||
$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 {
|
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 = $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]);
|
$stmt_events->execute([$instanceId]);
|
||||||
return $stmt_events->fetchAll(PDO::FETCH_ASSOC);
|
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 {
|
public function getAvailableTransitions(int $instanceId): array {
|
||||||
$stmt = $this->pdo->prepare(
|
$state = $this->getProcessState($instanceId);
|
||||||
'SELECT pi.current_status, pd.definition_json '
|
if (!$state) {
|
||||||
. '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'])) {
|
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
$definition = json_decode($result['definition_json'], true);
|
$currentNodeId = $state['instance']['current_node_id'];
|
||||||
if (!$definition || !isset($definition['transitions'])) {
|
$definition = $state['definition'];
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
$current_status = $result['current_status'];
|
|
||||||
$allowed_transitions = $definition['transitions'][$current_status] ?? [];
|
|
||||||
|
|
||||||
$transitions = [];
|
$transitions = [];
|
||||||
foreach ($allowed_transitions as $target_status) {
|
if (isset($definition['transitions'])) {
|
||||||
$transitions[] = [
|
foreach ($definition['transitions'] as $t) {
|
||||||
'id' => 'transition_' . str_replace(' ', '_', strtolower($target_status)), // e.g., transition_in_progress
|
if ($t['from'] === $currentNodeId) {
|
||||||
'name' => 'Oznacz jako ' . $target_status, // e.g., Oznacz jako In Progress
|
$transitions[] = $t;
|
||||||
'target_status' => $target_status
|
}
|
||||||
];
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $transitions;
|
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
|
<?php
|
||||||
|
|
||||||
require_once 'WorkflowEngine.php';
|
require_once 'WorkflowEngine.php';
|
||||||
session_start();
|
session_start();
|
||||||
|
|
||||||
@ -10,6 +11,8 @@ if (!isset($_SESSION['user_id'])) {
|
|||||||
$personId = $_GET['personId'] ?? null;
|
$personId = $_GET['personId'] ?? null;
|
||||||
$processDefinitionId = $_GET['processId'] ?? null; // Pulpit wysyła processId, który jest ID definicji
|
$processDefinitionId = $_GET['processId'] ?? null; // Pulpit wysyła processId, który jest ID definicji
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!$personId || !$processDefinitionId) {
|
if (!$personId || !$processDefinitionId) {
|
||||||
http_response_code(400);
|
http_response_code(400);
|
||||||
die('Brakujące parametry');
|
die('Brakujące parametry');
|
||||||
@ -20,9 +23,10 @@ $engine = new WorkflowEngine();
|
|||||||
|
|
||||||
// 1. Pobierz lub utwórz instancję
|
// 1. Pobierz lub utwórz instancję
|
||||||
$instance = $engine->getOrCreateInstanceByDefId($personId, $processDefinitionId, $userId);
|
$instance = $engine->getOrCreateInstanceByDefId($personId, $processDefinitionId, $userId);
|
||||||
|
|
||||||
if (!$instance) {
|
if (!$instance) {
|
||||||
http_response_code(500);
|
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'];
|
$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><?= htmlspecialchars($process['name']) ?></td>
|
||||||
<td class="text-center">
|
<td class="text-center">
|
||||||
<button class="btn btn-sm btn-secondary edit-process-btn"
|
<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-id="<?= $process['id'] ?>"
|
||||||
data-process-name="<?= htmlspecialchars($process['name']) ?>"
|
data-process-name="<?= htmlspecialchars($process['name']) ?>"
|
||||||
data-process-definition='<?= htmlspecialchars($process['definition_json'] ?? '') ?>'>
|
data-process-definition='<?= htmlspecialchars($process['definition_json'] ?? '') ?>'>
|
||||||
@ -127,22 +128,72 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
const processNameInput = createProcessModal.querySelector('#processName');
|
const processNameInput = createProcessModal.querySelector('#processName');
|
||||||
const definitionJsonTextarea = createProcessModal.querySelector('#definitionJson');
|
const definitionJsonTextarea = createProcessModal.querySelector('#definitionJson');
|
||||||
|
|
||||||
// Handle create button click
|
function renderProcessDefinition(definition) {
|
||||||
const createButton = document.querySelector('button[data-bs-target="#createProcessModal"]');
|
const statusesList = document.getElementById('statuses-list');
|
||||||
createButton.addEventListener('click', function() {
|
const transitionsList = document.getElementById('transitions-list');
|
||||||
modalTitle.textContent = 'Create Process';
|
const initialStatusSelect = document.getElementById('initialStatus');
|
||||||
form.action = '_save_process_definition.php';
|
const fromStatusSelect = document.getElementById('fromStatusSelect');
|
||||||
processIdInput.value = '';
|
const toStatusSelect = document.getElementById('toStatusSelect');
|
||||||
processNameInput.value = '';
|
|
||||||
definitionJsonTextarea.value = '';
|
|
||||||
});
|
|
||||||
|
|
||||||
// Handle edit button click
|
statusesList.innerHTML = '';
|
||||||
document.querySelectorAll('.edit-process-btn').forEach(button => {
|
transitionsList.innerHTML = '';
|
||||||
button.addEventListener('click', function() {
|
initialStatusSelect.innerHTML = '';
|
||||||
const processId = this.dataset.processId;
|
fromStatusSelect.innerHTML = '';
|
||||||
const processName = this.dataset.processName;
|
toStatusSelect.innerHTML = '';
|
||||||
const processDefinition = this.dataset.processDefinition;
|
|
||||||
|
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';
|
modalTitle.textContent = 'Edit Process';
|
||||||
form.action = '_save_process_definition.php';
|
form.action = '_save_process_definition.php';
|
||||||
@ -150,9 +201,15 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
processNameInput.value = processName;
|
processNameInput.value = processName;
|
||||||
definitionJsonTextarea.value = processDefinition;
|
definitionJsonTextarea.value = processDefinition;
|
||||||
|
|
||||||
const modal = new bootstrap.Modal(createProcessModal);
|
renderProcessDefinition(processDefinition);
|
||||||
modal.show();
|
} else {
|
||||||
});
|
modalTitle.textContent = 'Create Process';
|
||||||
|
form.action = '_save_process_definition.php';
|
||||||
|
processIdInput.value = '';
|
||||||
|
processNameInput.value = '';
|
||||||
|
definitionJsonTextarea.value = '';
|
||||||
|
renderProcessDefinition(''); // Clear the form
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</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