From b52d44d0255b2d1e1ecdb77355932106ba416e54 Mon Sep 17 00:00:00 2001 From: Ilyassbennanii Date: Thu, 4 Dec 2025 10:35:03 +0100 Subject: [PATCH 1/2] Learnpath: Fix session category display only in Learning Path sessions and add a star icon to category sessions - refs #1966 --- .../vue/components/lp/LpCategorySection.vue | 37 +++++--- assets/vue/views/lp/LpList.vue | 90 ++++++++++++++++--- 2 files changed, 103 insertions(+), 24 deletions(-) diff --git a/assets/vue/components/lp/LpCategorySection.vue b/assets/vue/components/lp/LpCategorySection.vue index e0bceeea96d..870fdb2ccbc 100644 --- a/assets/vue/components/lp/LpCategorySection.vue +++ b/assets/vue/components/lp/LpCategorySection.vue @@ -20,6 +20,7 @@ const props = defineProps({ ringDash: { type: Function, required: true }, ringValue: { type: Function, required: true }, buildDates: { type: Function, required: false }, + isSessionCategory: { type: Boolean, default: false }, }) const emit = defineEmits([ "open","edit","report","settings","build", @@ -111,15 +112,23 @@ function onChangeCat() { -

{{ displayTitle }}

+

+ {{ displayTitle }} + + +

{{ localList.length }} {{ t('Learning paths') }}
diff --git a/assets/vue/views/lp/LpList.vue b/assets/vue/views/lp/LpList.vue index f43fff7746b..b98314c8b90 100644 --- a/assets/vue/views/lp/LpList.vue +++ b/assets/vue/views/lp/LpList.vue @@ -150,13 +150,13 @@
- + { } onMounted(load) -const categorizedGroups = computed(() => { - const rows = [] - for (const cat of categories.value) { - const list = catLists.value[cat.iid] ?? [] - if (canEdit.value || list.length) { - rows.push([cat, list]) - } +// build the candidate fields object +function inspectCategorySessionCandidates(cat) { + const c = { + sid: cat?.sid, session: cat?.session, sessionId: cat?.sessionId, + courseSessionId: cat?.courseSessionId, course_session: cat?.course_session, + session_iid: cat?.session_iid, + } + if (Array.isArray(cat?.resourceLinkListFromEntity)) { + cat.resourceLinkListFromEntity.forEach((l, i) => { + c[`resourceLink_${i}_session`] = l?.session + c[`resourceLink_${i}_courseSessionId`] = l?.courseSessionId ?? l?.course_session + }) + } + return c +} + +function extractNumbersFromValue(v) { + if (v == null) return [] + if (typeof v === "number") return Number.isFinite(v) ? [v] : [] + if (typeof v === "string") { + const m = v.match(/-?\d+/g) + return m ? m.map(Number).filter(Number.isFinite) : [] + } + if (Array.isArray(v)) return v.flatMap(extractNumbersFromValue) + if (typeof v === "object") return Object.values(v).flatMap(extractNumbersFromValue) + return [] +} + +function getCategorySessionId(cat) { + if (!cat || typeof cat !== "object") return { catSid: 0, hasSessionField: false, candidates: {} } + const candidates = inspectCategorySessionCandidates(cat) + for (const val of Object.values(candidates)) { + if (val == null || String(val).trim() === "") continue + const nums = extractNumbersFromValue(val) + const found = nums.find(n => n !== 0) + if (found !== undefined) return { catSid: Number(found), hasSessionField: true, candidates } + } + const hasSessionField = Object.values(candidates).some(v => v != null && String(v).trim() !== "") + return { catSid: 0, hasSessionField, candidates } +} + +const filteredCategories = computed(() => { + if (!Array.isArray(categories.value)) return [] + const s = Number(sid.value) || 0 + const lpCatIdsInItems = new Set((items.value ?? []).map(lp => lp?.category?.iid).filter(id => id != null)) + + const matchesSessionValue = (candidates, sNum) => { + if (!candidates || typeof candidates !== "object") return false + return Object.values(candidates).some(v => { + if (v == null || String(v).trim() === "") return false + if (Number(String(v)) === sNum) return true + if (extractNumbersFromValue(v).some(n => n === sNum)) return true + if (String(v).trim() === String(sNum)) return true + return false + }) } - return rows + + return categories.value.filter(cat => { + const { catSid, hasSessionField, candidates } = getCategorySessionId(cat) + if (s > 0) { + if (catSid === s) return true + if (hasSessionField && matchesSessionValue(candidates, s)) return true + if (!hasSessionField && catSid === 0) return true + if (lpCatIdsInItems.has(cat.iid)) return true + return false + } + return !hasSessionField && catSid === 0 + }) +}) + +const categorizedGroups = computed(() => { + const cats = filteredCategories.value ?? [] + return cats.map(cat => { + const list = (catLists.value[cat.iid] ?? []).slice() + const { catSid, hasSessionField } = getCategorySessionId(cat) + const isSessionCategory = !!(hasSessionField && catSid !== 0) + return [cat, list, isSessionCategory] + }).filter(([_, list]) => (list && list.length) || canEdit.value) }) function rebuildListsFromItems() { From f2d804bc53c1b4d3eafb7d1bf60c5970a9ac88e9 Mon Sep 17 00:00:00 2001 From: Ilyassbennanii Date: Thu, 4 Dec 2025 10:43:28 +0100 Subject: [PATCH 2/2] Remove excess spaces --- .../vue/components/lp/LpCategorySection.vue | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/assets/vue/components/lp/LpCategorySection.vue b/assets/vue/components/lp/LpCategorySection.vue index 870fdb2ccbc..df46eadfbbb 100644 --- a/assets/vue/components/lp/LpCategorySection.vue +++ b/assets/vue/components/lp/LpCategorySection.vue @@ -127,8 +127,8 @@ function onChangeCat() {
{{ localList.length }} {{ t('Learning paths') }}