// src/utils/toolRendering.ts - Consolidated tool rendering utilities import { Tool, escapeHtml, sanitizeText, truncateText, getConfidenceColor } from './uiHelpers.js'; // TOOL CLASSIFICATION UTILITIES (consolidates repeated logic across components) export interface ToolClassification { isMethod: boolean; isConcept: boolean; isHosted: boolean; isOpenSource: boolean; hasKnowledgebase: boolean; } export function classifyTool(tool: Tool): ToolClassification { const isMethod = tool.type === 'method'; const isConcept = tool.type === 'concept'; const isHosted = tool.projectUrl !== undefined && tool.projectUrl !== null && tool.projectUrl !== "" && tool.projectUrl.trim() !== ""; const isOpenSource = tool.license !== 'Proprietary'; const hasKnowledgebase = tool.knowledgebase === true; return { isMethod, isConcept, isHosted, isOpenSource, hasKnowledgebase }; } export function getToolCardClass(tool: Tool): string { const { isMethod, isConcept, isHosted, isOpenSource } = classifyTool(tool); if (isConcept) return 'card card-concept tool-card cursor-pointer'; if (isMethod) return 'card card-method tool-card cursor-pointer'; if (isHosted) return 'card card-hosted tool-card cursor-pointer'; if (isOpenSource) return 'card card-oss tool-card cursor-pointer'; return 'card tool-card cursor-pointer'; } export function getToolChipClass(tool: Tool): string { const { isMethod, isHosted, isOpenSource } = classifyTool(tool); if (isMethod) return 'tool-chip tool-chip-method'; if (isHosted) return 'tool-chip tool-chip-hosted'; if (isOpenSource) return 'tool-chip tool-chip-oss'; return 'tool-chip'; } export function getRecommendationClass(tool: Tool): string { const { isMethod, isHosted, isOpenSource } = classifyTool(tool); if (isMethod) return 'method'; if (isHosted) return 'hosted'; if (isOpenSource) return 'oss'; return ''; } // BADGE RENDERING UTILITIES (consolidates badge logic across components) export function renderToolBadges(tool: Tool): string { const { isMethod, isConcept, isHosted, hasKnowledgebase } = classifyTool(tool); let badges = ''; if (isConcept) { badges += 'Konzept'; } else if (isMethod) { badges += 'Methode'; } else if (isHosted) { badges += 'CC24-Server'; } if (hasKnowledgebase) { badges += 'đź“–'; } return badges; } export function renderInlineBadges(tool: Tool): string { const { isMethod, isHosted, hasKnowledgebase } = classifyTool(tool); let badges = ''; if (isMethod) { badges += 'Methode'; } else if (isHosted) { badges += 'CC24-Server'; } if (hasKnowledgebase) { badges += 'đź“–'; } return badges; } // METADATA RENDERING UTILITIES (consolidates metadata display logic) export function renderToolMetadata(tool: Tool, compact: boolean = false): string { const { isMethod, isConcept } = classifyTool(tool); const domains = tool.domains || []; const phases = tool.phases || []; const domainsText = domains.length > 0 ? domains.join(', ') : 'Domain-agnostic'; const phasesText = phases.join(', '); if (compact) { return `
${isMethod ? 'Methode' : isConcept ? 'Konzept' : tool.platforms?.slice(0, 2).join(', ')} • ${tool.skillLevel}
`; } let metadataHTML = `
`; if (!isConcept) { metadataHTML += `
Betriebssystem: ${(tool.platforms || []).join(', ')}
Skill Level: ${tool.skillLevel}
Lizenzmodell: ${tool.license}
Deployment: ${tool.accessType}
`; } else { metadataHTML += `
Skill Level: ${tool.skillLevel}
`; } metadataHTML += `
Einsatzgebiete: ${domainsText}
Ermittlungsphasen: ${phasesText}
`; return metadataHTML; } // BUTTON RENDERING UTILITIES (consolidates button logic across components) export function renderToolButtons(tool: Tool, stopPropagation: boolean = true): string { const { isMethod, isConcept, isHosted } = classifyTool(tool); const onClickAttr = stopPropagation ? 'onclick="event.stopPropagation();"' : ''; if (isConcept) { return ` Mehr erfahren `; } if (isMethod) { return ` Zur Methode `; } if (isHosted) { return `
Homepage Zugreifen
`; } return ` Software-Homepage `; } export function renderExtendedToolLinks(tool: Tool): string { const { hasKnowledgebase } = classifyTool(tool); let linksHTML = renderToolButtons(tool, false); if (hasKnowledgebase) { const kbId = tool.name.toLowerCase() .replace(/[^a-z0-9\s-]/g, '') .replace(/\s+/g, '-') .replace(/-+/g, '-') .replace(/^-|-$/g, ''); linksHTML += ` Knowledgebase anzeigen `; } return linksHTML; } // TAG RENDERING UTILITIES (consolidates tag display logic) export function renderTagCloud(tool: Tool, maxTags: number = 8): string { const tags = tool.tags || []; return tags.slice(0, maxTags).map(tag => `${escapeHtml(tag)}` ).join(''); } export function renderRelatedItems( tool: Tool, allTools: Tool[], modalType: string = 'primary' ): string { const relatedConcepts = tool.related_concepts || []; const relatedSoftware = tool.related_software || []; let html = ''; if (relatedConcepts.length > 0 && modalType === 'primary') { const conceptLinks = relatedConcepts.map(conceptName => { const concept = allTools.find(t => t.name === conceptName && t.type === 'concept'); if (concept) { return ` `; } return `${conceptName}`; }).join(''); const isMobile = window.innerWidth <= 768; const collapseOnMobile = isMobile && relatedConcepts.length > 2; html += `
Verwandte Konzepte: ${collapseOnMobile ? ` ` : ''}
${conceptLinks}
`; } if (relatedSoftware.length > 0 && modalType === 'primary') { const softwareLinks = relatedSoftware.map(softwareName => { const software = allTools.find(t => t.name === softwareName && (t.type === 'software' || t.type === 'method')); if (software) { const { isHosted, isMethod } = classifyTool(software); const bgColor = isMethod ? 'var(--color-method-bg)' : isHosted ? 'var(--color-hosted-bg)' : 'var(--color-oss-bg)'; const borderColor = isMethod ? 'var(--color-method)' : isHosted ? 'var(--color-hosted)' : 'var(--color-oss)'; return ` `; } return `${softwareName}`; }).join(''); const isMobile = window.innerWidth <= 768; const collapseOnMobile = isMobile && relatedSoftware.length > 2; html += `
Verwandte Software: ${collapseOnMobile ? ` ` : ''}
${softwareLinks}
`; } return html; } // CONFIDENCE RENDERING UTILITIES (consolidates AI confidence display logic) export interface ConfidenceData { overall: number; semanticRelevance: number; taskSuitability: number; uncertaintyFactors: string[]; strengthIndicators: string[]; } export function renderConfidenceTooltip(confidence: ConfidenceData): string { const confidenceColor = getConfidenceColor(confidence.overall); const tooltipId = `tooltip-${Math.random().toString(36).substr(2, 9)}`; return `
${confidence.overall}%
`; } // SUITABILITY UTILITIES (consolidates suitability display logic) export function getSuitabilityText(score: string): string { const texts = { high: 'GUT GEEIGNET', medium: 'GEEIGNET', low: 'VIELLEICHT GEEIGNET' }; return texts[score] || 'GEEIGNET'; } export function getSuitabilityColor(score: string): string { const colors = { high: 'var(--color-accent)', medium: 'var(--color-warning)', low: 'var(--color-text-secondary)' }; return colors[score] || 'var(--color-warning)'; }