Skip to content

Commit 7cc8524

Browse files
Merge pull request #7429 from christianbeeznest/GH-5151
Learnpath: Implement SCORM package replacement (LP update) - refs #5151
2 parents 762ef8a + 0da7acc commit 7cc8524

7 files changed

Lines changed: 879 additions & 178 deletions

File tree

assets/vue/components/lp/LpCategorySection.vue

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const props = defineProps({
2222
buildDates: { type: Function, required: false },
2323
isSessionCategory: { type: Boolean, default: false },
2424
})
25+
2526
const emit = defineEmits([
2627
"open",
2728
"edit",
@@ -33,6 +34,7 @@ const emit = defineEmits([
3334
"delete",
3435
"export-scorm",
3536
"export-pdf",
37+
"update-scorm",
3638
"reorder",
3739
"toggle-auto-launch",
3840
])
@@ -73,20 +75,24 @@ const goCat = (action, extraParams = {}) => {
7375
})
7476
window.location.assign(url)
7577
}
78+
7679
const onCatEdit = () => goCat("add_lp_category")
7780
const onCatAddUsers = () => goCat("add_users_to_category")
81+
7882
const onCatToggleVisibility = () => {
7983
const vis = props.category.visibility ?? props.category.visible
8084
const next = typeof vis === "number" ? (vis ? 0 : 1) : 1
8185
goCat("toggle_category_visibility", { new_status: next })
8286
}
87+
8388
const onCatTogglePublish = () => {
8489
const pub = props.category.isPublished ?? props.category.published
8590
let next = 1
8691
if (typeof pub === "number") next = pub ? 0 : 1
8792
if (typeof pub === "string") next = pub === "v" ? 0 : 1
8893
goCat("toggle_category_publish", { new_status: next })
8994
}
95+
9096
const onCatDelete = () => {
9197
// Do not allow deletion if category is not empty
9298
if (localList.value.length > 0) {
@@ -103,11 +109,14 @@ const onCatDelete = () => {
103109
104110
const isOpen = ref(true)
105111
const storageKey = computed(() => `lpCatOpen:${props.category?.iid || props.title}`)
112+
106113
onMounted(() => {
107114
const saved = localStorage.getItem(storageKey.value)
108115
if (saved !== null) isOpen.value = saved === "1"
109116
})
117+
110118
watch(isOpen, (v) => localStorage.setItem(storageKey.value, v ? "1" : "0"))
119+
111120
const panelId = computed(() => `cat-panel-${props.category?.iid || props.title}`)
112121
const toggleOpen = () => {
113122
if (localList.value.length) isOpen.value = !isOpen.value
@@ -207,6 +216,7 @@ const toggleOpen = () => {
207216
></i>
208217
</span>
209218
</template>
219+
210220
<template #menu>
211221
<div
212222
class="absolute right-0 top-full mt-2 w-60 bg-white border border-gray-25 rounded-xl shadow-xl p-1 z-50"
@@ -217,26 +227,32 @@ const toggleOpen = () => {
217227
>
218228
{{ t("Edit category") }}
219229
</button>
230+
220231
<button
221232
class="w-full text-left px-3 py-2 rounded hover:bg-gray-15"
222233
@click="onCatAddUsers"
223234
>
224235
{{ t("Subscribe users to category") }}
225236
</button>
237+
226238
<div class="my-1 h-px bg-gray-15"></div>
239+
227240
<button
228241
class="w-full text-left px-3 py-2 rounded hover:bg-gray-15"
229242
@click="onCatToggleVisibility"
230243
>
231244
{{ t("Toggle visibility") }}
232245
</button>
246+
233247
<button
234248
class="w-full text-left px-3 py-2 rounded hover:bg-gray-15"
235249
@click="onCatTogglePublish"
236250
>
237251
{{ t("Publish / Hide") }}
238252
</button>
253+
239254
<div class="my-1 h-px bg-gray-15"></div>
255+
240256
<button
241257
class="w-full text-left px-3 py-2 rounded hover:bg-gray-15 text-danger"
242258
@click="onCatDelete"
@@ -309,17 +325,18 @@ const toggleOpen = () => {
309325
:lp="element"
310326
:ringDash="ringDash"
311327
:ringValue="ringValue"
312-
@build="$emit('build', element)"
313-
@delete="$emit('delete', element)"
314-
@edit="$emit('edit', element)"
315-
@open="$emit('open', element)"
316-
@report="$emit('report', element)"
317-
@settings="$emit('settings', element)"
318-
@toggle-auto-launch="$emit('toggle-auto-launch', element)"
319-
@toggle-visible="$emit('toggle-visible', element)"
320-
@toggle-publish="$emit('toggle-publish', element)"
321-
@export-scorm="$emit('export-scorm', element)"
322-
@export-pdf="$emit('export-pdf', element)"
328+
@build="emit('build', element)"
329+
@delete="emit('delete', element)"
330+
@edit="emit('edit', element)"
331+
@open="emit('open', element)"
332+
@report="emit('report', element)"
333+
@settings="emit('settings', element)"
334+
@toggle-auto-launch="emit('toggle-auto-launch', element)"
335+
@toggle-visible="emit('toggle-visible', element)"
336+
@toggle-publish="emit('toggle-publish', element)"
337+
@export-scorm="emit('export-scorm', element)"
338+
@export-pdf="emit('export-pdf', element)"
339+
@update-scorm="emit('update-scorm', element)"
323340
/>
324341
</template>
325342
</Draggable>

assets/vue/components/lp/LpRowItem.vue

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,18 @@ const emit = defineEmits([
2828
"export-scorm",
2929
"export-pdf",
3030
"toggle-auto-launch",
31+
"update-scorm",
3132
])
3233
34+
const lpType = computed(() => {
35+
const v = props.lp?.lpType ?? props.lp?.lp_type ?? props.lp?.type ?? props.lp?.lpTypeId ?? props.lp?.lp_type_id ?? 0
36+
37+
return Number(v) || 0
38+
})
39+
40+
// Only SCORM packages (type = 2 in Chamilo legacy)
41+
const canUpdateScorm = computed(() => props.canEdit && lpType.value === 2)
42+
3343
const dateText = computed(() => {
3444
const v = props.buildDates ? props.buildDates(props.lp) : ""
3545
return typeof v === "string" ? v.trim() : ""
@@ -212,6 +222,13 @@ const progressTextClass = computed(() => {
212222
>
213223
{{ t("Export as SCORM") }}
214224
</button>
225+
<button
226+
v-if="canUpdateScorm"
227+
class="w-full text-left px-3 py-2 rounded hover:bg-gray-15 md:hidden"
228+
@click="emit('update-scorm', lp)"
229+
>
230+
{{ t("Update SCORM") }}
231+
</button>
215232
<button
216233
class="w-full text-left px-3 py-2 rounded hover:bg-gray-15 md:hidden"
217234
@click="emit('settings', lp)"
@@ -272,6 +289,15 @@ const progressTextClass = computed(() => {
272289
>
273290
<i class="mdi mdi-archive-arrow-down text-xl" />
274291
</button>
292+
<button
293+
v-if="canUpdateScorm"
294+
:aria-label="t('Update SCORM')"
295+
:title="t('Update SCORM')"
296+
class="row-start-1 col-start-5 opacity-70 hover:opacity-100 hidden md:block"
297+
@click="emit('update-scorm', lp)"
298+
>
299+
<i class="mdi mdi-upload text-xl" />
300+
</button>
275301
<button
276302
v-if="canExportPdf"
277303
:aria-label="t('Export to PDF')"
@@ -333,6 +359,13 @@ const progressTextClass = computed(() => {
333359
>
334360
{{ t("Edit learnpath") }}
335361
</button>
362+
<button
363+
v-if="canUpdateScorm"
364+
class="w-full text-left px-3 py-2 rounded hover:bg-gray-15"
365+
@click="emit('update-scorm', lp)"
366+
>
367+
{{ t("Update SCORM") }}
368+
</button>
336369
<button
337370
class="w-full text-left px-3 py-2 rounded hover:bg-gray-15 text-danger"
338371
@click="emit('delete', lp)"

assets/vue/services/lpService.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,22 @@ const buildLegacyActionUrl = (arg1, arg2, arg3 = {}) => {
8585
return `/main/lp/lp_controller.php?${search.toString()}`
8686
}
8787

88+
/** Build URL for updating/uploading SCORM package for an existing LP. */
89+
const buildLegacyUploadUrl = (lpId, { cid, sid, node, gid = 0, gradebook = 0, origin = "" } = {}) => {
90+
return buildLegacyActionUrl(lpId, "upload", {
91+
cid,
92+
sid,
93+
node,
94+
gid,
95+
gradebook,
96+
origin,
97+
params: {
98+
// force teacher mode context
99+
isStudentView: "false",
100+
},
101+
})
102+
}
103+
88104
/** Navigates immediately to a legacy controller action. */
89105
const goLegacyAction = (lpId, action, opts = {}) => {
90106
window.location.href =
@@ -102,9 +118,7 @@ const goLegacyAction = (lpId, action, opts = {}) => {
102118
* @returns {Promise<Object[]>}
103119
*/
104120
const getLpCategories = async (searchParams) => {
105-
// API Platform resource for CLpCategory (GET collection)
106121
const { items } = await baseService.getCollection("/api/learning_path_categories/", searchParams)
107-
108122
return items
109123
}
110124

@@ -113,6 +127,7 @@ export default {
113127
getLearningPath,
114128
buildLegacyViewUrl,
115129
buildLegacyActionUrl,
130+
buildLegacyUploadUrl,
116131
goLegacyAction,
117132
getLpCategories,
118133
}

0 commit comments

Comments
 (0)