airefactor #19
@ -965,23 +965,12 @@ class AIQueryInterface {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<svg class="toggle-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="transform: rotate(90deg);">
|
||||
<svg class="toggle-icon" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="transform: rotate(0deg);">
|
||||
<polyline points="9 18 15 12 9 6"/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div style="margin: 0.5rem 0 1rem 0;">
|
||||
<button id="download-results-btn" class="btn btn-secondary">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
||||
<polyline points="7 10 12 15 17 10"/>
|
||||
<line x1="12" y1="15" x2="12" y2="3"/>
|
||||
</svg>
|
||||
Download Analyse (JSON)
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="audit-trail-details">
|
||||
<div class="audit-trail-details collapsed">
|
||||
<!-- Audit Summary -->
|
||||
<div class="audit-summary">
|
||||
<div class="summary-header">📊 Analyse-Zusammenfassung</div>
|
||||
@ -1021,6 +1010,16 @@ class AIQueryInterface {
|
||||
<div class="audit-process-flow">
|
||||
${this.renderPhaseGroups(rawAuditTrail, stats)}
|
||||
</div>
|
||||
<div style="margin: 0.5rem 0 1rem 0;">
|
||||
<button id="download-results-btn" class="btn btn-secondary">
|
||||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="margin-right: 0.5rem;">
|
||||
<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
|
||||
<polyline points="7 10 12 15 17 10"/>
|
||||
<line x1="12" y1="15" x2="12" y2="3"/>
|
||||
</svg>
|
||||
Download Analyse (JSON)
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@ -1918,32 +1917,38 @@ class AIQueryInterface {
|
||||
|
||||
const priority = tool.recommendation ? tool.recommendation.priority : tool.priority;
|
||||
const confidenceTooltip = tool.confidence ? this.renderConfidenceTooltip(tool.confidence) : '';
|
||||
|
||||
const cardClass = this.getToolClass(tool, 'recommendation');
|
||||
|
||||
return `
|
||||
<div class="tool-recommendation ${cardClass}" onclick="window.showToolDetails('${tool.name}')">
|
||||
<div class="tool-rec-header">
|
||||
<h4 class="tool-rec-name">
|
||||
${tool.icon ? `<span class="mr-2 text-lg">${tool.icon}</span>` : ''}
|
||||
<div class="tool-recommendation ${cardClass}" onclick="window.showToolDetails('${tool.name}')"
|
||||
style="position: relative; cursor: pointer; transition: var(--transition-fast);"
|
||||
onmouseover="this.style.transform='translateY(-2px)'; this.style.boxShadow='var(--shadow-md)';"
|
||||
onmouseout="this.style.transform='translateY(0)'; this.style.boxShadow='';">
|
||||
|
||||
<div class="tool-rec-header" style="display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 0.75rem;">
|
||||
<h4 class="tool-rec-name" style="font-weight: 600; font-size: 1rem; margin: 0; color: var(--color-text); flex: 1; margin-right: 0.75rem;">
|
||||
${tool.icon ? `<span style="margin-right: 0.5rem; font-size: 1.125rem;">${tool.icon}</span>` : ''}
|
||||
${tool.name}
|
||||
</h4>
|
||||
<div class="flex items-center gap-1 flex-shrink-0">
|
||||
<span class="tool-rec-priority ${priority}" style="background-color: ${priorityColors[priority]};">
|
||||
<div style="display: flex; align-items: center; gap: 0.375rem; flex-shrink: 0;">
|
||||
<span class="tool-rec-priority ${priority}"
|
||||
style="background-color: ${priorityColors[priority]}; color: white; padding: 0.25rem 0.5rem; border-radius: 1rem; font-size: 0.75rem; font-weight: 500; text-transform: uppercase; position: relative; display: flex; align-items: center; gap: 0.25rem;">
|
||||
${priority}
|
||||
${confidenceTooltip}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tool-rec-justification">
|
||||
<div class="tool-rec-justification" style="background-color: var(--color-bg-tertiary); padding: 0.75rem; border-radius: 0.375rem; border-left: 3px solid var(--color-primary); margin: 0.75rem 0; font-style: italic; white-space: pre-wrap; word-wrap: break-word; font-size: 0.875rem; line-height: 1.5; color: var(--color-text-secondary);">
|
||||
"${sanitizeText(tool.justification || (tool.recommendation && tool.recommendation.justification) || `Empfohlen für ${tool.phase}`)}"
|
||||
</div>
|
||||
|
||||
<div class="text-xs text-secondary mt-auto">
|
||||
<div class="flex flex-wrap gap-1 mb-2">
|
||||
<div style="font-size: 0.75rem; color: var(--color-text-secondary); margin-top: auto;">
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 0.375rem; margin-bottom: 0.5rem;">
|
||||
${this.renderToolBadges(tool)}
|
||||
</div>
|
||||
<div class="flex justify-between items-center">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<span>${tool.type === 'method' ? 'Methode' : tool.platforms.slice(0, 2).join(', ')}</span>
|
||||
<span>${tool.skillLevel}</span>
|
||||
</div>
|
||||
@ -2021,15 +2026,15 @@ class AIQueryInterface {
|
||||
const confidenceTooltip = recommendation.confidence ? this.renderConfidenceTooltip(recommendation.confidence) : '';
|
||||
|
||||
return `
|
||||
<div class="card ${this.getToolClass(tool, 'card')} cursor-pointer relative" onclick="window.showToolDetails('${tool.name}')">
|
||||
<div class="card ${this.getToolClass(tool, 'card')}" style="cursor: pointer; position: relative;" onclick="window.showToolDetails('${tool.name}')">
|
||||
<div style="position: absolute; top: -8px; right: -8px; width: 32px; height: 32px; background-color: ${rankColors[rank]}; color: white; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 1.125rem;">
|
||||
${rank}
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<h3 class="mb-2">${tool.name}</h3>
|
||||
<div class="flex flex-wrap gap-2 items-center mb-3">
|
||||
<span class="badge text-white relative flex items-center gap-1" style="background-color: ${suitabilityColors[recommendation.suitability_score]};">
|
||||
<div style="margin-bottom: 1rem;">
|
||||
<h3 style="margin: 0 0 0.5rem 0;">${tool.name}</h3>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem; align-items: center; margin-bottom: 0.75rem;">
|
||||
<span class="badge" style="background-color: ${suitabilityColors[recommendation.suitability_score]}; color: white; position: relative; display: flex; align-items: center; gap: 0.25rem;">
|
||||
${this.getSuitabilityText(recommendation.suitability_score)}
|
||||
${confidenceTooltip}
|
||||
</span>
|
||||
@ -2037,13 +2042,13 @@ class AIQueryInterface {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-6">
|
||||
<h4 class="mb-3 text-accent">Warum diese Methode?</h4>
|
||||
<div class="leading-relaxed">${sanitizeText(recommendation.detailed_explanation)}</div>
|
||||
<div style="margin-bottom: 1.5rem;">
|
||||
<h4 style="margin: 0.8rem 0 0.75rem 0; color: var(--color-accent);">Warum diese Methode?</h4>
|
||||
<div style="margin: 0; line-height: 1.6; white-space: pre-wrap; word-wrap: break-word;">${sanitizeText(recommendation.detailed_explanation)}</div>
|
||||
|
||||
${recommendation.implementation_approach ? `
|
||||
<h4 class="mt-3 mb-3 text-primary">Anwendungsansatz</h4>
|
||||
<div class="leading-relaxed">${sanitizeText(recommendation.implementation_approach)}</div>
|
||||
<h4 style="margin: 0.8rem 0 0.75rem 0; color: var(--color-primary);">Anwendungsansatz</h4>
|
||||
<div style="margin: 0; line-height: 1.6; white-space: pre-wrap; word-wrap: break-word;">${sanitizeText(recommendation.implementation_approach)}</div>
|
||||
` : ''}
|
||||
</div>
|
||||
|
||||
@ -2058,66 +2063,69 @@ class AIQueryInterface {
|
||||
if (!confidence || typeof confidence.overall !== 'number') return '';
|
||||
|
||||
const confidenceColor = getConfidenceColor(confidence.overall);
|
||||
const tooltipId = `tooltip-${Math.random().toString(36).substr(2, 9)}`;
|
||||
|
||||
return `
|
||||
<span class="inline-flex items-center gap-1 cursor-pointer ml-1 relative"
|
||||
<span class="confidence-tooltip-trigger"
|
||||
style="display: inline-flex; align-items: center; gap: 0.125rem; cursor: help; margin-left: 0.25rem; position: relative;"
|
||||
onmouseenter="this.querySelector('.confidence-tooltip').style.display = 'block'"
|
||||
onmouseleave="this.querySelector('.confidence-tooltip').style.display = 'none'"
|
||||
onclick="event.stopPropagation();">
|
||||
<div class="w-1.5 h-1.5 rounded-xl flex-shrink-0" style="background-color: ${confidenceColor};"></div>
|
||||
<span class="text-xs font-semibold text-white">${confidence.overall}%</span>
|
||||
<div style="width: 6px; height: 6px; border-radius: 50%; background-color: ${confidenceColor}; flex-shrink: 0;"></div>
|
||||
<span style="font-size: 0.625rem; color: white; font-weight: 600; text-shadow: 0 1px 2px rgba(0,0,0,0.5);">${confidence.overall}%</span>
|
||||
|
||||
<div class="confidence-tooltip hidden absolute top-full right-0 z-50 bg-primary text-white p-4 rounded-lg shadow-lg text-xs" style="min-width: 320px; max-width: 400px; margin-top: 0.5rem;">
|
||||
<div class="flex justify-between items-center mb-3">
|
||||
<strong class="text-sm">KI-Vertrauenswertung</strong>
|
||||
<span class="font-semibold px-2 py-1 rounded text-xs" style="background-color: ${confidenceColor};">${confidence.overall}%</span>
|
||||
<div class="confidence-tooltip"
|
||||
style="display: none; position: absolute; top: 100%; right: 0; z-index: 1001; background: var(--color-bg); border: 1px solid var(--color-border); border-radius: 0.5rem; padding: 1rem; min-width: 320px; max-width: 400px; box-shadow: var(--shadow-lg); font-size: 0.75rem; color: var(--color-text); margin-top: 0.5rem;">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.75rem;">
|
||||
<strong style="font-size: 0.875rem; color: var(--color-primary);">KI-Vertrauenswertung</strong>
|
||||
<span style="background-color: ${confidenceColor}; color: white; font-weight: 600; padding: 0.125rem 0.375rem; border-radius: 0.25rem; font-size: 0.625rem;">${confidence.overall}%</span>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-2 mb-3">
|
||||
<div class="bg-secondary p-2 rounded border-l-4" style="border-left-color: var(--color-accent);">
|
||||
<div class="flex justify-between items-center mb-1">
|
||||
<span class="font-semibold text-xs">🔍 Semantische Relevanz</span>
|
||||
<strong class="text-accent">${confidence.semanticRelevance}%</strong>
|
||||
<div style="display: grid; grid-template-columns: 1fr; gap: 0.625rem; margin-bottom: 0.75rem;">
|
||||
<div style="background: var(--color-bg-secondary); padding: 0.5rem; border-radius: 0.375rem; border-left: 3px solid var(--color-accent);">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.25rem;">
|
||||
<span style="font-weight: 600; font-size: 0.6875rem; color: var(--color-text);">🔍 Semantische Relevanz</span>
|
||||
<strong style="color: var(--color-accent);">${confidence.semanticRelevance}%</strong>
|
||||
</div>
|
||||
<div class="text-xs text-secondary leading-tight">
|
||||
<div style="font-size: 0.625rem; color: var(--color-text-secondary); line-height: 1.3;">
|
||||
Wie gut die Tool-Beschreibung semantisch zu Ihrer Anfrage passt
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-secondary p-2 rounded border-l-4" style="border-left-color: var(--color-primary);">
|
||||
<div class="flex justify-between items-center mb-1">
|
||||
<span class="font-semibold text-xs">🎯 Aufgaben-Eignung</span>
|
||||
<strong class="text-primary">${confidence.taskSuitability}%</strong>
|
||||
<div style="background: var(--color-bg-secondary); padding: 0.5rem; border-radius: 0.375rem; border-left: 3px solid var(--color-primary);">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.25rem;">
|
||||
<span style="font-weight: 600; font-size: 0.6875rem; color: var(--color-text);">🎯 Aufgaben-Eignung</span>
|
||||
<strong style="color: var(--color-primary);">${confidence.taskSuitability}%</strong>
|
||||
</div>
|
||||
<div class="text-xs text-secondary leading-tight">
|
||||
<div style="font-size: 0.625rem; color: var(--color-text-secondary); line-height: 1.3;">
|
||||
KI-bewertete Eignung für Ihre spezifische Aufgabenstellung
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${confidence.strengthIndicators && confidence.strengthIndicators.length > 0 ? `
|
||||
<div class="mb-3 p-2 rounded border-l-4" style="background-color: var(--color-oss-bg); border-left-color: var(--color-accent);">
|
||||
<strong class="text-accent text-xs flex items-center gap-1 mb-1">
|
||||
<div style="margin-bottom: 0.75rem; padding: 0.5rem; background: var(--color-oss-bg); border-radius: 0.375rem; border-left: 3px solid var(--color-accent);">
|
||||
<strong style="color: var(--color-accent); font-size: 0.6875rem; display: flex; align-items: center; gap: 0.25rem; margin-bottom: 0.375rem;">
|
||||
<span>✓</span> Stärken dieser Empfehlung:
|
||||
</strong>
|
||||
<ul class="ml-4 text-xs leading-normal">
|
||||
${confidence.strengthIndicators.slice(0, 3).map(s => `<li class="mb-1">${sanitizeText(s)}</li>`).join('')}
|
||||
<ul style="margin: 0; padding-left: 1rem; font-size: 0.625rem; line-height: 1.4; color: var(--color-text);">
|
||||
${confidence.strengthIndicators.slice(0, 3).map(s => `<li style="margin-bottom: 0.25rem;">${sanitizeText(s)}</li>`).join('')}
|
||||
</ul>
|
||||
</div>
|
||||
` : ''}
|
||||
|
||||
${confidence.uncertaintyFactors && confidence.uncertaintyFactors.length > 0 ? `
|
||||
<div class="p-2 rounded border-l-4" style="background-color: var(--color-hosted-bg); border-left-color: var(--color-warning);">
|
||||
<strong class="text-warning text-xs flex items-center gap-1 mb-1">
|
||||
<div style="padding: 0.5rem; background: var(--color-hosted-bg); border-radius: 0.375rem; border-left: 3px solid var(--color-warning);">
|
||||
<strong style="color: var(--color-warning); font-size: 0.6875rem; display: flex; align-items: center; gap: 0.25rem; margin-bottom: 0.375rem;">
|
||||
<span>⚠</span> Mögliche Einschränkungen:
|
||||
</strong>
|
||||
<ul class="ml-4 text-xs leading-normal">
|
||||
${confidence.uncertaintyFactors.slice(0, 3).map(f => `<li class="mb-1">${sanitizeText(f)}</li>`).join('')}
|
||||
<ul style="margin: 0; padding-left: 1rem; font-size: 0.625rem; line-height: 1.4; color: var(--color-text);">
|
||||
${confidence.uncertaintyFactors.slice(0, 3).map(f => `<li style="margin-bottom: 0.25rem;">${sanitizeText(f)}</li>`).join('')}
|
||||
</ul>
|
||||
</div>
|
||||
` : ''}
|
||||
|
||||
<div class="mt-3 pt-3 border-t border-secondary text-xs text-secondary text-center">
|
||||
<div style="margin-top: 0.75rem; padding-top: 0.75rem; border-top: 1px solid var(--color-border); font-size: 0.625rem; color: var(--color-text-secondary); text-align: center;">
|
||||
Forensisch fundierte KI-Analyse
|
||||
</div>
|
||||
</div>
|
||||
@ -2151,18 +2159,18 @@ class AIQueryInterface {
|
||||
if (!pros?.length && !cons?.length) return '';
|
||||
|
||||
return `
|
||||
<div class="grid grid-cols-2 gap-4 mb-6">
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; margin-bottom: 1.5rem;">
|
||||
${pros?.length ? `
|
||||
<div class="card-info-sm border-l-4" style="border-left-color: var(--color-accent); background-color: var(--color-oss-bg);">
|
||||
<h5 class="mb-2 text-accent text-sm">✓ Vorteile</h5>
|
||||
<div style="background-color: var(--color-oss-bg); padding: 1rem; border-radius: 0.5rem; border-left: 3px solid var(--color-accent);">
|
||||
<h5 style="margin: 0 0 0.5rem 0; color: var(--color-accent); font-size: 0.875rem;">✓ Vorteile</h5>
|
||||
<ul style="margin: 0; padding-left: 1rem;">
|
||||
${pros.map(pro => `<li style="margin-bottom: 0.25rem;">${sanitizeText(pro)}</li>`).join('')}
|
||||
</ul>
|
||||
</div>
|
||||
` : ''}
|
||||
${cons?.length ? `
|
||||
<div class="card-info-sm border-l-4" style="border-left-color: var(--color-warning); background-color: var(--color-hosted-bg);">
|
||||
<h5 class="mb-2 text-warning text-sm">✗ Nachteile</h5>
|
||||
<div style="background-color: var(--color-hosted-bg); padding: 1rem; border-radius: 0.5rem; border-left: 3px solid var(--color-warning);">
|
||||
<h5 style="margin: 0 0 0.5rem 0; color: var(--color-warning); font-size: 0.875rem;">✗ Nachteile</h5>
|
||||
<ul style="margin: 0; padding-left: 1rem;">
|
||||
${cons.map(con => `<li style="margin-bottom: 0.25rem;">${sanitizeText(con)}</li>`).join('')}
|
||||
</ul>
|
||||
@ -2176,7 +2184,7 @@ class AIQueryInterface {
|
||||
const isMethod = tool.type === 'method';
|
||||
|
||||
return `
|
||||
<div class="grid grid-auto-fit gap-3 text-sm text-secondary mb-4 p-3 bg-secondary rounded">
|
||||
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0.75rem; font-size: 0.8125rem; color: var(--color-text-secondary); margin-bottom: 1rem; padding: 0.75rem; background-color: var(--color-bg-secondary); border-radius: 0.375rem;">
|
||||
${!isMethod ? `<div><strong>Plattformen:</strong> ${tool.platforms.join(', ')}</div>` : ''}
|
||||
<div><strong>Skill Level:</strong> ${tool.skillLevel}</div>
|
||||
${!isMethod ? `<div><strong>Lizenz:</strong> ${tool.license}</div>` : ''}
|
||||
@ -2187,9 +2195,9 @@ class AIQueryInterface {
|
||||
|
||||
renderAlternatives(alternatives) {
|
||||
return `
|
||||
<div class="bg-secondary p-4 rounded mb-4">
|
||||
<h5 class="mb-2 text-secondary text-sm">Alternative Ansätze</h5>
|
||||
<div class="leading-relaxed">${sanitizeText(alternatives)}</div>
|
||||
<div style="background-color: var(--color-bg-secondary); padding: 1rem; border-radius: 0.5rem; margin-bottom: 1rem;">
|
||||
<h5 style="margin: 0 0 0.5rem 0; color: var(--color-text-secondary); font-size: 0.875rem;">Alternative Ansätze</h5>
|
||||
<div style="margin: 0; line-height: 1.6; white-space: pre-wrap; word-wrap: break-word;">${sanitizeText(alternatives)}</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@ -2231,6 +2239,15 @@ class AIQueryInterface {
|
||||
}
|
||||
}
|
||||
|
||||
getSuitabilityText(score) {
|
||||
const texts = {
|
||||
high: 'GUT GEEIGNET',
|
||||
medium: 'GEEIGNET',
|
||||
low: 'VIELLEICHT GEEIGNET'
|
||||
};
|
||||
return texts[score] || 'GEEIGNET';
|
||||
}
|
||||
|
||||
showLoading() {
|
||||
showElement(this.elements.loading);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user