shinkan-jinkendo/frontend/src/utils/exerciseListSessionState.js
Lars 14b005e9b8
All checks were successful
Deploy Development / deploy (push) Successful in 42s
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 33s
Test Suite / playwright-tests (push) Successful in 1m18s
Enhance exercise selection and display features
- Introduced new CSS styles for exercise cards and selection sections, improving visual feedback for selected exercises.
- Updated ExerciseListCard to support a new `selectionPinned` prop, allowing for a badge display on selected exercises.
- Refactored selection handling in ExercisesListPageRoot to manage selected entries more effectively, replacing the previous Set-based approach.
- Enhanced SaveSelectedExercisesAsModuleModal to support appending exercises to existing modules, improving module management capabilities.
- Updated session state handling to include selected entries, ensuring persistence across sessions.
2026-05-20 07:03:15 +02:00

52 lines
1.8 KiB
JavaScript

import { INITIAL_EXERCISE_LIST_FILTERS, mergeExerciseListPrefsFromApi } from '../constants/exerciseListFilters'
import { normalizeSelectedEntries } from './exerciseListSelection'
const STORAGE_KEY = 'shinkan.exerciseList.session.v1'
function safeParse(raw) {
if (!raw) return null
try {
return JSON.parse(raw)
} catch {
return null
}
}
/** @returns {{ filters: object, searchInput: string, aiSearchInput: string, mineOnly: boolean, selectedEntries: object[] } | null} */
export function readExerciseListSessionState() {
if (typeof sessionStorage === 'undefined') return null
const parsed = safeParse(sessionStorage.getItem(STORAGE_KEY))
if (!parsed || typeof parsed !== 'object') return null
const filters =
parsed.filters && typeof parsed.filters === 'object'
? mergeExerciseListPrefsFromApi(parsed.filters)
: { ...INITIAL_EXERCISE_LIST_FILTERS }
return {
filters,
searchInput: typeof parsed.searchInput === 'string' ? parsed.searchInput : '',
aiSearchInput: typeof parsed.aiSearchInput === 'string' ? parsed.aiSearchInput : '',
mineOnly: !!parsed.mineOnly,
selectedEntries: normalizeSelectedEntries(parsed.selectedEntries),
}
}
export function writeExerciseListSessionState(state) {
if (typeof sessionStorage === 'undefined' || !state || typeof state !== 'object') return
try {
sessionStorage.setItem(
STORAGE_KEY,
JSON.stringify({
filters: state.filters ?? { ...INITIAL_EXERCISE_LIST_FILTERS },
searchInput: typeof state.searchInput === 'string' ? state.searchInput : '',
aiSearchInput: typeof state.aiSearchInput === 'string' ? state.aiSearchInput : '',
mineOnly: !!state.mineOnly,
selectedEntries: normalizeSelectedEntries(state.selectedEntries),
})
)
} catch {
/* quota / private mode */
}
}