show.php
- Pfad:
src/View/content-pipeline/show.php
- Namespace: -
- Zeilen: 314 | Größe: 12,256 Bytes
- Geändert: 2025-12-27 14:08:28 | Gescannt: 2025-12-31 10:22:15
Code Hygiene Score: 87
- Dependencies: 100 (25%)
- LOC: 62 (20%)
- Methods: 100 (20%)
- Secrets: 100 (15%)
- Classes: 100 (10%)
- Magic Numbers: 50 (10%)
Issues 5
| Zeile |
Typ |
Beschreibung |
| 27 |
magic_number |
Magic Number gefunden: 1000 |
| 38 |
magic_number |
Magic Number gefunden: 1000 |
| 103 |
magic_number |
Magic Number gefunden: 1000 |
| 131 |
magic_number |
Magic Number gefunden: 1000 |
| 308 |
magic_number |
Magic Number gefunden: 100 |
Versionen 26
-
v26
2025-12-27 14:08 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v25
2025-12-27 12:06 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v24
2025-12-27 12:05 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v23
2025-12-27 12:05 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v22
2025-12-27 12:04 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v21
2025-12-27 12:03 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v20
2025-12-27 12:03 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v19
2025-12-23 16:32 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v18
2025-12-23 07:44 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v17
2025-12-23 04:18 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v16
2025-12-23 04:18 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v15
2025-12-23 04:18 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v14
2025-12-23 03:32 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v13
2025-12-22 15:22 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v12
2025-12-22 15:22 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v11
2025-12-22 15:22 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v10
2025-12-22 15:19 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v9
2025-12-22 15:19 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v8
2025-12-22 10:14 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v7
2025-12-22 10:14 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v6
2025-12-22 10:04 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v5
2025-12-22 10:03 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v4
2025-12-22 09:58 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v3
2025-12-22 09:58 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v2
2025-12-22 09:57 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Edit-Operation
-
v1
2025-12-22 09:42 | claude-code-hook | modified
Claude Code Pre-Hook Backup vor Write-Operation
Code
<?php ob_start(); ?>
<h1>Pipeline: <?= htmlspecialchars($pipeline['name']) ?></h1>
<?php if ($pipeline['is_default']): ?>
<span class="badge badge--success">Standard-Pipeline</span>
<?php endif; ?>
<div class="page-actions">
<a href="/content-pipeline/<?= $pipeline['id'] ?>/edit" class="btn btn--secondary">Bearbeiten</a>
<form action="/content-pipeline/<?= $pipeline['id'] ?>/run" method="POST" style="display:inline;">
<input type="hidden" name="_csrf_token" value="<?= htmlspecialchars($csrfToken ?? '') ?>">
<button type="submit" class="btn btn--primary">Pipeline starten</button>
</form>
</div>
<ul class="config-list">
<li class="config-list__item">
<span class="config-list__label">Quelle:</span>
<input type="text" name="source_path" class="config-list__input config-list__input--inline"
value="<?= htmlspecialchars($pipeline['source_path']) ?>"
hx-post="/content-pipeline/<?= $pipeline['id'] ?>/config"
hx-headers='{"X-CSRF-TOKEN": "<?= $csrfToken ?>"}'
hx-trigger="blur, keyup[key=='Enter']"
hx-swap="none"
hx-disabled-elt="this"
hx-on::after-request="this.classList.toggle('is-saved', event.detail.successful); setTimeout(() => this.classList.remove('is-saved'), 1000)">
</li>
<li class="config-list__item">
<span class="config-list__label">Dateitypen:</span>
<input type="text" name="extensions" class="config-list__input config-list__input--inline"
value="<?= implode(', ', $pipeline['extensions'] ?? []) ?>"
hx-post="/content-pipeline/<?= $pipeline['id'] ?>/config"
hx-headers='{"X-CSRF-TOKEN": "<?= $csrfToken ?>"}'
hx-trigger="blur, keyup[key=='Enter']"
hx-swap="none"
hx-disabled-elt="this"
hx-on::after-request="this.classList.toggle('is-saved', event.detail.successful); setTimeout(() => this.classList.remove('is-saved'), 1000)">
</li>
</ul>
<h2>Pipeline-Schritte</h2>
<table>
<thead>
<tr>
<th>#</th>
<th>Schritt</th>
<th>Phase</th>
<th>Modell</th>
<th>Zielspeicher</th>
<th>Konfiguration</th>
</tr>
</thead>
<tbody>
<?php foreach ($pipeline['steps'] as $step): ?>
<?php
$meta = $stepTypes[$step['step_type']] ?? ['label' => $step['step_type'], 'description' => '', 'phase' => '-', 'storage' => null];
$config = $step['config'] ?? [];
// Aktuelles Modell ermitteln (mit ollama: Prefix für Dropdown)
$currentModel = null;
$usesVision = $meta['uses_vision'] ?? false;
$usesLlm = $meta['uses_llm'] ?? false;
if (!empty($config['model'])) {
$isAnthropic = str_contains($config['model'], 'claude') || ($config['provider'] ?? '') === 'anthropic';
$currentModel = $isAnthropic ? $config['model'] : 'ollama:' . $config['model'];
}
// Config ohne model/provider für kompaktere Anzeige
$displayConfig = array_filter($config, fn ($k) => !in_array($k, ['provider', 'model']), ARRAY_FILTER_USE_KEY);
// Zielspeicher mit dynamischen Werten ersetzen
$storage = $meta['storage'] ?? null;
if ($storage !== null && isset($config['collection'])) {
$storage = str_replace('{collection}', $config['collection'], $storage);
}
?>
<tr data-step-id="<?= $step['id'] ?>">
<td><?= $step['sort_order'] ?></td>
<td>
<strong><?= $meta['label'] ?></strong>
<br>
<small><?= $meta['description'] ?></small>
</td>
<td><?= $meta['phase'] ?></td>
<td class="model-cell">
<?php if (!empty($meta['fixed_model'])): ?>
<span class="fixed-model"><?= htmlspecialchars($meta['fixed_model']) ?></span>
<?php elseif ($currentModel !== null || $usesVision || $usesLlm): ?>
<?php
$selected = $currentModel ?? ($usesVision ? \Infrastructure\AI\ModelConfig::getDefaultVisionModel() : \Infrastructure\AI\ModelConfig::getDefaultModel());
$availableModels = $usesVision ? \Infrastructure\AI\ModelConfig::getVisionModels() : \Infrastructure\AI\ModelConfig::getAll();
$ollamaModels = array_filter($availableModels, fn ($k) => str_starts_with($k, 'ollama:'), ARRAY_FILTER_USE_KEY);
$anthropicModels = array_filter($availableModels, fn ($k) => !str_starts_with($k, 'ollama:'), ARRAY_FILTER_USE_KEY);
?>
<select name="model" class="form-select form-select--compact"
hx-post="/content-pipeline/<?= $pipeline['id'] ?>/steps/<?= $step['id'] ?>/model"
hx-headers='{"X-CSRF-TOKEN": "<?= $csrfToken ?>"}'
hx-swap="none"
hx-disabled-elt="this"
hx-on::after-request="this.classList.toggle('is-saved', event.detail.successful); setTimeout(() => this.classList.remove('is-saved'), 1000)">
<?php if (!empty($ollamaModels)): ?>
<optgroup label="Ollama (lokal)">
<?php foreach ($ollamaModels as $modelId => $label): ?>
<option value="<?= htmlspecialchars($modelId) ?>" <?= $selected === $modelId ? 'selected' : '' ?>><?= htmlspecialchars($label) ?></option>
<?php endforeach; ?>
</optgroup>
<?php endif; ?>
<?php if (!empty($anthropicModels)): ?>
<optgroup label="Anthropic">
<?php foreach ($anthropicModels as $modelId => $label): ?>
<option value="<?= htmlspecialchars($modelId) ?>" <?= $selected === $modelId ? 'selected' : '' ?>><?= htmlspecialchars($label) ?></option>
<?php endforeach; ?>
</optgroup>
<?php endif; ?>
</select>
<?php else: ?>
<span class="text-muted">-</span>
<?php endif; ?>
</td>
<td class="storage-cell">
<?php if (!empty($meta['has_collection'])): ?>
<span class="storage-prefix">Qdrant:</span>
<select name="collection" class="collection-select"
hx-post="/content-pipeline/<?= $pipeline['id'] ?>/steps/<?= $step['id'] ?>/collection"
hx-headers='{"X-CSRF-TOKEN": "<?= $csrfToken ?>"}'
hx-swap="none"
hx-disabled-elt="this"
hx-on::after-request="this.classList.toggle('is-saved', event.detail.successful); setTimeout(() => this.classList.remove('is-saved'), 1000)">
<?php foreach ($collections as $collKey => $collLabel): ?>
<option value="<?= htmlspecialchars($collKey) ?>" <?= ($config['collection'] ?? 'documents') === $collKey ? 'selected' : '' ?>>
<?= htmlspecialchars($collKey) ?>
</option>
<?php endforeach; ?>
</select>
<?php elseif ($storage): ?>
<code class="storage-code"><?= htmlspecialchars($storage) ?></code>
<?php else: ?>
<span class="text-muted">-</span>
<?php endif; ?>
</td>
<td>
<?php if ($displayConfig): ?>
<code class="config-code"><?= htmlspecialchars(json_encode($displayConfig, JSON_UNESCAPED_UNICODE)) ?></code>
<?php else: ?>
<span class="text-muted">-</span>
<?php endif; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<h2>Ausführungen</h2>
<?php if (!empty($runs)): ?>
<table>
<thead>
<tr>
<th>ID</th>
<th>Status</th>
<th>Gestartet</th>
<th>Beendet</th>
<th>Dokumente</th>
<th>Chunks</th>
</tr>
</thead>
<tbody>
<?php foreach ($runs as $run): ?>
<tr>
<td><a href="/content-pipeline/<?= $pipeline['id'] ?>/run/<?= $run['id'] ?>/status">#<?= $run['id'] ?></a></td>
<td>
<span class="badge badge--<?= $run['status'] === 'completed' ? 'success' : ($run['status'] === 'failed' ? 'danger' : ($run['status'] === 'running' ? 'warning' : 'muted')) ?>">
<?= $run['status'] ?>
</span>
</td>
<td><?= $run['started_at'] ?? '-' ?></td>
<td><?= $run['completed_at'] ?? '-' ?></td>
<td>
<?= $run['documents_processed'] ?? 0 ?>/<?= $run['documents_total'] ?? 0 ?>
<?php if (($run['documents_failed'] ?? 0) > 0): ?>
<span class="text-danger">(<?= $run['documents_failed'] ?> Fehler)</span>
<?php endif; ?>
</td>
<td><?= $run['chunks_created'] ?? 0 ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p class="empty-state empty-state--small">Noch keine Ausführungen vorhanden.</p>
<?php endif; ?>
<p class="links-bar">
<a href="/content-pipeline">Zurück zur Übersicht</a>
</p>
<style>
.config-list {
list-style: none;
padding: 0;
margin: 1rem 0 2rem;
}
.config-list__item {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.5rem 0;
border-bottom: 1px solid var(--border-color-light, #eee);
}
.config-list__label {
font-weight: 500;
min-width: 100px;
}
.config-list__input {
flex: 1;
font-family: monospace;
font-size: 0.9rem;
padding: 0.25rem 0.5rem;
border: 1px solid var(--border-color, #ccc);
border-radius: 4px;
}
.config-list__input--inline {
border-color: transparent;
background: transparent;
}
.config-list__input--inline:hover {
border-color: var(--border-color, #ccc);
background: var(--bg-input, #fff);
}
.config-list__input:focus {
outline: none;
border-color: var(--color-primary, #0066cc);
background: var(--bg-input, #fff);
}
.config-list__input.is-saved {
border-color: var(--color-success, #28a745);
animation: flash-success 0.5s;
}
.config-list__input:disabled {
opacity: 0.6;
}
.config-code,
.storage-code {
font-size: 0.75rem;
max-width: 200px;
display: block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.config-code:hover,
.storage-code:hover {
white-space: normal;
word-break: break-all;
}
.storage-cell {
min-width: 150px;
}
.storage-code {
color: var(--color-primary, #0066cc);
background: var(--bg-muted, #f5f5f5);
padding: 0.15rem 0.4rem;
border-radius: 3px;
}
.fixed-model {
font-size: 0.8rem;
color: var(--text-muted, #666);
font-family: monospace;
}
.storage-prefix {
font-size: 0.8rem;
color: var(--text-muted, #666);
margin-right: 0.25rem;
}
.collection-select {
font-size: 0.8rem;
padding: 0.15rem 0.3rem;
border: 1px solid var(--border-color, #ccc);
border-radius: 3px;
background: var(--bg-input, #fff);
}
.collection-select.is-saving {
opacity: 0.6;
pointer-events: none;
}
.collection-select.is-saved {
border-color: var(--color-success, #28a745);
animation: flash-success 0.5s;
}
.model-cell .form-select--compact {
font-size: 0.8rem;
padding: 0.25rem 0.5rem;
min-width: 140px;
}
.model-cell .form-select--compact.is-saving {
opacity: 0.6;
pointer-events: none;
}
.model-cell .form-select--compact.is-saved {
border-color: var(--color-success, #28a745);
animation: flash-success 0.5s;
}
@keyframes flash-success {
0% { background-color: var(--color-success-light, #d4edda); }
100% { background-color: transparent; }
}
</style>
<?php $content = ob_get_clean(); ?>
<?php require VIEW_PATH . '/layout.php'; ?>