Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion assets/vue/components/lp/LpCategorySection.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -174,7 +175,15 @@ const toggleOpen = () => {
></span>
</template>

<h2 class="text-body-1 font-semibold text-gray-90">{{ displayTitle }}</h2>
<h2 class="text-body-1 font-semibold text-gray-90">
<span>{{ displayTitle }}</span>
<!-- Display the star if it's a session category; remove the check on category.type -->
<span
v-if="isSessionCategory"
class="ml-2 text-warning"
title="Category created for a session"
>★</span>
</h2>
</div>

<div class="flex items-center gap-2">
Expand Down
90 changes: 80 additions & 10 deletions assets/vue/views/lp/LpList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,13 @@
</template>
</Draggable>
</div>

<LpCategorySection
v-for="[cat, list] in categorizedGroups"
v-for="[cat, list, isSession] in categorizedGroups"
:key="cat.iid || cat.title"
:title="cat.title"
:category="cat"
:list="list"
:isSessionCategory="isSession"
:canEdit="canEdit"
:ringDash="ringDash"
:ringValue="ringValue"
Expand All @@ -176,6 +176,7 @@
@export-pdf="onExportPdf"
@reorder="(ids) => onReorderCategory(cat, ids)"
/>

</template>
</div>
<ExportPdfDialog
Expand Down Expand Up @@ -390,15 +391,84 @@ const load = async () => {
}
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() {
Expand Down
Loading