{
"event": "PreToolUse",
"tool_name": "Read",
"tool_input": {
"file_path": "\/var\/www\/dev.campus.systemische-tools.de\/src\/View\/content-pipeline\/show.php",
"offset": 170
}
}
{
"tool_response": {
"type": "text",
"file": {
"filePath": "\/var\/www\/dev.campus.systemische-tools.de\/src\/View\/content-pipeline\/show.php",
"content": " <tbody>\n <?php foreach ($runs as $run): ?>\n <tr>\n <td><a href=\"\/content-pipeline\/<?= $pipeline['id'] ?>\/run\/<?= $run['id'] ?>\/status\">#<?= $run['id'] ?><\/a><\/td>\n <td>\n <span class=\"badge badge--<?= $run['status'] === 'completed' ? 'success' : ($run['status'] === 'failed' ? 'danger' : ($run['status'] === 'running' ? 'warning' : 'muted')) ?>\">\n <?= $run['status'] ?>\n <\/span>\n <\/td>\n <td><?= $run['started_at'] ?? '-' ?><\/td>\n <td><?= $run['completed_at'] ?? '-' ?><\/td>\n <td>\n <?= $run['documents_processed'] ?? 0 ?>\/<?= $run['documents_total'] ?? 0 ?>\n <?php if (($run['documents_failed'] ?? 0) > 0): ?>\n <span class=\"text-danger\">(<?= $run['documents_failed'] ?> Fehler)<\/span>\n <?php endif; ?>\n <\/td>\n <td><?= $run['chunks_created'] ?? 0 ?><\/td>\n <\/tr>\n <?php endforeach; ?>\n <\/tbody>\n<\/table>\n<?php else: ?>\n<p class=\"empty-state empty-state--small\">Noch keine Ausführungen vorhanden.<\/p>\n<?php endif; ?>\n\n<p class=\"links-bar\">\n <a href=\"\/content-pipeline\">Zurück zur Übersicht<\/a>\n<\/p>\n\n<style>\n.config-list {\n list-style: none;\n padding: 0;\n margin: 1rem 0 2rem;\n}\n.config-list__item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0;\n border-bottom: 1px solid var(--border-color-light, #eee);\n}\n.config-list__label {\n font-weight: 500;\n min-width: 100px;\n}\n.config-list__value {\n flex: 1;\n font-family: monospace;\n font-size: 0.9rem;\n}\n.config-list__value.editable {\n cursor: pointer;\n padding: 0.25rem 0.5rem;\n border-radius: 4px;\n transition: background-color 0.15s;\n}\n.config-list__value.editable:hover {\n background: var(--bg-muted, #f5f5f5);\n}\n.config-list__value.editable::after {\n content: ' \\270E';\n font-size: 0.8rem;\n color: var(--text-muted, #999);\n opacity: 0;\n transition: opacity 0.15s;\n}\n.config-list__value.editable:hover::after {\n opacity: 1;\n}\n.config-list__input {\n flex: 1;\n font-family: monospace;\n font-size: 0.9rem;\n padding: 0.25rem 0.5rem;\n border: 1px solid var(--border-color, #ccc);\n border-radius: 4px;\n}\n.config-list__input:focus {\n outline: none;\n border-color: var(--color-primary, #0066cc);\n}\n.config-list__value.is-saving {\n opacity: 0.6;\n}\n.config-code,\n.storage-code {\n font-size: 0.75rem;\n max-width: 200px;\n display: block;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.config-code:hover,\n.storage-code:hover {\n white-space: normal;\n word-break: break-all;\n}\n.storage-cell {\n min-width: 150px;\n}\n.storage-code {\n color: var(--color-primary, #0066cc);\n background: var(--bg-muted, #f5f5f5);\n padding: 0.15rem 0.4rem;\n border-radius: 3px;\n}\n.fixed-model {\n font-size: 0.8rem;\n color: var(--text-muted, #666);\n font-family: monospace;\n}\n.storage-prefix {\n font-size: 0.8rem;\n color: var(--text-muted, #666);\n margin-right: 0.25rem;\n}\n.collection-select {\n font-size: 0.8rem;\n padding: 0.15rem 0.3rem;\n border: 1px solid var(--border-color, #ccc);\n border-radius: 3px;\n background: var(--bg-input, #fff);\n}\n.collection-select.is-saving {\n opacity: 0.6;\n pointer-events: none;\n}\n.collection-select.is-saved {\n border-color: var(--color-success, #28a745);\n animation: flash-success 0.5s;\n}\n.model-cell .form-select--compact {\n font-size: 0.8rem;\n padding: 0.25rem 0.5rem;\n min-width: 140px;\n}\n.model-cell .form-select--compact.is-saving {\n opacity: 0.6;\n pointer-events: none;\n}\n.model-cell .form-select--compact.is-saved {\n border-color: var(--color-success, #28a745);\n animation: flash-success 0.5s;\n}\n@keyframes flash-success {\n 0% { background-color: var(--color-success-light, #d4edda); }\n 100% { background-color: transparent; }\n}\n<\/style>\n\n<script>\ndocument.addEventListener('DOMContentLoaded', function() {\n const pipelineId = <?= (int) $pipeline['id'] ?>;\n\n \/\/ Model-Dropdowns\n document.querySelectorAll('.model-cell select').forEach(select => {\n select.addEventListener('change', async function() {\n const row = this.closest('tr');\n const stepId = row.dataset.stepId;\n const model = this.value;\n\n this.classList.add('is-saving');\n\n try {\n const response = await fetch(`\/content-pipeline\/${pipelineId}\/steps\/${stepId}\/model`, {\n method: 'POST',\n headers: { 'Content-Type': 'application\/x-www-form-urlencoded' },\n body: 'model=' + encodeURIComponent(model)\n });\n\n const data = await response.json();\n\n if (data.success) {\n this.classList.remove('is-saving');\n this.classList.add('is-saved');\n setTimeout(() => this.classList.remove('is-saved'), 500);\n\n \/\/ Speichere in localStorage für User-Präferenz\n localStorage.setItem('pipeline_default_model', model);\n } else {\n alert('Fehler: ' + (data.error || 'Unbekannter Fehler'));\n this.classList.remove('is-saving');\n }\n } catch (error) {\n alert('Speichern fehlgeschlagen: ' + error.message);\n this.classList.remove('is-saving');\n }\n });\n });\n\n \/\/ User-Präferenz für neues Standard-Modell laden\n const savedModel = localStorage.getItem('pipeline_default_model');\n if (savedModel) {\n console.log('Gespeichertes Standard-Modell:', savedModel);\n }\n\n \/\/ Collection-Dropdowns\n document.querySelectorAll('.collection-select').forEach(select => {\n select.addEventListener('change', async function() {\n const stepId = this.dataset.stepId;\n const collection = this.value;\n\n this.classList.add('is-saving');\n\n try {\n const response = await fetch(`\/content-pipeline\/${pipelineId}\/steps\/${stepId}\/collection`, {\n method: 'POST',\n headers: { 'Content-Type': 'application\/x-www-form-urlencoded' },\n body: 'collection=' + encodeURIComponent(collection)\n });\n\n const data = await response.json();\n\n if (data.success) {\n this.classList.remove('is-saving');\n this.classList.add('is-saved');\n setTimeout(() => this.classList.remove('is-saved'), 500);\n } else {\n alert('Fehler: ' + (data.error || 'Unbekannter Fehler'));\n this.classList.remove('is-saving');\n }\n } catch (error) {\n alert('Speichern fehlgeschlagen: ' + error.message);\n this.classList.remove('is-saving');\n }\n });\n });\n\n \/\/ Inline-Edit für Quelle und Dateitypen\n document.querySelectorAll('.config-list__value.editable').forEach(el => {\n el.addEventListener('click', function() {\n if (this.querySelector('input')) return;\n\n const field = this.dataset.field;\n const currentValue = this.textContent.trim();\n const originalEl = this;\n\n const input = document.createElement('input');\n input.type = 'text';\n input.className = 'config-list__input';\n input.value = currentValue;\n\n originalEl.textContent = '';\n originalEl.appendChild(input);\n input.focus();\n input.select();\n\n async function saveValue() {\n const newValue = input.value.trim();\n if (newValue === currentValue) {\n originalEl.textContent = currentValue;\n return;\n }\n\n originalEl.classList.add('is-saving');\n\n try {\n const response = await fetch(`\/content-pipeline\/${pipelineId}\/config`, {\n method: 'POST',\n headers: { 'Content-Type': 'application\/x-www-form-urlencoded' },\n body: field + '=' + encodeURIComponent(newValue)\n });\n\n const data = await response.json();\n\n if (data.success) {\n originalEl.textContent = newValue;\n originalEl.classList.remove('is-saving');\n } else {\n alert('Fehler: ' + (data.error || 'Unbekannter Fehler'));\n originalEl.textContent = currentValue;\n originalEl.classList.remove('is-saving');\n }\n } catch (error) {\n alert('Speichern fehlgeschlagen: ' + error.message);\n originalEl.textContent = currentValue;\n originalEl.classList.remove('is-saving');\n }\n }\n\n input.addEventListener('blur', saveValue);\n input.addEventListener('keydown', function(e) {\n if (e.key === 'Enter') {\n e.preventDefault();\n input.blur();\n } else if (e.key === 'Escape') {\n originalEl.textContent = currentValue;\n }\n });\n });\n });\n});\n<\/script>\n\n<?php $content = ob_get_clean(); ?>\n<?php require VIEW_PATH . '\/layout.php'; ?>\n",
"numLines": 300,
"startLine": 170,
"totalLines": 469
}
}
}