first draft enhancement 2
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
---
|
||||
import { getToolsData } from '../utils/dataService.js';
|
||||
import { isToolHosted } from '../utils/toolHelpers.js';
|
||||
|
||||
const data = await getToolsData();
|
||||
const tools = data.tools;
|
||||
@@ -698,7 +699,10 @@ class AIQueryInterface {
|
||||
if (fullTool) {
|
||||
toolsByPhase[recTool.phase].push({
|
||||
...fullTool,
|
||||
recommendation: recTool
|
||||
recommendation: recTool,
|
||||
confidence: recTool.confidence,
|
||||
justification: recTool.justification,
|
||||
priority: recTool.priority
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -999,6 +1003,151 @@ class AIQueryInterface {
|
||||
return String(data);
|
||||
}
|
||||
|
||||
renderConfidenceIndicator(confidence) {
|
||||
if (!confidence || typeof confidence.overall !== 'number') return '';
|
||||
|
||||
const confidenceColor = confidence.overall >= 80 ? 'var(--color-accent)' :
|
||||
confidence.overall >= 60 ? 'var(--color-warning)' : 'var(--color-error)';
|
||||
|
||||
const strengthText = confidence.overall >= 80 ? 'HOCH' :
|
||||
confidence.overall >= 60 ? 'MITTEL' : 'NIEDRIG';
|
||||
|
||||
return `
|
||||
<div class="confidence-indicator-integrated" style="display: flex; align-items: center; gap: 0.5rem; margin-bottom: 0.75rem;">
|
||||
<div class="confidence-bar-wrapper" style="flex: 1; height: 4px; background-color: var(--color-bg-tertiary); border-radius: 2px; overflow: hidden;">
|
||||
<div class="confidence-bar-fill" style="width: ${confidence.overall}%; height: 100%; background-color: ${confidenceColor}; transition: var(--transition-fast);"></div>
|
||||
</div>
|
||||
<div class="confidence-badge-compact" style="display: flex; align-items: center; gap: 0.375rem;">
|
||||
<span class="badge badge-mini" style="background-color: ${confidenceColor}; color: white; font-weight: 600; font-size: 0.625rem;">
|
||||
${confidence.overall}%
|
||||
</span>
|
||||
<button class="btn-icon" style="width: 16px; height: 16px; padding: 0.125rem; font-size: 0.625rem;" onclick="this.parentElement.nextElementSibling.style.display = this.parentElement.nextElementSibling.style.display === 'none' ? 'block' : 'none'; this.textContent = this.textContent === 'ℹ️' ? '✕' : 'ℹ️';" title="Vertrauens-Details">ℹ️</button>
|
||||
</div>
|
||||
<div style="display: none; position: absolute; z-index: 20; background: var(--color-bg); border: 1px solid var(--color-border); border-radius: 0.5rem; padding: 1rem; margin-top: 6rem; right: 0; min-width: 320px; box-shadow: var(--shadow-lg);" class="confidence-details-popup">
|
||||
<div style="margin-bottom: 0.75rem;">
|
||||
<div style="display: flex; justify-content: between; align-items: center; margin-bottom: 0.5rem;">
|
||||
<strong class="text-sm">Vertrauens-Komponenten</strong>
|
||||
<span class="badge badge-mini" style="background-color: ${confidenceColor}; color: white;">${strengthText}</span>
|
||||
</div>
|
||||
<div style="display: grid; grid-template-columns: 1fr 1fr; gap: 0.5rem; font-size: 0.75rem;">
|
||||
<div style="display: flex; justify-content: space-between; padding: 0.25rem; background: var(--color-bg-secondary); border-radius: 0.25rem;">
|
||||
<span>Ähnlichkeit:</span>
|
||||
<span class="font-semibold">${confidence.embeddingsQuality}%</span>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between; padding: 0.25rem; background: var(--color-bg-secondary); border-radius: 0.25rem;">
|
||||
<span>Domain:</span>
|
||||
<span class="font-semibold">${confidence.domainAlignment}%</span>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between; padding: 0.25rem; background: var(--color-bg-secondary); border-radius: 0.25rem;">
|
||||
<span>Konsens:</span>
|
||||
<span class="font-semibold">${confidence.consensus}%</span>
|
||||
</div>
|
||||
<div style="display: flex; justify-content: space-between; padding: 0.25rem; background: var(--color-bg-secondary); border-radius: 0.25rem;">
|
||||
<span>Aktualität:</span>
|
||||
<span class="font-semibold">${confidence.freshness}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${confidence.strengthIndicators && confidence.strengthIndicators.length > 0 ? `
|
||||
<div style="margin-bottom: 0.75rem;">
|
||||
<strong class="text-accent" style="font-size: 0.75rem;">✓ Stärken:</strong>
|
||||
<ul style="font-size: 0.6875rem; margin-top: 0.25rem; padding-left: 1rem; line-height: 1.3;">
|
||||
${confidence.strengthIndicators.slice(0, 2).map(strength => `<li style="margin-bottom: 0.25rem;">${this.sanitizeText(strength)}</li>`).join('')}
|
||||
</ul>
|
||||
</div>
|
||||
` : ''}
|
||||
|
||||
${confidence.uncertaintyFactors && confidence.uncertaintyFactors.length > 0 ? `
|
||||
<div style="padding-top: 0.75rem; border-top: 1px solid var(--color-border);">
|
||||
<strong class="text-warning" style="font-size: 0.75rem;">⚠ Unsicherheiten:</strong>
|
||||
<ul style="font-size: 0.6875rem; margin-top: 0.25rem; padding-left: 1rem; line-height: 1.3;">
|
||||
${confidence.uncertaintyFactors.slice(0, 2).map(factor => `<li style="margin-bottom: 0.25rem;">${this.sanitizeText(factor)}</li>`).join('')}
|
||||
</ul>
|
||||
</div>
|
||||
` : ''}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
renderWorkflowTool(tool) {
|
||||
const hasValidProjectUrl = isToolHosted(tool);
|
||||
const priorityColors = {
|
||||
high: 'var(--color-error)',
|
||||
medium: 'var(--color-warning)',
|
||||
low: 'var(--color-accent)'
|
||||
};
|
||||
|
||||
return `
|
||||
<div class="tool-recommendation ${this.getToolClass(tool, 'recommendation')}" onclick="window.showToolDetails('${tool.name}')" style="position: relative;">
|
||||
<div class="tool-rec-header">
|
||||
<h4 class="tool-rec-name">
|
||||
${tool.icon ? `<span style="margin-right: 0.5rem;">${tool.icon}</span>` : ''}
|
||||
${tool.name}
|
||||
</h4>
|
||||
<div class="flex items-center gap-2">
|
||||
<span class="tool-rec-priority ${tool.recommendation ? tool.recommendation.priority : tool.priority}"
|
||||
style="background-color: ${priorityColors[tool.recommendation ? tool.recommendation.priority : tool.priority]}; color: white; padding: 0.25rem 0.5rem; border-radius: 1rem; font-size: 0.75rem;">
|
||||
${tool.recommendation ? tool.recommendation.priority : tool.priority}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
${tool.confidence ? this.renderConfidenceIndicator(tool.confidence) : ''}
|
||||
|
||||
<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;">
|
||||
"${this.sanitizeText(tool.justification || (tool.recommendation && tool.recommendation.justification) || `Empfohlen für ${tool.phase}`)}"
|
||||
</div>
|
||||
|
||||
<div style="font-size: 0.75rem; color: var(--color-text-secondary);">
|
||||
${this.renderToolBadges(tool)}
|
||||
<div style="margin-top: 0.5rem;">
|
||||
${tool.type === 'method' ? 'Methode' : tool.platforms.join(', ') + ' • ' + tool.license}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
renderDetailedTool(tool, recommendation, rank) {
|
||||
const rankColors = { 1: 'var(--color-accent)', 2: 'var(--color-primary)', 3: 'var(--color-warning)' };
|
||||
const suitabilityColors = { high: 'var(--color-accent)', medium: 'var(--color-warning)', low: 'var(--color-text-secondary)' };
|
||||
|
||||
return `
|
||||
<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 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;">
|
||||
${this.getSuitabilityText(recommendation.suitability_score)}
|
||||
</span>
|
||||
${this.renderToolBadges(tool)}
|
||||
</div>
|
||||
${recommendation.confidence ? this.renderConfidenceIndicator(recommendation.confidence) : ''}
|
||||
</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;">${this.sanitizeText(recommendation.detailed_explanation)}</div>
|
||||
|
||||
${recommendation.implementation_approach ? `
|
||||
<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;">${this.sanitizeText(recommendation.implementation_approach)}</div>
|
||||
` : ''}
|
||||
</div>
|
||||
|
||||
${this.renderProsAndCons(recommendation.pros, recommendation.cons)}
|
||||
${this.renderToolMetadata(tool)}
|
||||
${recommendation.alternatives ? this.renderAlternatives(recommendation.alternatives) : ''}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
renderHeader(title, query) {
|
||||
return `
|
||||
<div style="text-align: center; margin-bottom: 2rem; padding: 1.5rem; background: linear-gradient(135deg, var(--color-primary) 0%, #525252 100%); color: white; border-radius: 0.75rem;">
|
||||
@@ -1099,7 +1248,7 @@ class AIQueryInterface {
|
||||
}
|
||||
|
||||
renderWorkflowTool(tool) {
|
||||
const hasValidProjectUrl = this.isToolHosted(tool);
|
||||
const hasValidProjectUrl = isToolHosted(tool);
|
||||
const priorityColors = {
|
||||
high: 'var(--color-error)',
|
||||
medium: 'var(--color-warning)',
|
||||
@@ -1142,7 +1291,10 @@ class AIQueryInterface {
|
||||
const fullTool = tools.find(t => t.name === toolRec.name);
|
||||
if (!fullTool) return '';
|
||||
|
||||
return this.renderDetailedTool(fullTool, toolRec, index + 1);
|
||||
return this.renderDetailedTool(fullTool, {
|
||||
...toolRec,
|
||||
confidence: toolRec.confidence
|
||||
}, index + 1);
|
||||
}).join('')}
|
||||
</div>
|
||||
`;
|
||||
@@ -1256,7 +1408,7 @@ class AIQueryInterface {
|
||||
|
||||
renderToolBadges(tool) {
|
||||
const isMethod = tool.type === 'method';
|
||||
const hasValidProjectUrl = this.isToolHosted(tool);
|
||||
const hasValidProjectUrl = isToolHosted(tool);
|
||||
|
||||
let badges = '';
|
||||
if (isMethod) {
|
||||
@@ -1300,16 +1452,9 @@ class AIQueryInterface {
|
||||
.trim();
|
||||
}
|
||||
|
||||
isToolHosted(tool) {
|
||||
return tool.projectUrl !== undefined &&
|
||||
tool.projectUrl !== null &&
|
||||
tool.projectUrl !== "" &&
|
||||
tool.projectUrl.trim() !== "";
|
||||
}
|
||||
|
||||
getToolClass(tool, context = 'card') {
|
||||
const isMethod = tool.type === 'method';
|
||||
const hasValidProjectUrl = this.isToolHosted(tool);
|
||||
const hasValidProjectUrl = isToolHosted(tool);
|
||||
|
||||
if (context === 'recommendation') {
|
||||
if (isMethod) return 'method';
|
||||
@@ -1402,5 +1547,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
aiInterface.hideError();
|
||||
}
|
||||
};
|
||||
window.isToolHosted = window.isToolHosted || isToolHosted
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user