Add defaultCollapsed prop to SkillTree components for improved user experience
All checks were successful
Deploy Development / deploy (push) Successful in 44s
Test Suite / pytest-backend (push) Successful in 41s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 12s
Test Suite / k6 /health Baseline (push) Successful in 34s
Test Suite / playwright-tests (push) Successful in 1m15s

- Introduced a `defaultCollapsed` prop in `SkillTreeMultiSelect` and `SkillTreePickerPanel` to control the initial expansion state of skill trees.
- Updated `SkillTreeSelect` to accept a `defaultCollapsed` prop, enhancing flexibility in component usage.
- Adjusted state management in `SkillTreePickerPanel` to respect the `defaultCollapsed` setting, improving user interaction with skill selection.
This commit is contained in:
Lars 2026-05-20 11:05:27 +02:00
parent 3067b2e6a8
commit 46feb4c867
4 changed files with 12 additions and 3 deletions

View File

@ -122,6 +122,7 @@ export default function SkillTreeMultiSelect({
searchQuery={query} searchQuery={query}
onPickSkill={(id) => addId(id)} onPickSkill={(id) => addId(id)}
pickMode="multi" pickMode="multi"
defaultCollapsed
/> />
) : ( ) : (
<ul className="multiselect-combo__list" role="listbox"> <ul className="multiselect-combo__list" role="listbox">

View File

@ -84,6 +84,8 @@ export default function SkillTreePickerPanel({
onPickSkill, onPickSkill,
pickMode = 'single', pickMode = 'single',
className = '', className = '',
/** true: nur Hauptgruppen sichtbar, bis der Nutzer aufklappt (Filter) */
defaultCollapsed = true,
}) { }) {
const exclude = useMemo(() => normExclude(excludeIds), [excludeIds]) const exclude = useMemo(() => normExclude(excludeIds), [excludeIds])
const fullTree = useMemo(() => buildSkillCatalogTree(skills), [skills]) const fullTree = useMemo(() => buildSkillCatalogTree(skills), [skills])
@ -96,12 +98,16 @@ export default function SkillTreePickerPanel({
useEffect(() => { useEffect(() => {
if (searchQuery.trim()) { if (searchQuery.trim()) {
setExpanded(new Set(allExpandableKeys(displayTree))) setExpanded(new Set(allExpandableKeys(displayTree)))
} else if (defaultCollapsed) {
setExpanded(new Set())
} }
}, [searchQuery, displayTree]) }, [searchQuery, displayTree, defaultCollapsed])
useEffect(() => { useEffect(() => {
if (!defaultCollapsed) {
setExpanded(new Set(allExpandableKeys(fullTree))) setExpanded(new Set(allExpandableKeys(fullTree)))
}, [fullTree]) }
}, [fullTree, defaultCollapsed])
const onToggle = useCallback((key) => { const onToggle = useCallback((key) => {
setExpanded((prev) => { setExpanded((prev) => {

View File

@ -75,6 +75,7 @@ export default function SkillTreeSelect({
searchQuery={query} searchQuery={query}
onPickSkill={pick} onPickSkill={pick}
pickMode="single" pickMode="single"
defaultCollapsed={false}
/> />
</div> </div>
</div> </div>

View File

@ -16,6 +16,7 @@ import {
import { autoScrollForDragNearEdges } from '../../utils/dragAutoScroll' import { autoScrollForDragNearEdges } from '../../utils/dragAutoScroll'
import SkillTreeSelect from '../SkillTreeSelect' import SkillTreeSelect from '../SkillTreeSelect'
import { skillCatalogPathLabel } from '../../utils/skillCatalogTree' import { skillCatalogPathLabel } from '../../utils/skillCatalogTree'
import { SKILL_LEVEL_OPTIONS, normalizeSkillLevelSlug } from '../../constants/skillLevels'
import { useAuth } from '../../context/AuthContext' import { useAuth } from '../../context/AuthContext'
import { useToast } from '../../context/ToastContext' import { useToast } from '../../context/ToastContext'
import { import {