All checks were successful
Deploy Development / deploy (push) Successful in 39s
Test Suite / pytest-backend (push) Successful in 35s
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 1m1s
- Bumped APP_VERSION to 0.8.121 and updated the changelog to reflect new features. - Introduced the ExerciseListFilterModal and ExerciseListBulkModal components, enhancing the exercise list functionality. - Modularized the ExerciseListPage to improve code organization and maintainability. - Added Playwright tests for the filter dialog functionality, ensuring proper user interaction and visibility.
84 lines
3.5 KiB
JavaScript
84 lines
3.5 KiB
JavaScript
import {
|
|
INITIAL_EXERCISE_LIST_FILTERS,
|
|
splitMnCatalogRules,
|
|
splitScalarCatalogRules,
|
|
} from '../constants/exerciseListFilters'
|
|
|
|
/** Dashboard-Deep-Link: ?mine=1, optional ?status=draft — überschreibt gespeicherte Prefs-Kombination. */
|
|
export function applyDashboardExerciseListUrl(mergedFromPrefs) {
|
|
try {
|
|
const sp = new URLSearchParams(window.location.search)
|
|
const mine = sp.get('mine') === '1' || sp.get('created_by_me') === '1'
|
|
const statusDraft = sp.get('status') === 'draft'
|
|
|
|
if (mine) {
|
|
const next = { ...INITIAL_EXERCISE_LIST_FILTERS }
|
|
if (statusDraft) {
|
|
next.status_rules = [{ key: 'url-dashboard-draft', id: 'draft', mode: 'require' }]
|
|
}
|
|
return next
|
|
}
|
|
|
|
if (statusDraft) {
|
|
return {
|
|
...mergedFromPrefs,
|
|
status_rules: [{ key: 'url-dashboard-draft', id: 'draft', mode: 'require' }],
|
|
}
|
|
}
|
|
return mergedFromPrefs
|
|
} catch {
|
|
return mergedFromPrefs
|
|
}
|
|
}
|
|
|
|
export function buildExerciseListQueryBase(filters, debouncedSearch, debouncedAiSearch, mineOnly) {
|
|
const q = {}
|
|
const n = (v) => (v === '' || v == null ? undefined : Number(v))
|
|
const ids = (arr) =>
|
|
Array.isArray(arr) && arr.length ? arr.map((x) => Number(x)).filter((x) => !Number.isNaN(x)) : undefined
|
|
const fMn = splitMnCatalogRules(filters.focus_rules)
|
|
if (fMn.includeIds.length) q.focus_area_must_include_ids = fMn.includeIds
|
|
if (fMn.excludeIds.length) q.focus_area_must_exclude_ids = fMn.excludeIds
|
|
if (filters.focus_only_without) q.focus_only_without_focus_areas = true
|
|
|
|
const fa = ids(filters.focus_area_ids)
|
|
if (fa?.length) q.focus_area_ids = fa
|
|
|
|
const sdMn = splitMnCatalogRules(filters.style_direction_rules)
|
|
if (sdMn.includeIds.length) q.style_direction_must_include_ids = sdMn.includeIds
|
|
if (sdMn.excludeIds.length) q.style_direction_must_exclude_ids = sdMn.excludeIds
|
|
const sdLegacy = ids(filters.style_direction_ids)
|
|
if (sdLegacy?.length) q.style_direction_ids = sdLegacy
|
|
|
|
const ttMn = splitMnCatalogRules(filters.training_type_rules)
|
|
if (ttMn.includeIds.length) q.training_type_must_include_ids = ttMn.includeIds
|
|
if (ttMn.excludeIds.length) q.training_type_must_exclude_ids = ttMn.excludeIds
|
|
const ttLegacy = ids(filters.training_type_ids)
|
|
if (ttLegacy?.length) q.training_type_ids = ttLegacy
|
|
|
|
const tgMn = splitMnCatalogRules(filters.target_group_rules)
|
|
if (tgMn.includeIds.length) q.target_group_must_include_ids = tgMn.includeIds
|
|
if (tgMn.excludeIds.length) q.target_group_must_exclude_ids = tgMn.excludeIds
|
|
const tgLegacy = ids(filters.target_group_ids)
|
|
if (tgLegacy?.length) q.target_group_ids = tgLegacy
|
|
|
|
const visMn = splitScalarCatalogRules(filters.visibility_rules)
|
|
if (visMn.includeVals.length) q.visibility_any = visMn.includeVals
|
|
if (visMn.excludeVals.length) q.visibility_exclude_any = visMn.excludeVals
|
|
|
|
const stMn = splitScalarCatalogRules(filters.status_rules)
|
|
if (stMn.includeVals.length) q.status_any = stMn.includeVals
|
|
if (stMn.excludeVals.length) q.status_exclude_any = stMn.excludeVals
|
|
|
|
const sk = ids(filters.skill_ids)
|
|
if (sk?.length) q.skill_ids = sk
|
|
if (filters.skill_min_level) q.skill_min_level = n(filters.skill_min_level)
|
|
if (filters.skill_max_level) q.skill_max_level = n(filters.skill_max_level)
|
|
if (filters.exclude_without_focus) q.exclude_without_focus = true
|
|
if (filters.include_archived) q.include_archived = true
|
|
if (debouncedSearch) q.search = debouncedSearch
|
|
if (debouncedAiSearch) q.ai_search = debouncedAiSearch
|
|
if (mineOnly) q.created_by_me = true
|
|
return q
|
|
}
|