@@ -22,43 +22,60 @@ const props = defineProps({
2222 buildDates: { type: Function , required: false },
2323})
2424const emit = defineEmits ([
25- " open" ," edit" ," report" ," settings" ," build" ,
26- " toggle-visible" ," toggle-publish" ," delete" ,
27- " export-scorm" ," export-pdf" ,
28- " reorder" ," toggle-auto-launch" ,
25+ " open" ,
26+ " edit" ,
27+ " report" ,
28+ " settings" ,
29+ " build" ,
30+ " toggle-visible" ,
31+ " toggle-publish" ,
32+ " delete" ,
33+ " export-scorm" ,
34+ " export-pdf" ,
35+ " reorder" ,
36+ " toggle-auto-launch" ,
2937])
3038
3139const displayTitle = computed (() => props .title || t (" Learning path categories" ))
3240
3341const localList = ref ([... (props .list ?? [])])
3442const dragging = ref (false )
3543
36- watch (() => props .list , (nv ) => {
37- if (dragging .value ) return
38- localList .value = [... (nv ?? [])]
39- }, { immediate: true })
44+ watch (
45+ () => props .list ,
46+ (nv ) => {
47+ if (dragging .value ) return
48+ localList .value = [... (nv ?? [])]
49+ },
50+ { immediate: true },
51+ )
4052
4153function onEndCat () {
4254 dragging .value = false
43- emit (" reorder" , localList .value .map (i => i .iid ))
55+ emit (
56+ " reorder" ,
57+ localList .value .map ((i ) => i .iid ),
58+ )
4459}
4560
4661const route = useRoute ()
47- const cid = computed (() => Number (route .query ? .cid ?? 0 ) || undefined )
48- const sid = computed (() => Number (route .query ? .sid ?? 0 ) || undefined )
62+ const cid = computed (() => Number (route .query ? .cid ?? 0 ) || undefined )
63+ const sid = computed (() => Number (route .query ? .sid ?? 0 ) || undefined )
4964const node = computed (() => Number (route .params ? .node ?? 0 ) || undefined )
5065
5166const goCat = (action , extraParams = {}) => {
5267 const url = lpService .buildLegacyActionUrl (action, {
53- cid: cid .value , sid: sid .value , node: node .value ,
68+ cid: cid .value ,
69+ sid: sid .value ,
70+ node: node .value ,
5471 params: { id: props .category .iid , ... extraParams },
5572 })
5673 window .location .assign (url)
5774}
58- const onCatEdit = () => goCat (" add_lp_category" )
59- const onCatAddUsers = () => goCat (" add_users_to_category" )
75+ const onCatEdit = () => goCat (" add_lp_category" )
76+ const onCatAddUsers = () => goCat (" add_users_to_category" )
6077const onCatToggleVisibility = () => {
61- const vis = props .category .visibility ?? props .category .visible
78+ const vis = props .category .visibility ?? props .category .visible
6279 const next = typeof vis === " number" ? (vis ? 0 : 1 ) : 1
6380 goCat (" toggle_category_visibility" , { new_status: next })
6481}
@@ -70,6 +87,12 @@ const onCatTogglePublish = () => {
7087 goCat (" toggle_category_publish" , { new_status: next })
7188}
7289const onCatDelete = () => {
90+ // Do not allow deletion if category is not empty
91+ if (localList .value .length > 0 ) {
92+ alert (t (" You must move or remove all learning paths from this category before deleting it." ))
93+ return
94+ }
95+
7396 const label = (props .category .title || " " ).trim () || t (" Category" )
7497 const msg = ` ${ t (" Are you sure you want to delete" )} ${ label} ?`
7598 if (confirm (msg)) {
@@ -83,41 +106,82 @@ onMounted(() => {
83106 const saved = localStorage.getItem(storageKey.value)
84107 if (saved !== null) isOpen.value = saved === "1"
85108})
86- watch(isOpen, v => localStorage.setItem(storageKey.value, v ? "1" : "0"))
109+ watch(isOpen, (v) => localStorage.setItem(storageKey.value, v ? "1" : "0"))
87110const panelId = computed(() => ` cat- panel- ${props .category ? .iid || props .title }` )
88- const toggleOpen = () => { if (localList.value.length) isOpen.value = !isOpen.value }
89- function onChangeCat() {
90- emit("reorder", localList.value.map(i => i.iid))
111+ const toggleOpen = () => {
112+ if (localList.value.length) isOpen.value = !isOpen.value
91113}
92114</script>
93115
94116<template>
95117 <section class="relative ml-2 rounded-2xl shadow-lg">
96118 <header class="relative bg-support-6 rounded-t-2xl flex items-center justify-between pl-0 pr-4 py-3">
97- <span class="pointer-events-none absolute inset-y-0 -left-1.5 w-1.5 bg-support-5 rounded-l-2xl" aria-hidden />
119+ <span
120+ class="pointer-events-none absolute inset-y-0 -left-1.5 w-1.5 bg-support-5 rounded-l-2xl"
121+ aria-hidden
122+ />
98123 <div class="flex items-center gap-3">
99124 <template v-if="canEdit">
100125 <button
101126 class="w-8 h-8 grid place-content-center rounded-lg text-gray-50 hover:bg-gray-15 hover:text-gray-90"
102- :title="t('Drag to reorder')" :aria-label="t('Drag to reorder')"
127+ :title="t('Drag to reorder')"
128+ :aria-label="t('Drag to reorder')"
103129 >
104- <svg width="14" height="14" viewBox="0 0 14 14" fill="currentColor" aria-hidden>
105- <circle cx="4" cy="3" r="1.2" /><circle cx="4" cy="7" r="1.2" /><circle cx="4" cy="11" r="1.2" />
106- <circle cx="10" cy="3" r="1.2" /><circle cx="10" cy="7" r="1.2" /><circle cx="10" cy="11" r="1.2" />
130+ <svg
131+ width="14"
132+ height="14"
133+ viewBox="0 0 14 14"
134+ fill="currentColor"
135+ aria-hidden
136+ >
137+ <circle
138+ cx="4"
139+ cy="3"
140+ r="1.2"
141+ />
142+ <circle
143+ cx="4"
144+ cy="7"
145+ r="1.2"
146+ />
147+ <circle
148+ cx="4"
149+ cy="11"
150+ r="1.2"
151+ />
152+ <circle
153+ cx="10"
154+ cy="3"
155+ r="1.2"
156+ />
157+ <circle
158+ cx="10"
159+ cy="7"
160+ r="1.2"
161+ />
162+ <circle
163+ cx="10"
164+ cy="11"
165+ r="1.2"
166+ />
107167 </svg>
108168 </button>
109169 </template>
110170 <template v-else>
111- <span class="inline-block w-8 h-8" aria-hidden></span>
171+ <span
172+ class="inline-block w-8 h-8"
173+ aria-hidden
174+ ></span>
112175 </template>
113176
114177 <h2 class="text-body-1 font-semibold text-gray-90">{{ displayTitle }}</h2>
115178 </div>
116179
117180 <div class="flex items-center gap-2">
118- <div class="text-tiny text-gray-50">{{ localList.length }} {{ t(' Learning paths' ) }}</div>
181+ <div class="text-tiny text-gray-50">{{ localList.length }} {{ t(" Learning paths" ) }}</div>
119182
120- <BaseDropdownMenu v-if="canEdit"
183+ <BaseDropdownMenu
184+ v-if="canEdit"
121185 :dropdown-id="` category- ${category .iid }` "
122186 class="relative z-30"
123187 >
@@ -127,18 +191,48 @@ function onChangeCat() {
127191 :title="t('Options')"
128192 :aria-label="t('Options')"
129193 >
130- <i class="mdi mdi-dots-vertical text-lg" aria-hidden></i>
194+ <i
195+ class="mdi mdi-dots-vertical text-lg"
196+ aria-hidden
197+ ></i>
131198 </span>
132199 </template>
133200 <template #menu>
134- <div class="absolute right-0 top-full mt-2 w-60 bg-white border border-gray-25 rounded-xl shadow-xl p-1 z-50">
135- <button class="w-full text-left px-3 py-2 rounded hover:bg-gray-15" @click="onCatEdit">{{ t('Edit category') }}</button>
136- <button class="w-full text-left px-3 py-2 rounded hover:bg-gray-15" @click="onCatAddUsers">{{ t('Subscribe users to category') }}</button>
201+ <div
202+ class="absolute right-0 top-full mt-2 w-60 bg-white border border-gray-25 rounded-xl shadow-xl p-1 z-50"
203+ >
204+ <button
205+ class="w-full text-left px-3 py-2 rounded hover:bg-gray-15"
206+ @click="onCatEdit"
207+ >
208+ {{ t("Edit category") }}
209+ </button>
210+ <button
211+ class="w-full text-left px-3 py-2 rounded hover:bg-gray-15"
212+ @click="onCatAddUsers"
213+ >
214+ {{ t("Subscribe users to category") }}
215+ </button>
137216 <div class="my-1 h-px bg-gray-15"></div>
138- <button class="w-full text-left px-3 py-2 rounded hover:bg-gray-15" @click="onCatToggleVisibility">{{ t('Toggle visibility') }}</button>
139- <button class="w-full text-left px-3 py-2 rounded hover:bg-gray-15" @click="onCatTogglePublish">{{ t('Publish / Hide') }}</button>
217+ <button
218+ class="w-full text-left px-3 py-2 rounded hover:bg-gray-15"
219+ @click="onCatToggleVisibility"
220+ >
221+ {{ t("Toggle visibility") }}
222+ </button>
223+ <button
224+ class="w-full text-left px-3 py-2 rounded hover:bg-gray-15"
225+ @click="onCatTogglePublish"
226+ >
227+ {{ t("Publish / Hide") }}
228+ </button>
140229 <div class="my-1 h-px bg-gray-15"></div>
141- <button class="w-full text-left px-3 py-2 rounded hover:bg-gray-15 text-danger" @click="onCatDelete">{{ t('Delete') }}</button>
230+ <button
231+ class="w-full text-left px-3 py-2 rounded hover:bg-gray-15 text-danger"
232+ @click="onCatDelete"
233+ >
234+ {{ t("Delete") }}
235+ </button>
142236 </div>
143237 </template>
144238 </BaseDropdownMenu>
@@ -151,16 +245,31 @@ function onChangeCat() {
151245 :title="t('Expand') / t('Collapse')"
152246 @click="toggleOpen"
153247 >
154- <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor"
155- class="transition-transform duration-200"
156- :class="isOpen ? 'rotate-180' : ''">
157- <path d="M6 9l6 6 6-6" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
248+ <svg
249+ width="18"
250+ height="18"
251+ viewBox="0 0 24 24"
252+ fill="none"
253+ stroke="currentColor"
254+ class="transition-transform duration-200"
255+ :class="isOpen ? 'rotate-180' : ''"
256+ >
257+ <path
258+ d="M6 9l6 6 6-6"
259+ stroke-width="2"
260+ stroke-linecap="round"
261+ stroke-linejoin="round"
262+ />
158263 </svg>
159264 </button>
160265 </div>
161266 </header>
162267
163- <div v-if="isOpen && localList.length" :id="panelId" class="sm:px-4 sm:pb-4 px-2 pb-2 bg-white rounded-b-2xl">
268+ <div
269+ v-if="isOpen && localList.length"
270+ :id="panelId"
271+ class="sm:px-4 sm:pb-4 px-2 pb-2 bg-white rounded-b-2xl"
272+ >
164273 <Draggable
165274 v-model="localList"
166275 item-key="iid"
@@ -189,17 +298,17 @@ function onChangeCat() {
189298 :canExportPdf="canExportPdf"
190299 :canAutoLaunch="canAutoLaunch"
191300 :buildDates="buildDates"
192- @toggle-auto-launch="$emit('toggle-auto-launch', element)"
193- @open="$emit('open', element)"
194- @edit="$emit('edit', element)"
195- @report="$emit('report', element)"
196- @settings="$emit('settings', element)"
197- @build="$emit('build', element)"
198- @toggle-visible="$emit('toggle-visible', element)"
199- @toggle-publish="$emit('toggle-publish', element)"
200- @delete="$emit('delete', element)"
201- @export-scorm="$emit('export-scorm', element)"
202- @export-pdf="$emit('export-pdf', element)"
301+ @toggle-auto-launch="$emit('toggle-auto-launch', element)"
302+ @open="$emit('open', element)"
303+ @edit="$emit('edit', element)"
304+ @report="$emit('report', element)"
305+ @settings="$emit('settings', element)"
306+ @build="$emit('build', element)"
307+ @toggle-visible="$emit('toggle-visible', element)"
308+ @toggle-publish="$emit('toggle-publish', element)"
309+ @delete="$emit('delete', element)"
310+ @export-scorm="$emit('export-scorm', element)"
311+ @export-pdf="$emit('export-pdf', element)"
203312 />
204313 </template>
205314 </Draggable>
0 commit comments