shinkan-jinkendo/frontend/src/components/skills/SkillProfileCompact.jsx
Lars 2de4c0b7c9
All checks were successful
Deploy Development / deploy (push) Successful in 40s
Test Suite / pytest-backend (push) Successful in 38s
Test Suite / lint-backend (push) Successful in 1s
Test Suite / build-frontend (push) Successful in 12s
Test Suite / k6 /health Baseline (push) Successful in 33s
Test Suite / playwright-tests (push) Successful in 1m17s
Refactor Skill Scoring Functions and Enhance Corpus Handling
- Introduced new helper functions for managing artifact type corpus, improving code organization and readability.
- Updated the `compute_club_corpus_reference` function to utilize the new corpus handling methods, enhancing clarity and maintainability.
- Refactored skill profile functions to leverage the new corpus structure, ensuring consistent data retrieval across different artifact types.
- Improved the handling of visibility clauses for library content, streamlining database queries for skill profiles.
- Enhanced the batch skill profile summary function to aggregate reference data by artifact type, improving performance and accuracy.
2026-05-21 10:17:22 +02:00

64 lines
2.1 KiB
JavaScript

import React from 'react'
import {
formatClubPercent,
formatSkillWeight,
kpiRowsFromSummary,
peerPercentSuffix,
} from '../../utils/skillProfileListHelpers'
/**
* Kleine KPI-Kacheln: je Unterkategorie die Top-Fähigkeit (Listen/Karten).
*/
export default function SkillProfileCompact({
summary,
artifactType = 'training_module',
loading = false,
emptyText = 'Keine Fähigkeiten',
displayLimit = 24,
highlightSkillIds = [],
}) {
if (loading) {
return (
<div className="skill-kpi-grid skill-kpi-grid--loading" aria-busy="true">
<span className="form-sub"></span>
</div>
)
}
const rows = kpiRowsFromSummary(summary, { limit: displayLimit })
const highlight = new Set((highlightSkillIds || []).map(String))
const peerLabel = peerPercentSuffix(artifactType)
if (!rows.length) {
return summary ? <p className="form-sub skill-kpi-grid--empty">{emptyText}</p> : null
}
return (
<ul className="skill-kpi-grid" aria-label="Fähigkeiten je Kategorie">
{rows.map((row) => {
const highlighted = highlight.has(String(row.skill_id))
const isBest = row.is_club_best_for_skill || row.universal_percent >= 100
return (
<li
key={`${row.category_name}-${row.skill_id}`}
className={
'skill-kpi-tile' +
(highlighted ? ' skill-kpi-tile--highlight' : '') +
(isBest ? ' skill-kpi-tile--best' : '')
}
title={`${row.category_name}: ${row.skill_name} — Gewicht ${formatSkillWeight(row.weight ?? row.score)}, ${formatClubPercent(row.universal_percent)} unter ${peerLabel}`}
>
<span className="skill-kpi-tile__cat">{row.category_name}</span>
<span className="skill-kpi-tile__name">{row.skill_name}</span>
<span className="skill-kpi-tile__score">{formatSkillWeight(row.weight ?? row.score)}</span>
<span className="skill-kpi-tile__pct">
{isBest ? '★ ' : ''}
{formatClubPercent(row.universal_percent)} {peerLabel}
</span>
</li>
)
})}
</ul>
)
}