Commit 6bfad320 authored by Mahmoud Aglan's avatar Mahmoud Aglan

Coool

parent 0f1cba7f
...@@ -131,4 +131,74 @@ class WorkflowController extends Controller ...@@ -131,4 +131,74 @@ class WorkflowController extends Controller
$count = count($processed); $count = count($processed);
return $this->redirect('/workflows')->withSuccess("تم معالجة {$count} انتقال تلقائي"); return $this->redirect('/workflows')->withSuccess("تم معالجة {$count} انتقال تلقائي");
} }
public function edit(Request $request, string $code): Response
{
$definition = WorkflowDefinition::findByCode($code);
if (!$definition) {
return $this->redirect('/workflows')->withError('تعريف دورة العمل غير موجود');
}
return $this->view('Workflow.Views.edit', [
'definition' => $definition,
]);
}
public function update(Request $request, string $code): Response
{
$db = App::getInstance()->db();
$definition = WorkflowDefinition::findByCode($code);
if (!$definition) {
return $this->redirect('/workflows')->withError('تعريف دورة العمل غير موجود');
}
$nameAr = trim((string) $request->post('name_ar', ''));
$nameEn = trim((string) $request->post('name_en', ''));
$descriptionAr = trim((string) $request->post('description_ar', ''));
if ($nameAr === '') {
return $this->redirect("/workflows/edit/{$code}")->withError('الاسم بالعربي مطلوب');
}
$defJson = $definition->getDefinition();
// Update state labels
$statesInput = $request->post('states', []);
if (is_array($statesInput)) {
foreach ($statesInput as $key => $stateData) {
if (isset($defJson['states'][$key])) {
if (!empty($stateData['label_ar'])) {
$defJson['states'][$key]['label_ar'] = trim($stateData['label_ar']);
}
if (!empty($stateData['label_en'])) {
$defJson['states'][$key]['label_en'] = trim($stateData['label_en']);
}
}
}
}
// Update transition triggers
$transitionsInput = $request->post('transitions', []);
if (is_array($transitionsInput)) {
foreach ($transitionsInput as $idx => $tData) {
if (isset($defJson['transitions'][$idx]) && !empty($tData['trigger_edit'])) {
$defJson['transitions'][$idx]['trigger'] = $tData['trigger_edit'];
}
}
}
$newVersion = (int) $definition->version + 1;
$db->update('workflow_definitions', [
'name_ar' => $nameAr,
'name_en' => $nameEn ?: null,
'description_ar' => $descriptionAr ?: null,
'definition_json' => json_encode($defJson, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
'version' => $newVersion,
'updated_at' => date('Y-m-d H:i:s'),
], '`id` = ?', [(int) $definition->id]);
return $this->redirect("/workflows/diagram/{$code}")->withSuccess('تم تحديث دورة العمل — الإصدار ' . $newVersion);
}
} }
\ No newline at end of file
...@@ -4,8 +4,10 @@ declare(strict_types=1); ...@@ -4,8 +4,10 @@ declare(strict_types=1);
return [ return [
['GET', '/workflows', 'Workflow\Controllers\WorkflowController@index', ['auth', 'csrf'], 'rules.view'], ['GET', '/workflows', 'Workflow\Controllers\WorkflowController@index', ['auth', 'csrf'], 'rules.view'],
['GET', '/workflows/diagram/{code}', 'Workflow\Controllers\WorkflowController@diagram', ['auth', 'csrf'], 'rules.view'], ['GET', '/workflows/diagram/{code}', 'Workflow\Controllers\WorkflowController@diagram', ['auth', 'csrf'], 'rules.view'],
['GET', '/workflows/instances/{code}', 'Workflow\Controllers\WorkflowController@instances', ['auth', 'csrf'], 'rules.view'], ['GET', '/workflows/edit/{code}', 'Workflow\Controllers\WorkflowController@edit', ['auth', 'csrf'], 'rules.edit'],
['POST', '/workflows/edit/{code}', 'Workflow\Controllers\WorkflowController@update', ['auth', 'csrf'], 'rules.edit'],
['GET', '/workflows/instances/{id:\d+}', 'Workflow\Controllers\WorkflowController@instance', ['auth', 'csrf'], 'rules.view'], ['GET', '/workflows/instances/{id:\d+}', 'Workflow\Controllers\WorkflowController@instance', ['auth', 'csrf'], 'rules.view'],
['POST', '/workflows/instances/{id:\d+}/transition','Workflow\Controllers\WorkflowController@transition', ['auth', 'csrf'], 'rules.edit'], ['POST', '/workflows/instances/{id:\d+}/transition','Workflow\Controllers\WorkflowController@transition', ['auth', 'csrf'], 'rules.edit'],
['GET', '/workflows/instances/{code}', 'Workflow\Controllers\WorkflowController@instances', ['auth', 'csrf'], 'rules.view'],
['POST', '/workflows/process-timeouts', 'Workflow\Controllers\WorkflowController@processTimeouts', ['auth', 'csrf'], 'rules.edit'], ['POST', '/workflows/process-timeouts', 'Workflow\Controllers\WorkflowController@processTimeouts', ['auth', 'csrf'], 'rules.edit'],
]; ];
\ No newline at end of file
...@@ -2,8 +2,9 @@ ...@@ -2,8 +2,9 @@
<?php $__template->section('title'); ?>مخطط: <?= e($definition->name_ar) ?><?php $__template->endSection(); ?> <?php $__template->section('title'); ?>مخطط: <?= e($definition->name_ar) ?><?php $__template->endSection(); ?>
<?php $__template->section('page_actions'); ?> <?php $__template->section('page_actions'); ?>
<a href="/workflows" class="btn btn-outline">← العودة</a> <a href="/workflows" class="btn btn-outline">العودة</a>
<a href="/workflows/instances/<?= e($definition->workflow_code) ?>" class="btn btn-outline">عرض المثيلات</a> <a href="/workflows/instances/<?= e($definition->workflow_code) ?>" class="btn btn-outline">المثيلات</a>
<a href="/workflows/edit/<?= e($definition->workflow_code) ?>" class="btn btn-primary">تعديل دورة العمل</a>
<?php $__template->endSection(); ?> <?php $__template->endSection(); ?>
<?php $__template->section('content'); ?> <?php $__template->section('content'); ?>
...@@ -12,58 +13,71 @@ ...@@ -12,58 +13,71 @@
$transitions = $definition->getTransitions(); $transitions = $definition->getTransitions();
?> ?>
<!-- Definition Header -->
<div class="card" style="margin-bottom:20px;padding:20px;"> <div class="card" style="margin-bottom:20px;padding:20px;">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:20px;"> <div style="display:flex;justify-content:space-between;align-items:center;">
<div> <div>
<h2 style="margin:0;color:#0D7377;"><?= e($definition->name_ar) ?></h2> <h2 style="margin:0 0 4px;color:#1A1A2E;font-size:20px;"><?= e($definition->name_ar) ?></h2>
<p style="color:#6B7280;margin:5px 0 0;"><?= e($definition->description_ar ?? '') ?></p> <?php if ($definition->description_ar): ?>
<p style="color:#6B7280;font-size:14px;margin:0;"><?= e($definition->description_ar) ?></p>
<?php endif; ?>
</div> </div>
<div style="text-align:left;"> <div style="text-align:left;">
<code style="font-size:12px;color:#9CA3AF;"><?= e($definition->workflow_code) ?></code><br> <span style="font-family:monospace;font-size:12px;color:#9CA3AF;background:#F3F4F6;padding:4px 8px;border-radius:4px;"><?= e($definition->workflow_code) ?></span>
<small style="color:#6B7280;">الإصدار <?= (int) $definition->version ?></small> <div style="font-size:12px;color:#6B7280;margin-top:4px;">الإصدار <?= (int) $definition->version ?> &middot; <?= count($states) ?> حالات &middot; <?= count($transitions) ?> انتقالات</div>
</div> </div>
</div> </div>
</div>
<!-- State Diagram (CSS-based flowchart) --> <!-- Visual Flowchart -->
<div style="display:flex;flex-wrap:wrap;gap:20px;justify-content:center;padding:30px 0;"> <div class="card" style="margin-bottom:20px;">
<?php foreach ($states as $key => $state): ?> <div style="padding:16px 20px;border-bottom:1px solid #E5E7EB;">
<?php <h3 style="margin:0;color:#1A1A2E;font-size:15px;">مخطط الحالات</h3>
$type = $state['type'] ?? 'intermediate'; </div>
$bgColor = match($type) { <div style="padding:30px;overflow-x:auto;">
'initial' => '#EFF6FF', <div style="display:flex;flex-wrap:wrap;gap:16px;justify-content:center;align-items:center;min-height:200px;">
'terminal' => '#FEF2F2', <?php foreach ($states as $key => $state): ?>
'intermediate' => '#FFFFFF', <?php
default => '#F9FAFB', $type = $state['type'] ?? 'intermediate';
}; $bgColor = match($type) {
$borderColor = match($type) { 'initial' => '#EFF6FF',
'initial' => '#0284C7', 'terminal' => '#FEF2F2',
'terminal' => '#DC2626', 'intermediate' => '#FFFFFF',
'intermediate' => '#0D7377', default => '#F9FAFB',
default => '#E5E7EB', };
}; $borderColor = match($type) {
$shape = match($type) { 'initial' => '#0284C7',
'initial' => 'border-radius:50%;width:120px;height:120px;', 'terminal' => '#DC2626',
'terminal' => 'border-radius:8px;border-width:3px;', 'intermediate' => '#0D7377',
default => 'border-radius:8px;', default => '#E5E7EB',
}; };
?> $iconColor = match($type) {
<div id="state-<?= e($key) ?>" style="background:<?= $bgColor ?>;border:2px solid <?= $borderColor ?>;padding:15px 20px;text-align:center;min-width:140px;<?= $shape ?>display:flex;flex-direction:column;align-items:center;justify-content:center;"> 'initial' => '#0284C7',
<div style="font-weight:700;color:#1A1A2E;font-size:14px;"><?= e($state['label_ar'] ?? $key) ?></div> 'terminal' => '#DC2626',
<div style="font-size:10px;color:#9CA3AF;margin-top:4px;"><?= e($key) ?></div> default => '#0D7377',
<?php if ($type === 'initial'): ?> };
<div style="font-size:10px;color:#0284C7;margin-top:2px;">▶ بداية</div> $borderRadius = ($type === 'initial') ? '50%' : (($type === 'terminal') ? '8px' : '12px');
<?php elseif ($type === 'terminal'): ?> $borderWidth = ($type === 'terminal') ? '3px' : '2px';
<div style="font-size:10px;color:#DC2626;margin-top:2px;">■ نهاية</div> $size = ($type === 'initial') ? 'width:130px;height:130px;' : 'min-width:140px;padding:18px 22px;';
<?php endif; ?> ?>
<div style="background:<?= $bgColor ?>;border:<?= $borderWidth ?> solid <?= $borderColor ?>;border-radius:<?= $borderRadius ?>;<?= $size ?>text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center;box-shadow:0 2px 8px rgba(0,0,0,0.04);transition:transform 0.2s,box-shadow 0.2s;">
<div style="font-weight:700;color:#1A1A2E;font-size:14px;margin-bottom:4px;"><?= e($state['label_ar'] ?? $key) ?></div>
<div style="font-size:10px;color:#9CA3AF;font-family:monospace;"><?= e($key) ?></div>
<?php if ($type === 'initial'): ?>
<div style="font-size:10px;color:<?= $iconColor ?>;margin-top:4px;font-weight:600;">&#9654; بداية</div>
<?php elseif ($type === 'terminal'): ?>
<div style="font-size:10px;color:<?= $iconColor ?>;margin-top:4px;font-weight:600;">&#9632; نهاية</div>
<?php endif; ?>
</div>
<?php endforeach; ?>
</div> </div>
<?php endforeach; ?>
</div> </div>
</div> </div>
<!-- Transition Table --> <!-- Transitions Table -->
<div class="card"> <div class="card" style="margin-bottom:20px;">
<div style="padding:15px 20px;border-bottom:1px solid #E5E7EB;"> <div style="padding:16px 20px;border-bottom:1px solid #E5E7EB;">
<h3 style="margin:0;color:#0D7377;">جدول الانتقالات</h3> <h3 style="margin:0;color:#1A1A2E;font-size:15px;">جدول الانتقالات (<?= count($transitions) ?>)</h3>
</div> </div>
<div class="table-responsive"> <div class="table-responsive">
<table class="data-table"> <table class="data-table">
...@@ -71,6 +85,7 @@ ...@@ -71,6 +85,7 @@
<tr> <tr>
<th>اسم الانتقال</th> <th>اسم الانتقال</th>
<th>من</th> <th>من</th>
<th></th>
<th>إلى</th> <th>إلى</th>
<th>النوع</th> <th>النوع</th>
<th>الشروط</th> <th>الشروط</th>
...@@ -83,71 +98,92 @@ ...@@ -83,71 +98,92 @@
$fromState = $states[$t['from']] ?? []; $fromState = $states[$t['from']] ?? [];
$toState = $states[$t['to']] ?? []; $toState = $states[$t['to']] ?? [];
$trigger = $t['trigger'] ?? 'manual'; $trigger = $t['trigger'] ?? 'manual';
$guards = $t['guards'] ?? [];
$actions = $t['actions'] ?? [];
?> ?>
<tr> <tr>
<td style="font-weight:600;"><?= e($t['name']) ?></td>
<td> <td>
<span style="color:#DC2626;font-size:13px;"><?= e($fromState['label_ar'] ?? $t['from']) ?></span> <span style="font-weight:700;color:#1A1A2E;"><?= e($t['name']) ?></span>
</td>
<td>
<span style="background:#FEF2F2;color:#DC2626;padding:3px 8px;border-radius:4px;font-size:12px;font-weight:600;"><?= e($fromState['label_ar'] ?? $t['from']) ?></span>
</td> </td>
<td style="text-align:center;color:#9CA3AF;font-size:16px;">&#8592;</td>
<td> <td>
<span style="color:#059669;font-size:13px;"><?= e($toState['label_ar'] ?? $t['to']) ?></span> <span style="background:#F0FDF4;color:#059669;padding:3px 8px;border-radius:4px;font-size:12px;font-weight:600;"><?= e($toState['label_ar'] ?? $t['to']) ?></span>
</td> </td>
<td> <td>
<span style="background:<?= $trigger === 'automatic' ? '#FFF7ED' : '#F0FDF4' ?>;color:<?= $trigger === 'automatic' ? '#D97706' : '#059669' ?>;padding:2px 8px;border-radius:4px;font-size:12px;"> <?php if ($trigger === 'automatic'): ?>
<?= $trigger === 'automatic' ? 'تلقائي' : 'يدوي' ?> <span style="background:#FFF7ED;color:#D97706;padding:3px 10px;border-radius:4px;font-size:12px;font-weight:600;">تلقائي</span>
</span> <?php else: ?>
<span style="background:#F0FDF4;color:#059669;padding:3px 10px;border-radius:4px;font-size:12px;font-weight:600;">يدوي</span>
<?php endif; ?>
</td> </td>
<td style="font-size:12px;"> <td style="font-size:12px;">
<?php $guards = $t['guards'] ?? []; ?>
<?php if (empty($guards)): ?> <?php if (empty($guards)): ?>
<span style="color:#9CA3AF;">بدون شروط</span> <span style="color:#D1D5DB;">&#8212;</span>
<?php else: ?> <?php else: ?>
<?php foreach ($guards as $g): ?> <?php foreach ($guards as $g): ?>
<div style="margin-bottom:2px;"> <div style="margin-bottom:3px;display:flex;align-items:center;gap:4px;">
<code style="font-size:11px;background:#F3F4F6;padding:1px 4px;border-radius:2px;"><?= e($g['type'] ?? '') ?></code> <span style="background:#F3F4F6;padding:2px 6px;border-radius:3px;font-family:monospace;font-size:11px;"><?= e($g['type'] ?? '') ?></span>
<span style="color:#6B7280;"><?= e(is_array($g['value'] ?? '') ? json_encode($g['value']) : (string)($g['value'] ?? '')) ?></span> <span style="color:#6B7280;"><?= e(is_array($g['value'] ?? '') ? json_encode($g['value']) : (string)($g['value'] ?? '')) ?></span>
<?php if (isset($g['days'])): ?><span style="color:#D97706;"><?= (int) $g['days'] ?> يوم</span><?php endif; ?> <?php if (isset($g['days'])): ?>
</div> <span style="color:#D97706;font-weight:600;"><?= (int) $g['days'] ?> يوم</span>
<?php endif; ?>
</div>
<?php endforeach; ?> <?php endforeach; ?>
<?php endif; ?> <?php endif; ?>
</td> </td>
<td style="font-size:12px;"> <td style="font-size:12px;">
<?php $actions = $t['actions'] ?? []; ?>
<?php if (empty($actions)): ?> <?php if (empty($actions)): ?>
<span style="color:#9CA3AF;"></span> <span style="color:#D1D5DB;">&#8212;</span>
<?php else: ?> <?php else: ?>
<?php foreach ($actions as $a): ?> <?php foreach ($actions as $a): ?>
<div><code style="font-size:11px;"><?= e($a['type'] ?? '') ?>: <?= e($a['value'] ?? '') ?></code></div> <div style="margin-bottom:3px;">
<span style="background:#EFF6FF;padding:2px 6px;border-radius:3px;font-family:monospace;font-size:11px;color:#0284C7;"><?= e($a['type'] ?? '') ?></span>
<span style="color:#6B7280;"><?= e($a['value'] ?? '') ?></span>
</div>
<?php endforeach; ?> <?php endforeach; ?>
<?php endif; ?> <?php endif; ?>
</td> </td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
<?php if (empty($transitions)): ?>
<tr><td colspan="7" style="text-align:center;padding:40px;color:#9CA3AF;">لا توجد انتقالات مُعرّفة</td></tr>
<?php endif; ?>
</tbody> </tbody>
</table> </table>
</div> </div>
</div> </div>
<!-- States Summary --> <!-- States Summary Grid -->
<div class="card" style="margin-top:20px;"> <div class="card">
<div style="padding:15px 20px;border-bottom:1px solid #E5E7EB;"> <div style="padding:16px 20px;border-bottom:1px solid #E5E7EB;">
<h3 style="margin:0;color:#0D7377;">ملخص الحالات (<?= count($states) ?>)</h3> <h3 style="margin:0;color:#1A1A2E;font-size:15px;">الحالات (<?= count($states) ?>)</h3>
</div> </div>
<div style="padding:20px;display:grid;grid-template-columns:repeat(auto-fill, minmax(200px, 1fr));gap:10px;"> <div style="padding:20px;display:grid;grid-template-columns:repeat(auto-fill, minmax(220px, 1fr));gap:12px;">
<?php foreach ($states as $key => $state): ?> <?php foreach ($states as $key => $state): ?>
<?php <?php
$type = $state['type'] ?? 'intermediate'; $type = $state['type'] ?? 'intermediate';
$color = match($type) { $leftBorderColor = match($type) {
'initial' => '#0284C7', 'initial' => '#0284C7',
'terminal' => '#DC2626', 'terminal' => '#DC2626',
default => '#0D7377', default => '#0D7377',
}; };
$typeLabel = match($type) {
'initial' => 'بداية',
'terminal' => 'نهاية',
default => 'وسيطة',
};
?> ?>
<div style="padding:10px 15px;border:1px solid #E5E7EB;border-right:4px solid <?= $color ?>;border-radius:6px;"> <div style="padding:12px 16px;border:1px solid #E5E7EB;border-right:4px solid <?= $leftBorderColor ?>;border-radius:6px;background:#FAFAFA;">
<div style="font-weight:600;color:#1A1A2E;"><?= e($state['label_ar'] ?? $key) ?></div> <div style="font-weight:700;color:#1A1A2E;font-size:14px;margin-bottom:2px;"><?= e($state['label_ar'] ?? $key) ?></div>
<div style="font-size:11px;color:#9CA3AF;"><?= e($key) ?> · <?= e($type) ?></div> <div style="display:flex;justify-content:space-between;align-items:center;">
<span style="font-size:11px;color:#9CA3AF;font-family:monospace;"><?= e($key) ?></span>
<span style="font-size:10px;color:<?= $leftBorderColor ?>;font-weight:600;"><?= $typeLabel ?></span>
</div>
</div> </div>
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
</div> </div>
<?php $__template->endSection(); ?> <?php $__template->endSection(); ?>
\ No newline at end of file
<?php $__template->layout('Layout.main'); ?>
<?php $__template->section('title'); ?>تعديل: <?= e($definition->name_ar) ?><?php $__template->endSection(); ?>
<?php $__template->section('page_actions'); ?>
<a href="/workflows/diagram/<?= e($definition->workflow_code) ?>" class="btn btn-outline">عرض المخطط</a>
<a href="/workflows" class="btn btn-outline">العودة</a>
<?php $__template->endSection(); ?>
<?php $__template->section('content'); ?>
<?php
$states = $definition->getStates();
$transitions = $definition->getTransitions();
?>
<!-- Basic Info -->
<form method="POST" action="/workflows/edit/<?= e($definition->workflow_code) ?>">
<?= csrf_field() ?>
<div class="card" style="margin-bottom:20px;">
<div style="padding:16px 20px;border-bottom:1px solid #E5E7EB;">
<h3 style="margin:0;color:#1A1A2E;font-size:15px;">المعلومات الأساسية</h3>
</div>
<div style="padding:20px;display:grid;grid-template-columns:1fr 1fr;gap:16px;">
<div class="form-group">
<label class="form-label">كود دورة العمل</label>
<input type="text" class="form-input" value="<?= e($definition->workflow_code) ?>" readonly style="background:#F3F4F6;font-family:monospace;">
</div>
<div class="form-group">
<label class="form-label">الإصدار</label>
<input type="text" class="form-input" value="v<?= (int) $definition->version ?>" readonly style="background:#F3F4F6;">
</div>
<div class="form-group">
<label class="form-label">الاسم بالعربي <span style="color:#DC2626;">*</span></label>
<input type="text" name="name_ar" class="form-input" value="<?= e($definition->name_ar) ?>" required>
</div>
<div class="form-group">
<label class="form-label">الاسم بالإنجليزي</label>
<input type="text" name="name_en" class="form-input" value="<?= e($definition->name_en ?? '') ?>" style="direction:ltr;text-align:left;">
</div>
<div class="form-group" style="grid-column:1/-1;">
<label class="form-label">الوصف</label>
<textarea name="description_ar" class="form-textarea" rows="2"><?= e($definition->description_ar ?? '') ?></textarea>
</div>
</div>
</div>
<!-- States Editor -->
<div class="card" style="margin-bottom:20px;">
<div style="padding:16px 20px;border-bottom:1px solid #E5E7EB;display:flex;justify-content:space-between;align-items:center;">
<h3 style="margin:0;color:#1A1A2E;font-size:15px;">الحالات (<?= count($states) ?>)</h3>
<span style="font-size:12px;color:#9CA3AF;">المفتاح غير قابل للتعديل — فقط التسميات</span>
</div>
<div style="padding:20px;">
<div style="display:grid;gap:10px;">
<?php foreach ($states as $key => $state): ?>
<?php
$type = $state['type'] ?? 'intermediate';
$leftColor = match($type) { 'initial' => '#0284C7', 'terminal' => '#DC2626', default => '#0D7377' };
?>
<div style="display:grid;grid-template-columns:180px 1fr 1fr 120px;gap:12px;align-items:center;padding:12px 16px;background:#FAFAFA;border:1px solid #E5E7EB;border-right:4px solid <?= $leftColor ?>;border-radius:6px;">
<div>
<span style="font-family:monospace;font-size:12px;background:#F3F4F6;padding:3px 8px;border-radius:4px;"><?= e($key) ?></span>
</div>
<div>
<input type="text" name="states[<?= e($key) ?>][label_ar]" class="form-input" value="<?= e($state['label_ar'] ?? $key) ?>" placeholder="التسمية بالعربي" style="font-size:13px;padding:6px 10px;">
</div>
<div>
<input type="text" name="states[<?= e($key) ?>][label_en]" class="form-input" value="<?= e($state['label_en'] ?? '') ?>" placeholder="Label (English)" style="font-size:13px;padding:6px 10px;direction:ltr;text-align:left;">
</div>
<div style="text-align:center;">
<span style="font-size:11px;color:<?= $leftColor ?>;font-weight:600;">
<?= match($type) { 'initial' => 'بداية', 'terminal' => 'نهاية', default => 'وسيطة' } ?>
</span>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
<!-- Transitions Editor -->
<div class="card" style="margin-bottom:20px;">
<div style="padding:16px 20px;border-bottom:1px solid #E5E7EB;">
<h3 style="margin:0;color:#1A1A2E;font-size:15px;">الانتقالات (<?= count($transitions) ?>)</h3>
</div>
<div class="table-responsive">
<table class="data-table" style="font-size:13px;">
<thead>
<tr>
<th style="width:160px;">اسم الانتقال</th>
<th>من</th>
<th>إلى</th>
<th style="width:100px;">النوع</th>
<th>الشروط</th>
<th>الإجراءات</th>
</tr>
</thead>
<tbody>
<?php foreach ($transitions as $idx => $t): ?>
<?php
$fromState = $states[$t['from']] ?? [];
$toState = $states[$t['to']] ?? [];
$trigger = $t['trigger'] ?? 'manual';
$guards = $t['guards'] ?? [];
$actions = $t['actions'] ?? [];
?>
<tr>
<td>
<input type="hidden" name="transitions[<?= $idx ?>][name]" value="<?= e($t['name']) ?>">
<input type="hidden" name="transitions[<?= $idx ?>][from]" value="<?= e($t['from']) ?>">
<input type="hidden" name="transitions[<?= $idx ?>][to]" value="<?= e($t['to']) ?>">
<input type="hidden" name="transitions[<?= $idx ?>][trigger]" value="<?= e($trigger) ?>">
<input type="hidden" name="transitions[<?= $idx ?>][guards_json]" value="<?= e(json_encode($guards, JSON_UNESCAPED_UNICODE)) ?>">
<input type="hidden" name="transitions[<?= $idx ?>][actions_json]" value="<?= e(json_encode($actions, JSON_UNESCAPED_UNICODE)) ?>">
<span style="font-weight:700;"><?= e($t['name']) ?></span>
</td>
<td>
<span style="background:#FEF2F2;color:#DC2626;padding:3px 8px;border-radius:4px;font-size:12px;"><?= e($fromState['label_ar'] ?? $t['from']) ?></span>
</td>
<td>
<span style="background:#F0FDF4;color:#059669;padding:3px 8px;border-radius:4px;font-size:12px;"><?= e($toState['label_ar'] ?? $t['to']) ?></span>
</td>
<td>
<select name="transitions[<?= $idx ?>][trigger_edit]" style="font-size:12px;padding:4px 8px;border:1px solid #E5E7EB;border-radius:4px;background:#fff;">
<option value="manual" <?= $trigger === 'manual' ? 'selected' : '' ?>>يدوي</option>
<option value="automatic" <?= $trigger === 'automatic' ? 'selected' : '' ?>>تلقائي</option>
</select>
</td>
<td style="font-size:11px;">
<?php if (empty($guards)): ?>
<span style="color:#D1D5DB;">بدون</span>
<?php else: ?>
<?php foreach ($guards as $g): ?>
<div style="margin-bottom:2px;">
<span style="background:#F3F4F6;padding:1px 5px;border-radius:3px;font-family:monospace;"><?= e($g['type'] ?? '') ?></span>
<?php if (isset($g['days'])): ?><span style="color:#D97706;"><?= (int) $g['days'] ?>d</span><?php endif; ?>
</div>
<?php endforeach; ?>
<?php endif; ?>
</td>
<td style="font-size:11px;">
<?php if (empty($actions)): ?>
<span style="color:#D1D5DB;">&#8212;</span>
<?php else: ?>
<?php foreach ($actions as $a): ?>
<div><span style="font-family:monospace;"><?= e(($a['type'] ?? '') . ':' . ($a['value'] ?? '')) ?></span></div>
<?php endforeach; ?>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<!-- Save Actions -->
<div style="display:flex;gap:10px;justify-content:space-between;align-items:center;">
<div style="display:flex;gap:10px;">
<button type="submit" class="btn btn-primary" style="padding:12px 30px;">حفظ التعديلات</button>
<a href="/workflows/diagram/<?= e($definition->workflow_code) ?>" class="btn btn-outline" style="padding:12px 20px;">إلغاء</a>
</div>
<div style="font-size:12px;color:#9CA3AF;">
سيتم زيادة رقم الإصدار تلقائياً عند الحفظ
</div>
</div>
</form>
<?php $__template->endSection(); ?>
<?php $__template->layout('Layout.main'); ?> <?php $__template->layout('Layout.main'); ?>
<?php $__template->section('title'); ?>محرك دورات العمل<?php $__template->endSection(); ?> <?php $__template->section('title'); ?>دورات العمل<?php $__template->endSection(); ?>
<?php $__template->section('page_actions'); ?> <?php $__template->section('page_actions'); ?>
<form method="POST" action="/workflows/process-timeouts" style="display:inline;"> <form method="POST" action="/workflows/process-timeouts" style="display:inline;">
<?= csrf_field() ?> <?= csrf_field() ?>
<button type="submit" class="btn btn-outline" onclick="return confirm('هل تريد معالجة الانتقالات التلقائية المنتهية؟')">⏱ معالجة المهلات المنتهية</button> <button type="submit" class="btn btn-outline" onclick="return confirm('هل تريد معالجة جميع الانتقالات التلقائية المنتهية المهلة؟')">
معالجة المهلات المنتهية
</button>
</form> </form>
<?php $__template->endSection(); ?> <?php $__template->endSection(); ?>
<?php $__template->section('content'); ?> <?php $__template->section('content'); ?>
<!-- Workflow Definitions Overview -->
<div style="display:grid;grid-template-columns:repeat(auto-fill, minmax(300px, 1fr));gap:20px;margin-bottom:30px;">
<?php foreach ($definitions as $def): ?>
<?php $s = $stats[$def['workflow_code']] ?? ['active' => 0, 'completed' => 0]; ?>
<div class="card" style="padding:20px;">
<div style="display:flex;justify-content:space-between;align-items:start;margin-bottom:15px;">
<div>
<h3 style="margin:0;color:#1A1A2E;"><?= e($def['name_ar']) ?></h3>
<code style="font-size:11px;color:#9CA3AF;"><?= e($def['workflow_code']) ?></code>
</div>
<span style="background:#F3F4F6;padding:2px 8px;border-radius:4px;font-size:12px;">v<?= (int) $def['version'] ?></span>
</div>
<p style="color:#6B7280;font-size:13px;margin-bottom:15px;"><?= e($def['description_ar'] ?? '') ?></p>
<div style="display:flex;gap:15px;margin-bottom:15px;">
<div style="text-align:center;">
<div style="font-size:24px;font-weight:700;color:#0D7377;"><?= $s['active'] ?></div>
<div style="font-size:11px;color:#6B7280;">نشط</div>
</div>
<div style="text-align:center;">
<div style="font-size:24px;font-weight:700;color:#059669;"><?= $s['completed'] ?></div>
<div style="font-size:11px;color:#6B7280;">مكتمل</div>
</div>
</div>
<div style="display:flex;gap:8px;">
<a href="/workflows/diagram/<?= e($def['workflow_code']) ?>" class="btn btn-sm btn-outline">المخطط</a>
<a href="/workflows/instances/<?= e($def['workflow_code']) ?>" class="btn btn-sm btn-outline">المثيلات</a>
<a href="/workflows/instances/<?= e($def['workflow_code']) ?>?status=active" class="btn btn-sm btn-outline" style="color:#D97706;">النشطة</a>
</div>
</div>
<?php endforeach; ?>
</div>
<!-- Filtered Instances (if viewing specific workflow) -->
<?php if (!empty($filteredInstances)): ?> <?php if (!empty($filteredInstances)): ?>
<div class="card"> <!-- Filtered Instances View -->
<div style="padding:15px 20px;border-bottom:1px solid #E5E7EB;display:flex;justify-content:space-between;align-items:center;"> <div class="card" style="margin-bottom:20px;">
<h3 style="margin:0;color:#0D7377;"> <div style="padding:20px;border-bottom:1px solid #E5E7EB;display:flex;justify-content:space-between;align-items:center;">
مثيلات: <?= e($currentDef ? $currentDef->name_ar : ($filterCode ?? '')) ?> <div>
<h2 style="margin:0;color:#1A1A2E;font-size:18px;">
<?= e($currentDef ? $currentDef->name_ar : ($filterCode ?? '')) ?>
</h2>
<?php if (!empty($filterStatus)): ?> <?php if (!empty($filterStatus)): ?>
<span style="font-size:14px;color:#6B7280;">(<?= $filterStatus === 'active' ? 'نشطة' : ($filterStatus === 'completed' ? 'مكتملة' : 'الكل') ?>)</span> <span style="font-size:13px;color:#6B7280;margin-top:4px;display:block;">
عرض: <?= $filterStatus === 'active' ? 'المثيلات النشطة' : ($filterStatus === 'completed' ? 'المثيلات المكتملة' : 'جميع المثيلات') ?>
</span>
<?php endif; ?>
</div>
<div style="display:flex;gap:8px;">
<?php if (!empty($filterCode)): ?>
<a href="/workflows/instances/<?= e($filterCode) ?>" class="btn btn-sm <?= empty($filterStatus) ? 'btn-primary' : 'btn-outline' ?>">الكل</a>
<a href="/workflows/instances/<?= e($filterCode) ?>?status=active" class="btn btn-sm <?= ($filterStatus ?? '') === 'active' ? 'btn-primary' : 'btn-outline' ?>">نشطة</a>
<a href="/workflows/instances/<?= e($filterCode) ?>?status=completed" class="btn btn-sm <?= ($filterStatus ?? '') === 'completed' ? 'btn-primary' : 'btn-outline' ?>">مكتملة</a>
<?php endif; ?> <?php endif; ?>
</h3> <a href="/workflows" class="btn btn-sm btn-outline">العودة للنظرة العامة</a>
<a href="/workflows" class="btn btn-sm btn-outline">← العودة</a> </div>
</div> </div>
<div class="table-responsive"> <div class="table-responsive">
<table class="data-table"> <table class="data-table">
<thead> <thead>
<tr> <tr>
<th>#</th> <th style="width:60px;">#</th>
<th>نوع الكيان</th> <th>نوع الكيان</th>
<th>رقم الكيان</th> <th>رقم الكيان</th>
<th>الحالة الحالية</th> <th>الحالة الحالية</th>
<th>دخول الحالة</th> <th>دخول الحالة</th>
<th>مكتمل</th> <th style="width:80px;">الوضع</th>
<th>الإجراءات</th> <th style="width:100px;">الإجراءات</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<?php if (empty($filteredInstances)): ?>
<tr><td colspan="7" style="text-align:center;padding:60px;color:#9CA3AF;font-size:15px;">لا توجد مثيلات مطابقة</td></tr>
<?php else: ?>
<?php foreach ($filteredInstances as $inst): ?> <?php foreach ($filteredInstances as $inst): ?>
<?php <?php
$stateLabel = $inst['current_state']; $stateLabel = $inst['current_state'];
...@@ -75,25 +59,33 @@ ...@@ -75,25 +59,33 @@
$states = $currentDef->getStates(); $states = $currentDef->getStates();
$stateLabel = $states[$inst['current_state']]['label_ar'] ?? $inst['current_state']; $stateLabel = $states[$inst['current_state']]['label_ar'] ?? $inst['current_state'];
} }
$isCompleted = (bool) $inst['is_completed'];
?> ?>
<tr> <tr>
<td><?= (int) $inst['id'] ?></td> <td style="font-weight:600;color:#6B7280;"><?= (int) $inst['id'] ?></td>
<td><code style="font-size:12px;"><?= e($inst['entity_type']) ?></code></td> <td>
<td><?= (int) $inst['entity_id'] ?></td> <span style="background:#F3F4F6;padding:3px 8px;border-radius:4px;font-size:12px;font-family:monospace;"><?= e($inst['entity_type']) ?></span>
</td>
<td style="font-weight:600;"><?= (int) $inst['entity_id'] ?></td>
<td> <td>
<span style="background:<?= $inst['is_completed'] ? '#F0FDF4' : '#FFF7ED' ?>;color:<?= $inst['is_completed'] ? '#059669' : '#D97706' ?>;padding:3px 10px;border-radius:4px;font-size:13px;font-weight:600;"> <span style="display:inline-flex;align-items:center;gap:6px;background:<?= $isCompleted ? '#F0FDF4' : '#FFF7ED' ?>;color:<?= $isCompleted ? '#059669' : '#92400E' ?>;padding:5px 12px;border-radius:6px;font-size:13px;font-weight:600;">
<span style="width:8px;height:8px;border-radius:50%;background:<?= $isCompleted ? '#059669' : '#D97706' ?>;"></span>
<?= e($stateLabel) ?> <?= e($stateLabel) ?>
</span> </span>
</td> </td>
<td style="font-size:12px;"><?= e($inst['state_entered_at']) ?></td> <td style="font-size:13px;color:#6B7280;"><?= e($inst['state_entered_at']) ?></td>
<td><?= $inst['is_completed'] ? '<span style="color:#059669;">✓</span>' : '<span style="color:#D97706;">—</span>' ?></td> <td style="text-align:center;">
<?php if ($isCompleted): ?>
<span style="color:#059669;font-size:18px;" title="مكتمل">&#10003;</span>
<?php else: ?>
<span style="color:#D97706;font-size:14px;" title="جارية">&#9679;</span>
<?php endif; ?>
</td>
<td> <td>
<a href="/workflows/instances/<?= (int) $inst['id'] ?>" class="btn btn-sm btn-outline">عرض</a> <a href="/workflows/instances/<?= (int) $inst['id'] ?>" class="btn btn-sm btn-primary">عرض التفاصيل</a>
</td> </td>
</tr> </tr>
<?php endforeach; ?> <?php endforeach; ?>
<?php if (empty($filteredInstances)): ?>
<tr><td colspan="7" style="text-align:center;padding:40px;color:#6B7280;">لا توجد مثيلات</td></tr>
<?php endif; ?> <?php endif; ?>
</tbody> </tbody>
</table> </table>
...@@ -101,4 +93,61 @@ ...@@ -101,4 +93,61 @@
</div> </div>
<?php endif; ?> <?php endif; ?>
<?php $__template->endSection(); ?> <!-- Workflow Definitions Dashboard -->
\ No newline at end of file <?php if (empty($filteredInstances)): ?>
<div style="display:grid;grid-template-columns:repeat(auto-fill, minmax(340px, 1fr));gap:20px;">
<?php foreach ($definitions as $def): ?>
<?php $s = $stats[$def['workflow_code']] ?? ['active' => 0, 'completed' => 0]; ?>
<?php $total = $s['active'] + $s['completed']; ?>
<div class="card" style="overflow:hidden;transition:box-shadow 0.2s;">
<!-- Card Header -->
<div style="padding:20px 20px 0;">
<div style="display:flex;justify-content:space-between;align-items:start;margin-bottom:8px;">
<div style="flex:1;">
<h3 style="margin:0 0 4px;color:#1A1A2E;font-size:16px;font-weight:700;"><?= e($def['name_ar']) ?></h3>
<span style="font-size:11px;color:#9CA3AF;font-family:monospace;background:#F9FAFB;padding:2px 6px;border-radius:3px;"><?= e($def['workflow_code']) ?></span>
</div>
<span style="background:#EFF6FF;color:#0284C7;padding:3px 8px;border-radius:4px;font-size:11px;font-weight:600;">v<?= (int) $def['version'] ?></span>
</div>
<?php if (!empty($def['description_ar'])): ?>
<p style="color:#6B7280;font-size:13px;margin:10px 0 0;line-height:1.5;"><?= e($def['description_ar']) ?></p>
<?php endif; ?>
</div>
<!-- Stats Bar -->
<div style="padding:16px 20px;margin-top:12px;display:flex;gap:24px;border-top:1px solid #F3F4F6;">
<div>
<div style="font-size:28px;font-weight:800;color:#D97706;line-height:1;"><?= $s['active'] ?></div>
<div style="font-size:11px;color:#6B7280;margin-top:2px;">نشطة</div>
</div>
<div>
<div style="font-size:28px;font-weight:800;color:#059669;line-height:1;"><?= $s['completed'] ?></div>
<div style="font-size:11px;color:#6B7280;margin-top:2px;">مكتملة</div>
</div>
<div>
<div style="font-size:28px;font-weight:800;color:#6B7280;line-height:1;"><?= $total ?></div>
<div style="font-size:11px;color:#6B7280;margin-top:2px;">الإجمالي</div>
</div>
</div>
<!-- Actions -->
<div style="padding:12px 20px 16px;display:flex;gap:8px;flex-wrap:wrap;">
<a href="/workflows/instances/<?= e($def['workflow_code']) ?>?status=active" class="btn btn-sm btn-primary">النشطة (<?= $s['active'] ?>)</a>
<a href="/workflows/diagram/<?= e($def['workflow_code']) ?>" class="btn btn-sm btn-outline">المخطط</a>
<a href="/workflows/edit/<?= e($def['workflow_code']) ?>" class="btn btn-sm btn-outline">تعديل</a>
<a href="/workflows/instances/<?= e($def['workflow_code']) ?>" class="btn btn-sm btn-outline">كل المثيلات</a>
</div>
</div>
<?php endforeach; ?>
<?php if (empty($definitions)): ?>
<div style="grid-column:1/-1;text-align:center;padding:80px 20px;color:#9CA3AF;">
<div style="font-size:48px;margin-bottom:15px;">&#128260;</div>
<h3 style="color:#6B7280;margin:0 0 8px;">لا توجد دورات عمل مُعرّفة</h3>
<p style="font-size:14px;margin:0;">أضف تعريفات دورات العمل من خلال قاعدة البيانات أو ملفات البذر</p>
</div>
<?php endif; ?>
</div>
<?php endif; ?>
<?php $__template->endSection(); ?>
...@@ -2,153 +2,226 @@ ...@@ -2,153 +2,226 @@
<?php $__template->section('title'); ?>مثيل دورة العمل #<?= (int) $instance->id ?><?php $__template->endSection(); ?> <?php $__template->section('title'); ?>مثيل دورة العمل #<?= (int) $instance->id ?><?php $__template->endSection(); ?>
<?php $__template->section('page_actions'); ?> <?php $__template->section('page_actions'); ?>
<a href="/workflows" class="btn btn-outline">← العودة</a> <a href="/workflows/instances/<?= e($instance->workflow_code) ?>" class="btn btn-outline">العودة للمثيلات</a>
<a href="/workflows/diagram/<?= e($instance->workflow_code) ?>" class="btn btn-outline">عرض المخطط</a> <a href="/workflows/diagram/<?= e($instance->workflow_code) ?>" class="btn btn-outline">المخطط</a>
<?php $__template->endSection(); ?> <?php $__template->endSection(); ?>
<?php $__template->section('content'); ?> <?php $__template->section('content'); ?>
<?php <?php
$states = $definition ? $definition->getStates() : []; $states = $definition ? $definition->getStates() : [];
$currentStateInfo = $states[$instance->current_state] ?? []; $currentStateInfo = $states[$instance->current_state] ?? [];
$stateType = $currentStateInfo['type'] ?? 'intermediate';
$isCompleted = (bool) $instance->is_completed;
?> ?>
<div style="display:grid;grid-template-columns:1fr 350px;gap:20px;"> <!-- Status Banner -->
<div style="padding:20px;margin-bottom:20px;border-radius:8px;background:<?= $isCompleted ? 'linear-gradient(135deg, #F0FDF4, #DCFCE7)' : 'linear-gradient(135deg, #EFF6FF, #DBEAFE)' ?>;border:1px solid <?= $isCompleted ? '#BBF7D0' : '#BFDBFE' ?>;">
<div style="display:flex;justify-content:space-between;align-items:center;">
<div style="display:flex;align-items:center;gap:15px;">
<div style="width:50px;height:50px;border-radius:50%;background:<?= $isCompleted ? '#059669' : '#0284C7' ?>;display:flex;align-items:center;justify-content:center;">
<span style="color:#fff;font-size:22px;font-weight:700;"><?= $isCompleted ? '&#10003;' : '&#9654;' ?></span>
</div>
<div>
<div style="font-size:13px;color:#6B7280;margin-bottom:2px;"><?= e($definition ? $definition->name_ar : $instance->workflow_code) ?></div>
<div style="font-size:22px;font-weight:800;color:#1A1A2E;"><?= e($currentStateInfo['label_ar'] ?? $instance->current_state) ?></div>
</div>
</div>
<div style="text-align:left;">
<div style="font-size:12px;color:#6B7280;">الكيان</div>
<div style="font-weight:600;font-size:14px;"><span style="font-family:monospace;background:#F3F4F6;padding:2px 8px;border-radius:4px;"><?= e($instance->entity_type) ?></span> #<?= (int) $instance->entity_id ?></div>
</div>
</div>
</div>
<div style="display:grid;grid-template-columns:1fr 380px;gap:20px;">
<!-- Main Content -->
<div> <div>
<!-- Instance Info --> <!-- Instance Details Card -->
<div class="card" style="margin-bottom:20px;"> <div class="card" style="margin-bottom:20px;">
<div style="padding:15px 20px;border-bottom:1px solid #E5E7EB;"> <div style="padding:16px 20px;border-bottom:1px solid #E5E7EB;">
<h3 style="margin:0;color:#0D7377;">معلومات المثيل</h3> <h3 style="margin:0;color:#1A1A2E;font-size:15px;">تفاصيل المثيل</h3>
</div> </div>
<div style="padding:20px;"> <div style="padding:20px;">
<table style="width:100%;font-size:14px;"> <div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;">
<tr><td style="padding:6px 0;color:#6B7280;width:35%;">دورة العمل</td><td style="padding:6px 0;font-weight:600;"><?= e($definition ? $definition->name_ar : $instance->workflow_code) ?></td></tr> <div style="padding:12px;background:#F9FAFB;border-radius:6px;">
<tr><td style="padding:6px 0;color:#6B7280;">نوع الكيان</td><td><code><?= e($instance->entity_type) ?></code></td></tr> <div style="font-size:11px;color:#9CA3AF;text-transform:uppercase;margin-bottom:4px;">دورة العمل</div>
<tr><td style="padding:6px 0;color:#6B7280;">رقم الكيان</td><td><?= (int) $instance->entity_id ?></td></tr> <div style="font-weight:600;color:#1A1A2E;"><?= e($definition ? $definition->name_ar : $instance->workflow_code) ?></div>
<tr> </div>
<td style="padding:6px 0;color:#6B7280;">الحالة الحالية</td> <div style="padding:12px;background:#F9FAFB;border-radius:6px;">
<td> <div style="font-size:11px;color:#9CA3AF;text-transform:uppercase;margin-bottom:4px;">الإصدار</div>
<span style="background:<?= $instance->is_completed ? '#F0FDF4' : '#EFF6FF' ?>;color:<?= $instance->is_completed ? '#059669' : '#0284C7' ?>;padding:4px 12px;border-radius:6px;font-weight:700;font-size:15px;"> <div style="font-weight:600;color:#1A1A2E;">v<?= (int) ($definition ? $definition->version : 1) ?></div>
<?= e($currentStateInfo['label_ar'] ?? $instance->current_state) ?> </div>
</span> <div style="padding:12px;background:#F9FAFB;border-radius:6px;">
</td> <div style="font-size:11px;color:#9CA3AF;text-transform:uppercase;margin-bottom:4px;">دخول الحالة</div>
</tr> <div style="font-weight:600;color:#1A1A2E;font-size:13px;"><?= e($instance->state_entered_at) ?></div>
<tr><td style="padding:6px 0;color:#6B7280;">دخول الحالة</td><td><?= e($instance->state_entered_at) ?></td></tr> </div>
<tr><td style="padding:6px 0;color:#6B7280;">تاريخ الإنشاء</td><td><?= e($instance->created_at) ?></td></tr> <div style="padding:12px;background:#F9FAFB;border-radius:6px;">
<tr> <div style="font-size:11px;color:#9CA3AF;text-transform:uppercase;margin-bottom:4px;">تاريخ الإنشاء</div>
<td style="padding:6px 0;color:#6B7280;">مكتمل</td> <div style="font-weight:600;color:#1A1A2E;font-size:13px;"><?= e($instance->created_at) ?></div>
<td> </div>
<?php if ($instance->is_completed): ?> <?php if ($isCompleted): ?>
<span style="color:#059669;font-weight:600;">✓ نعم — <?= e($instance->completed_at) ?></span> <div style="padding:12px;background:#F0FDF4;border-radius:6px;grid-column:1/-1;">
<?php else: ?> <div style="font-size:11px;color:#059669;text-transform:uppercase;margin-bottom:4px;">تاريخ الاكتمال</div>
<span style="color:#D97706;">جارية</span> <div style="font-weight:600;color:#059669;"><?= e($instance->completed_at) ?></div>
<?php endif; ?> </div>
</td> <?php endif; ?>
</tr> </div>
</table>
</div> </div>
</div> </div>
<!-- Transition History --> <!-- Transition History Timeline -->
<div class="card"> <div class="card">
<div style="padding:15px 20px;border-bottom:1px solid #E5E7EB;"> <div style="padding:16px 20px;border-bottom:1px solid #E5E7EB;display:flex;justify-content:space-between;align-items:center;">
<h3 style="margin:0;color:#0D7377;">سجل الانتقالات</h3> <h3 style="margin:0;color:#1A1A2E;font-size:15px;">سجل الانتقالات</h3>
<span style="font-size:12px;color:#9CA3AF;"><?= count($history) ?> انتقال</span>
</div> </div>
<div style="padding:20px;"> <div style="padding:20px;">
<?php if (empty($history)): ?> <?php if (empty($history)): ?>
<div style="text-align:center;padding:30px;color:#6B7280;">لا توجد انتقالات مسجلة</div> <div style="text-align:center;padding:40px;color:#9CA3AF;">
<div style="font-size:32px;margin-bottom:10px;">&#128203;</div>
<p style="margin:0;">لا توجد انتقالات مسجلة بعد</p>
</div>
<?php else: ?> <?php else: ?>
<?php foreach ($history as $i => $h): ?> <div style="position:relative;padding-right:20px;">
<?php <!-- Timeline line -->
$fromInfo = $states[$h['from_state']] ?? []; <div style="position:absolute;right:7px;top:8px;bottom:8px;width:2px;background:#E5E7EB;"></div>
$toInfo = $states[$h['to_state']] ?? [];
?> <?php foreach ($history as $i => $h): ?>
<div style="display:flex;gap:15px;padding:15px 0;<?= $i < count($history) - 1 ? 'border-bottom:1px solid #F3F4F6;' : '' ?>"> <?php
<div style="flex-shrink:0;width:10px;position:relative;"> $fromInfo = $states[$h['from_state']] ?? [];
<div style="width:10px;height:10px;border-radius:50%;background:#0D7377;margin-top:5px;"></div> $toInfo = $states[$h['to_state']] ?? [];
<?php if ($i < count($history) - 1): ?> $isLast = ($i === count($history) - 1);
<div style="position:absolute;top:15px;right:4px;width:2px;height:calc(100% + 15px);background:#E5E7EB;"></div> ?>
<?php endif; ?> <div style="position:relative;padding:0 0 <?= $isLast ? '0' : '24px' ?> 25px;">
</div> <!-- Timeline dot -->
<div style="flex:1;"> <div style="position:absolute;right:2px;top:6px;width:12px;height:12px;border-radius:50%;background:<?= $isLast ? '#0D7377' : '#D1D5DB' ?>;border:2px solid #fff;box-shadow:0 0 0 2px <?= $isLast ? '#0D7377' : '#E5E7EB' ?>;"></div>
<div style="display:flex;justify-content:space-between;margin-bottom:5px;">
<strong style="color:#1A1A2E;"><?= e($h['transition_name']) ?></strong> <div style="background:#F9FAFB;border-radius:8px;padding:14px 16px;border:1px solid #F3F4F6;">
<span style="color:#9CA3AF;font-size:12px;"><?= e($h['created_at']) ?></span> <div style="display:flex;justify-content:space-between;align-items:start;margin-bottom:8px;">
</div> <span style="font-weight:700;color:#1A1A2E;font-size:14px;"><?= e($h['transition_name']) ?></span>
<div style="font-size:13px;color:#6B7280;margin-bottom:4px;"> <span style="color:#9CA3AF;font-size:11px;white-space:nowrap;"><?= e($h['created_at']) ?></span>
<span style="color:#DC2626;"><?= e($fromInfo['label_ar'] ?? $h['from_state']) ?></span> </div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:6px;">
<span style="color:#059669;"><?= e($toInfo['label_ar'] ?? $h['to_state']) ?></span> <span style="background:#FEF2F2;color:#DC2626;padding:2px 8px;border-radius:4px;font-size:12px;font-weight:600;"><?= e($fromInfo['label_ar'] ?? $h['from_state']) ?></span>
</div> <span style="color:#9CA3AF;font-size:14px;">&#8592;</span>
<div style="font-size:12px;color:#9CA3AF;"> <span style="background:#F0FDF4;color:#059669;padding:2px 8px;border-radius:4px;font-size:12px;font-weight:600;"><?= e($toInfo['label_ar'] ?? $h['to_state']) ?></span>
<?= e($h['employee_name'] ?? 'النظام') ?> </div>
· <?= e($h['trigger_type']) ?> <div style="font-size:12px;color:#9CA3AF;">
<?= e($h['employee_name'] ?? 'النظام') ?>
&middot;
<span style="background:<?= ($h['trigger_type'] ?? '') === 'timeout' ? '#FFF7ED' : '#F3F4F6' ?>;padding:1px 6px;border-radius:3px;"><?= e($h['trigger_type'] ?? 'manual') ?></span>
</div>
<?php if (!empty($h['notes'])): ?>
<div style="margin-top:8px;font-size:13px;color:#4B5563;background:#fff;padding:8px 12px;border-radius:6px;border:1px solid #E5E7EB;line-height:1.5;"><?= e($h['notes']) ?></div>
<?php endif; ?>
</div> </div>
<?php if ($h['notes']): ?>
<div style="font-size:13px;color:#4B5563;margin-top:4px;background:#F9FAFB;padding:6px 10px;border-radius:4px;"><?= e($h['notes']) ?></div>
<?php endif; ?>
</div> </div>
<?php endforeach; ?>
</div> </div>
<?php endforeach; ?>
<?php endif; ?> <?php endif; ?>
</div> </div>
</div> </div>
</div> </div>
<!-- Available Transitions --> <!-- Sidebar -->
<div> <div>
<?php if (!$instance->is_completed && !empty($available)): ?> <!-- Available Transitions -->
<div class="card" style="margin-bottom:20px;"> <?php if (!$isCompleted && !empty($available)): ?>
<div style="padding:12px 15px;border-bottom:1px solid #E5E7EB;"> <div class="card" style="margin-bottom:20px;border:2px solid #0D7377;">
<h4 style="margin:0;color:#1A1A2E;font-size:14px;">الانتقالات المتاحة</h4> <div style="padding:14px 16px;background:#F0FDFA;border-bottom:1px solid #CCFBF1;">
<h4 style="margin:0;color:#0D7377;font-size:14px;font-weight:700;">الانتقالات المتاحة</h4>
</div> </div>
<div style="padding:15px;"> <div style="padding:16px;">
<?php foreach ($available as $trans): ?> <?php foreach ($available as $idx => $trans): ?>
<form method="POST" action="/workflows/instances/<?= (int) $instance->id ?>/transition" style="margin-bottom:12px;padding-bottom:12px;border-bottom:1px solid #F3F4F6;"> <form method="POST" action="/workflows/instances/<?= (int) $instance->id ?>/transition" style="<?= $idx < count($available) - 1 ? 'margin-bottom:16px;padding-bottom:16px;border-bottom:1px solid #F3F4F6;' : '' ?>">
<?= csrf_field() ?> <?= csrf_field() ?>
<input type="hidden" name="transition_name" value="<?= e($trans['name']) ?>"> <input type="hidden" name="transition_name" value="<?= e($trans['name']) ?>">
<div style="margin-bottom:8px;">
<strong style="color:#1A1A2E;font-size:14px;"><?= e($trans['name']) ?></strong> <div style="margin-bottom:10px;">
<div style="font-size:12px;color:#6B7280;"><?= e($trans['to_label_ar']) ?></div> <div style="font-weight:700;color:#1A1A2E;font-size:14px;margin-bottom:3px;"><?= e($trans['name']) ?></div>
<div style="font-size:12px;color:#6B7280;display:flex;align-items:center;gap:4px;">
&#8594; <span style="color:#059669;font-weight:600;"><?= e($trans['to_label_ar']) ?></span>
</div>
</div> </div>
<div class="form-group" style="margin-bottom:8px;">
<textarea name="notes" class="form-textarea" rows="2" placeholder="ملاحظات (اختياري)" style="font-size:12px;"></textarea> <div style="margin-bottom:10px;">
<textarea name="notes" rows="2" placeholder="ملاحظات (اختياري)..." style="width:100%;border:1px solid #E5E7EB;border-radius:6px;padding:8px 10px;font-size:13px;resize:vertical;font-family:inherit;"></textarea>
</div> </div>
<?php if ($trans['can_execute']): ?> <?php if ($trans['can_execute']): ?>
<button type="submit" class="btn btn-sm btn-primary" style="width:100%;" onclick="return confirm('هل تريد تنفيذ هذا الانتقال؟')">تنفيذ</button> <button type="submit" class="btn btn-sm btn-primary" style="width:100%;padding:10px;" onclick="return confirm('تأكيد تنفيذ الانتقال: <?= e($trans['name']) ?>؟')">
تنفيذ الانتقال
</button>
<?php else: ?> <?php else: ?>
<button type="button" class="btn btn-sm" style="width:100%;background:#E5E7EB;color:#9CA3AF;cursor:not-allowed;" disabled>غير متاح (شرط غير مستوفى)</button> <button type="button" class="btn btn-sm" style="width:100%;padding:10px;background:#F3F4F6;color:#9CA3AF;cursor:not-allowed;border:1px solid #E5E7EB;" disabled>
غير متاح — شرط غير مستوفى
</button>
<?php endif; ?> <?php endif; ?>
</form> </form>
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
</div> </div>
<?php elseif ($instance->is_completed): ?> <?php elseif ($isCompleted): ?>
<div class="card" style="padding:30px;text-align:center;"> <div class="card" style="margin-bottom:20px;text-align:center;padding:30px;">
<div style="font-size:48px;margin-bottom:10px;"></div> <div style="width:60px;height:60px;border-radius:50%;background:#F0FDF4;display:inline-flex;align-items:center;justify-content:center;margin-bottom:12px;">
<strong style="color:#059669;">دورة العمل مكتملة</strong> <span style="color:#059669;font-size:28px;">&#10003;</span>
</div>
<div style="font-weight:700;color:#059669;font-size:15px;">دورة العمل مكتملة</div>
<div style="font-size:12px;color:#6B7280;margin-top:4px;"><?= e($instance->completed_at) ?></div>
</div> </div>
<?php else: ?> <?php else: ?>
<div class="card" style="padding:30px;text-align:center;color:#6B7280;"> <div class="card" style="margin-bottom:20px;text-align:center;padding:30px;color:#9CA3AF;">
لا توجد انتقالات يدوية متاحة <div style="font-size:32px;margin-bottom:8px;">&#128274;</div>
<p style="margin:0;font-size:13px;">لا توجد انتقالات يدوية متاحة حالياً</p>
</div> </div>
<?php endif; ?> <?php endif; ?>
<!-- State Map --> <!-- State Map (Progress Tracker) -->
<div class="card"> <div class="card">
<div style="padding:12px 15px;border-bottom:1px solid #E5E7EB;"> <div style="padding:14px 16px;border-bottom:1px solid #E5E7EB;">
<h4 style="margin:0;color:#1A1A2E;font-size:14px;">خريطة الحالات</h4> <h4 style="margin:0;color:#1A1A2E;font-size:14px;">مسار دورة العمل</h4>
</div> </div>
<div style="padding:15px;"> <div style="padding:16px;">
<?php
$stateKeys = array_keys($states);
$currentIdx = array_search($instance->current_state, $stateKeys);
?>
<?php foreach ($states as $key => $state): ?> <?php foreach ($states as $key => $state): ?>
<div style="padding:6px 10px;margin-bottom:4px;border-radius:4px;font-size:13px;<?= $key === $instance->current_state ? 'background:#EFF6FF;border:2px solid #0284C7;font-weight:700;' : 'background:#F9FAFB;border:1px solid #E5E7EB;' ?>"> <?php
<?php if ($key === $instance->current_state): ?><?php elseif (($state['type'] ?? '') === 'terminal'): ?><?php else: ?><?php endif; ?> $isCurrent = ($key === $instance->current_state);
<?= e($state['label_ar'] ?? $key) ?> $idx = array_search($key, $stateKeys);
<?php if (($state['type'] ?? '') === 'initial'): ?><small style="color:#059669;">(بداية)</small><?php endif; ?> $isPast = ($currentIdx !== false && $idx < $currentIdx);
<?php if (($state['type'] ?? '') === 'terminal'): ?><small style="color:#DC2626;">(نهاية)</small><?php endif; ?> $type = $state['type'] ?? 'intermediate';
if ($isCurrent) {
$dotColor = '#0D7377';
$bgColor = '#F0FDFA';
$borderColor = '#0D7377';
$textColor = '#0D7377';
} elseif ($isPast || $isCompleted) {
$dotColor = '#059669';
$bgColor = '#F0FDF4';
$borderColor = '#BBF7D0';
$textColor = '#059669';
} else {
$dotColor = '#D1D5DB';
$bgColor = '#F9FAFB';
$borderColor = '#E5E7EB';
$textColor = '#6B7280';
}
?>
<div style="display:flex;align-items:center;gap:10px;padding:8px 10px;margin-bottom:4px;border-radius:6px;background:<?= $bgColor ?>;border:1px solid <?= $borderColor ?>;">
<span style="width:10px;height:10px;border-radius:50%;background:<?= $dotColor ?>;flex-shrink:0;<?= $isCurrent ? 'box-shadow:0 0 0 3px rgba(13,115,119,0.2);' : '' ?>"></span>
<span style="flex:1;font-size:13px;font-weight:<?= $isCurrent ? '700' : '500' ?>;color:<?= $textColor ?>;"><?= e($state['label_ar'] ?? $key) ?></span>
<?php if ($type === 'initial'): ?>
<span style="font-size:10px;background:#EFF6FF;color:#0284C7;padding:1px 5px;border-radius:3px;">بداية</span>
<?php elseif ($type === 'terminal'): ?>
<span style="font-size:10px;background:#FEF2F2;color:#DC2626;padding:1px 5px;border-radius:3px;">نهاية</span>
<?php endif; ?>
</div> </div>
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<?php $__template->endSection(); ?> <?php $__template->endSection(); ?>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment