diff --git a/frontend/src/app.css b/frontend/src/app.css index 2900609..29877e8 100644 --- a/frontend/src/app.css +++ b/frontend/src/app.css @@ -5320,12 +5320,6 @@ html.modal-scroll-locked .app-main { line-height: 1.35; } -.skill-tree__group-label--skill-group { - font-weight: 500; - color: var(--text2); - font-size: 0.84rem; -} - .multi-assoc-block { border: 1px solid var(--border); border-radius: 8px; diff --git a/frontend/src/components/SkillTreePickerPanel.jsx b/frontend/src/components/SkillTreePickerPanel.jsx index d6647fb..e127a1a 100644 --- a/frontend/src/components/SkillTreePickerPanel.jsx +++ b/frontend/src/components/SkillTreePickerPanel.jsx @@ -55,11 +55,7 @@ function SkillTreeNodes({ nodes, depth, expanded, exclude, onToggle, onPickSkill ) : ( )} - + {node.label} @@ -82,7 +78,7 @@ function SkillTreeNodes({ nodes, depth, expanded, exclude, onToggle, onPickSkill } /** - * Ausklappbare Baumliste: Hauptgruppe → Kategorie (beide standard offen) → Fähigkeiten-Gruppe (standard zu). + * Ausklappbare Baumliste: Hauptgruppe → Kategorie → Fähigkeit (Hauptgruppe und Kategorie standard offen). */ export default function SkillTreePickerPanel({ skills = [], diff --git a/frontend/src/utils/skillCatalogTree.js b/frontend/src/utils/skillCatalogTree.js index cdf62ed..64de7bb 100644 --- a/frontend/src/utils/skillCatalogTree.js +++ b/frontend/src/utils/skillCatalogTree.js @@ -80,33 +80,18 @@ export function buildSkillCatalogTree(skills) { if (a.sortOrder !== b.sortOrder) return a.sortOrder - b.sortOrder return a.label.localeCompare(b.label, 'de') }) - .map((cat) => { - const skillLeaves = [...cat.skills].sort(bySortThenName).map((skill) => ({ + .map((cat) => ({ + key: cat.key, + type: cat.type, + label: cat.label, + children: [...cat.skills].sort(bySortThenName).map((skill) => ({ key: `s-${skill.id}`, type: 'skill', label: (skill.name || '').trim() || `#${skill.id}`, skillId: Number(skill.id), skill, - })) - const n = skillLeaves.length - return { - key: cat.key, - type: cat.type, - label: cat.label, - children: - n > 0 - ? [ - { - key: `${cat.key}-skills`, - type: 'skillGroup', - label: n === 1 ? '1 Fähigkeit' : `${n} Fähigkeiten`, - skillCount: n, - children: skillLeaves, - }, - ] - : [], - } - }), + })), + })), })) } @@ -132,8 +117,7 @@ export function collectSkillLeavesFromTree(tree, excludeIds) { out.push({ id: n.skillId, label: n.label, pathLabel, skill: n.skill }) } } else if (n.children?.length) { - const nextPath = n.type === 'skillGroup' ? pathParts : [...pathParts, n.label] - walk(n.children, nextPath) + walk(n.children, [...pathParts, n.label]) } } } @@ -153,9 +137,6 @@ export function filterSkillTreeByQuery(tree, query) { if (n.type === 'skill') { const hay = `${n.label} ${skillCatalogPathLabel(n.skill)}`.toLowerCase() if (hay.includes(q)) result.push(n) - } else if (n.type === 'skillGroup') { - const kids = filterNodes(n.children || []) - if (kids.length) result.push({ ...n, children: kids }) } else { const kids = filterNodes(n.children || []) if (kids.length) result.push({ ...n, children: kids }) @@ -166,7 +147,7 @@ export function filterSkillTreeByQuery(tree, query) { return filterNodes(tree) } -/** Alle aufklappbaren Knoten (inkl. Fähigkeiten-Gruppen unter Kategorien). */ +/** Alle aufklappbaren Knoten (Hauptgruppe und Kategorie). */ export function allExpandableKeys(tree) { const keys = [] const walk = (nodes) => { @@ -181,7 +162,7 @@ export function allExpandableKeys(tree) { return keys } -/** Standard: Hauptgruppe + Kategorie offen, Fähigkeiten-Liste zugeklappt. */ +/** Standard: Hauptgruppe und Kategorie aufgeklappt (Fähigkeiten direkt darunter sichtbar). */ export function defaultExpandedKeysForSkillTree(tree) { const keys = [] const walk = (nodes) => { diff --git a/frontend/src/utils/skillCatalogTree.test.js b/frontend/src/utils/skillCatalogTree.test.js index 723c3eb..bbd06fd 100644 --- a/frontend/src/utils/skillCatalogTree.test.js +++ b/frontend/src/utils/skillCatalogTree.test.js @@ -44,9 +44,9 @@ describe('skillCatalogTree', () => { expect(tree[0].label).toBe('Karate') expect(tree[0].children).toHaveLength(2) expect(tree[0].children[0].label).toBe('Kata') - const kataSkills = tree[0].children[0].children[0] - expect(kataSkills.type).toBe('skillGroup') - expect(kataSkills.children[0].skillId).toBe(2) + const kataSkill = tree[0].children[0].children[0] + expect(kataSkill.type).toBe('skill') + expect(kataSkill.skillId).toBe(2) }) it('defaultExpandedKeysForSkillTree opens main and category only', () => { @@ -54,7 +54,7 @@ describe('skillCatalogTree', () => { const keys = defaultExpandedKeysForSkillTree(tree) expect(keys).toContain('m-10') expect(keys.some((k) => k.includes('c-21'))).toBe(true) - expect(keys.some((k) => k.endsWith('-skills'))).toBe(false) + expect(keys.some((k) => k.startsWith('s-'))).toBe(false) }) it('skillCatalogPathLabel', () => { @@ -72,8 +72,7 @@ describe('skillCatalogTree', () => { const tree = buildSkillCatalogTree(sample) const filtered = filterSkillTreeByQuery(tree, 'dachi') const kihon = filtered[0].children.find((c) => c.label === 'Kihon') - const group = kihon?.children?.[0] - expect(group?.children?.some((s) => s.skillId === 1)).toBe(true) + expect(kihon?.children?.some((s) => s.skillId === 1)).toBe(true) }) it('catalogSkillsForSelection lists unassigned buckets', () => {