parent
073260bd71
commit
782b7ed354
@ -1,419 +0,0 @@ |
|||||||
<template> |
|
||||||
<div |
|
||||||
v-if="isCourseLoading" |
|
||||||
class="flex flex-col gap-4" |
|
||||||
> |
|
||||||
<div class="flex gap-4 items-center"> |
|
||||||
<Skeleton |
|
||||||
class="mr-auto" |
|
||||||
height="2.5rem" |
|
||||||
width="12rem" |
|
||||||
/> |
|
||||||
<Skeleton |
|
||||||
v-if="isCurrentTeacher" |
|
||||||
height="2.5rem" |
|
||||||
width="8rem" |
|
||||||
/> |
|
||||||
<Skeleton |
|
||||||
v-if="isCurrentTeacher" |
|
||||||
height="2.5rem" |
|
||||||
width="3rem" |
|
||||||
/> |
|
||||||
</div> |
|
||||||
|
|
||||||
<Skeleton |
|
||||||
height="16rem" |
|
||||||
/> |
|
||||||
|
|
||||||
<div class="flex items-center gap-6"> |
|
||||||
<Skeleton |
|
||||||
height="1.5rem" |
|
||||||
width="6rem" |
|
||||||
/> |
|
||||||
<Skeleton |
|
||||||
v-if="isCurrentTeacher" |
|
||||||
class="ml-auto" |
|
||||||
height="1.5rem" |
|
||||||
width="6rem" |
|
||||||
/> |
|
||||||
<Skeleton |
|
||||||
v-if="isCurrentTeacher" |
|
||||||
class="aspect-square" |
|
||||||
height="1.5rem" |
|
||||||
width="6rem" |
|
||||||
/> |
|
||||||
<Skeleton |
|
||||||
v-if="isCurrentTeacher" |
|
||||||
class="aspect-square" |
|
||||||
height="1.5rem" |
|
||||||
width="6rem" |
|
||||||
/> |
|
||||||
<Skeleton |
|
||||||
v-if="isCurrentTeacher" |
|
||||||
class="aspect-square" |
|
||||||
height="1.5rem" |
|
||||||
width="6rem" |
|
||||||
/> |
|
||||||
</div> |
|
||||||
|
|
||||||
<hr class="mt-0 mb-4"> |
|
||||||
|
|
||||||
<div class="grid gap-y-12 sm:gap-x-5 md:gap-x-16 md:gap-y-12 justify-between grid-cols-course-tools"> |
|
||||||
<Skeleton |
|
||||||
v-for="v in 30" |
|
||||||
:key="v" |
|
||||||
class="aspect-square" |
|
||||||
height="auto" |
|
||||||
width="7.5rem" |
|
||||||
/> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
<div |
|
||||||
v-else |
|
||||||
class="flex flex-col gap-4" |
|
||||||
> |
|
||||||
<div class="flex gap-4 items-center"> |
|
||||||
<h2 |
|
||||||
class="mr-auto" |
|
||||||
> |
|
||||||
{{ course.title }} |
|
||||||
<small v-if="session"> |
|
||||||
({{ session.title }}) |
|
||||||
</small> |
|
||||||
</h2> |
|
||||||
|
|
||||||
<Button |
|
||||||
v-if="course && isCurrentTeacher" |
|
||||||
:label="t('See as student')" |
|
||||||
class="p-button-outlined p-button-plain" |
|
||||||
icon="pi pi-eye" |
|
||||||
type="button" |
|
||||||
/> |
|
||||||
|
|
||||||
<Button |
|
||||||
v-if="course && isCurrentTeacher" |
|
||||||
aria-controls="course-tmenu" |
|
||||||
aria-haspopup="true" |
|
||||||
class="p-button-text p-button-plain" |
|
||||||
icon="mdi mdi-cog" |
|
||||||
type="button" |
|
||||||
@click="toggleCourseTMenu" |
|
||||||
/> |
|
||||||
|
|
||||||
<TieredMenu |
|
||||||
id="course-tmenu" |
|
||||||
ref="courseTMenu" |
|
||||||
:model="courseItems" |
|
||||||
:popup="true" |
|
||||||
/> |
|
||||||
</div> |
|
||||||
|
|
||||||
<div |
|
||||||
v-if="isCurrentTeacher" |
|
||||||
> |
|
||||||
<div |
|
||||||
v-if="intro" |
|
||||||
class="flex flex-col gap-4" |
|
||||||
> |
|
||||||
<div v-html="intro.introText" /> |
|
||||||
|
|
||||||
<Button |
|
||||||
v-if="createInSession && introTool" |
|
||||||
:label="t('Course introduction')" |
|
||||||
class="p-button-outlined ml-auto" |
|
||||||
icon="mdi mdi-plus" |
|
||||||
@click="addIntro(course, introTool)" |
|
||||||
/> |
|
||||||
<Button |
|
||||||
v-else |
|
||||||
:label="t('Update')" |
|
||||||
class="p-button-outlined ml-auto" |
|
||||||
icon="mdi mdi-pencil" |
|
||||||
@click="updateIntro(intro)" |
|
||||||
/> |
|
||||||
</div> |
|
||||||
<EmptyState |
|
||||||
v-else-if="introTool" |
|
||||||
:detail="t('Add a course introduction to display to your students.')" |
|
||||||
:summary="t('You don\'t have any course content yet.')" |
|
||||||
icon="mdi mdi-book-open-page-variant" |
|
||||||
> |
|
||||||
<Button |
|
||||||
:label="t('Course introduction')" |
|
||||||
class="mt-4 p-button-outlined" |
|
||||||
icon="mdi mdi-plus" |
|
||||||
@click="addIntro(course, introTool)" |
|
||||||
/> |
|
||||||
</EmptyState> |
|
||||||
</div> |
|
||||||
<div |
|
||||||
v-else-if="intro" |
|
||||||
v-html="intro.introText" |
|
||||||
/> |
|
||||||
|
|
||||||
<div class="flex items-center gap-6"> |
|
||||||
<h6 v-t="'Tools'" /> |
|
||||||
<Button |
|
||||||
v-if="isCurrentTeacher" |
|
||||||
:disabled="isSorting || isCustomizing" |
|
||||||
:label="t('Show all')" |
|
||||||
class="p-button-text p-button-plain p-button-sm ml-auto" |
|
||||||
icon="mdi mdi-eye" |
|
||||||
@click="onClickShowAll" |
|
||||||
/> |
|
||||||
<Button |
|
||||||
v-if="isCurrentTeacher" |
|
||||||
:disabled="isSorting || isCustomizing" |
|
||||||
:label="t('Hide all')" |
|
||||||
class="p-button-text p-button-plain p-button-sm" |
|
||||||
icon="mdi mdi-eye-off" |
|
||||||
@click="onClickHideAll" |
|
||||||
/> |
|
||||||
<ToggleButton |
|
||||||
v-if="isCurrentTeacher" |
|
||||||
v-model="isSorting" |
|
||||||
:disabled="isCustomizing" |
|
||||||
:off-label="t('Sort')" |
|
||||||
:on-label="t('Sort')" |
|
||||||
class="p-button-text p-button-plain p-button-sm" |
|
||||||
off-icon="mdi mdi-swap-vertical" |
|
||||||
on-icon="mdi mdi-swap-vertical" |
|
||||||
/> |
|
||||||
<ToggleButton |
|
||||||
v-if="isCurrentTeacher" |
|
||||||
v-model="isCustomizing" |
|
||||||
:disabled="isSorting" |
|
||||||
:off-label="t('Customize')" |
|
||||||
:on-label="t('Customize')" |
|
||||||
class="p-button-text p-button-plain p-button-sm" |
|
||||||
off-icon="mdi mdi-format-paint" |
|
||||||
on-icon="mdi mdi-format-paint" |
|
||||||
/> |
|
||||||
</div> |
|
||||||
<hr class="mt-0 mb-4"> |
|
||||||
|
|
||||||
<div class="grid gap-y-12 sm:gap-x-5 md:gap-x-16 md:gap-y-12 grid-cols-course-tools"> |
|
||||||
<CourseToolList |
|
||||||
v-for="(tool, index) in tools.authoring" |
|
||||||
:key="index" |
|
||||||
:change-visibility="changeVisibility" |
|
||||||
:course="course" |
|
||||||
:go-to-course-tool="goToCourseTool" |
|
||||||
:go-to-setting-course-tool="goToSettingCourseTool" |
|
||||||
:tool="tool" |
|
||||||
/> |
|
||||||
|
|
||||||
<CourseToolList |
|
||||||
v-for="(tool, index) in tools.interaction" |
|
||||||
:key="index" |
|
||||||
:change-visibility="changeVisibility" |
|
||||||
:course="course" |
|
||||||
:go-to-course-tool="goToCourseTool" |
|
||||||
:go-to-setting-course-tool="goToSettingCourseTool" |
|
||||||
:tool="tool" |
|
||||||
/> |
|
||||||
|
|
||||||
<CourseToolList |
|
||||||
v-for="(tool, index) in tools.plugin" |
|
||||||
:key="index" |
|
||||||
:change-visibility="changeVisibility" |
|
||||||
:course="course" |
|
||||||
:go-to-course-tool="goToCourseTool" |
|
||||||
:go-to-setting-course-tool="goToSettingCourseTool" |
|
||||||
:tool="tool" |
|
||||||
/> |
|
||||||
|
|
||||||
<ShortCutList |
|
||||||
v-for="(shortcut, index) in shortcuts" |
|
||||||
:key="index" |
|
||||||
:change-visibility="changeVisibility" |
|
||||||
:go-to-short-cut="goToShortCut" |
|
||||||
:shortcut="shortcut" |
|
||||||
/> |
|
||||||
</div> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script setup> |
|
||||||
import { computed, provide, ref } from "vue"; |
|
||||||
import { useStore } from "vuex"; |
|
||||||
import { useRoute, useRouter } from "vue-router"; |
|
||||||
import { useI18n } from "vue-i18n"; |
|
||||||
import axios from "axios"; |
|
||||||
import { ENTRYPOINT } from "../../config/entrypoint"; |
|
||||||
import Button from "primevue/button"; |
|
||||||
import ToggleButton from "primevue/togglebutton"; |
|
||||||
import TieredMenu from "primevue/tieredmenu"; |
|
||||||
import CourseToolList from "../../components/course/CourseToolList.vue"; |
|
||||||
import ShortCutList from "../../components/course/ShortCutList.vue"; |
|
||||||
import translateHtml from "../../../js/translatehtml.js"; |
|
||||||
import EmptyState from "../../components/EmptyState"; |
|
||||||
import Skeleton from "primevue/skeleton"; |
|
||||||
|
|
||||||
const route = useRoute(); |
|
||||||
const store = useStore(); |
|
||||||
const router = useRouter(); |
|
||||||
const { t } = useI18n(); |
|
||||||
|
|
||||||
const course = ref(null); |
|
||||||
const session = ref(null); |
|
||||||
const tools = ref({}); |
|
||||||
const shortcuts = ref([]); |
|
||||||
const intro = ref(null); |
|
||||||
const introTool = ref(null); |
|
||||||
const createInSession = ref(false); |
|
||||||
|
|
||||||
let courseId = route.params.id; |
|
||||||
let sessionId = route.query.sid ?? 0; |
|
||||||
|
|
||||||
const isCourseLoading = ref(true); |
|
||||||
|
|
||||||
const isCurrentTeacher = computed(() => store.getters["security/isCurrentTeacher"]); |
|
||||||
|
|
||||||
const isSorting = ref(false); |
|
||||||
const isCustomizing = ref(false); |
|
||||||
|
|
||||||
provide("isSorting", isSorting); |
|
||||||
provide("isCustomizing", isCustomizing); |
|
||||||
|
|
||||||
// Remove the course session state. |
|
||||||
store.dispatch("session/cleanSession"); |
|
||||||
|
|
||||||
const courseItems = ref([]); |
|
||||||
|
|
||||||
axios |
|
||||||
.get(ENTRYPOINT + `../course/${courseId}/home.json?sid=${sessionId}`) |
|
||||||
.then(({ data }) => { |
|
||||||
course.value = data.course; |
|
||||||
session.value = data.session; |
|
||||||
tools.value = data.tools; |
|
||||||
shortcuts.value = data.shortcuts; |
|
||||||
|
|
||||||
if (tools.value.admin) { |
|
||||||
courseItems.value = tools.value.admin.map(tool => ({ |
|
||||||
label: tool.tool.titleToShow, |
|
||||||
url: goToCourseTool(course, tool) |
|
||||||
})); |
|
||||||
} |
|
||||||
|
|
||||||
getIntro(); |
|
||||||
|
|
||||||
isCourseLoading.value = false; |
|
||||||
}) |
|
||||||
.catch(error => console.log(error)); |
|
||||||
|
|
||||||
const courseTMenu = ref(null); |
|
||||||
|
|
||||||
const toggleCourseTMenu = event => { |
|
||||||
courseTMenu.value.toggle(event); |
|
||||||
}; |
|
||||||
|
|
||||||
async function getIntro() { |
|
||||||
// Searching for the CTool called 'course_homepage'. |
|
||||||
let currentIntroTool = course.value.tools.find(element => element.title === "course_homepage"); |
|
||||||
|
|
||||||
if (!introTool.value) { |
|
||||||
introTool.value = currentIntroTool; |
|
||||||
|
|
||||||
if (sessionId) { |
|
||||||
createInSession.value = true; |
|
||||||
} |
|
||||||
|
|
||||||
// Search CToolIntro for this |
|
||||||
const filter = { |
|
||||||
courseTool: currentIntroTool.iid, |
|
||||||
cid: courseId, |
|
||||||
sid: sessionId |
|
||||||
}; |
|
||||||
|
|
||||||
try { |
|
||||||
const response = await store.dispatch("ctoolintro/findAll", filter); |
|
||||||
if (response) { |
|
||||||
if (sessionId) { |
|
||||||
createInSession.value = false; |
|
||||||
} |
|
||||||
// first item |
|
||||||
intro.value = response[0]; |
|
||||||
translateHtml(); |
|
||||||
} |
|
||||||
} catch (e) { |
|
||||||
console.error(e); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
function addIntro(course, introTool) { |
|
||||||
return router.push({ |
|
||||||
name: "ToolIntroCreate", |
|
||||||
params: { "courseTool": introTool.iid }, |
|
||||||
query: { |
|
||||||
"cid": courseId, |
|
||||||
"sid": sessionId, |
|
||||||
"parentResourceNodeId": course.resourceNode.id |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
function updateIntro(intro) { |
|
||||||
return router.push({ |
|
||||||
name: "ToolIntroUpdate", |
|
||||||
params: { "id": intro["@id"] }, |
|
||||||
query: { |
|
||||||
"cid": courseId, |
|
||||||
"sid": sessionId, |
|
||||||
"id": intro["@id"] |
|
||||||
} |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
function goToSettingCourseTool(course, tool) { |
|
||||||
return "/course/" + courseId + "/settings/" + tool.tool.title + "?sid=" + sessionId; |
|
||||||
} |
|
||||||
|
|
||||||
function goToCourseTool(course, tool) { |
|
||||||
return "/course/" + courseId + "/tool/" + tool.tool.title + "?sid=" + sessionId; |
|
||||||
} |
|
||||||
|
|
||||||
function goToShortCut(shortcut) { |
|
||||||
const url = new URLSearchParams("?"); |
|
||||||
|
|
||||||
url.append("cid", courseId); |
|
||||||
url.append("sid", sessionId); |
|
||||||
|
|
||||||
return shortcut.url + "?" + url; |
|
||||||
} |
|
||||||
|
|
||||||
const setToolVisibility = (tool, visibility) => { |
|
||||||
tool.ctool.resourceNode.resourceLinks[0].visibility = visibility; |
|
||||||
}; |
|
||||||
|
|
||||||
function changeVisibility(course, tool) { |
|
||||||
axios.post(ENTRYPOINT + "../r/course_tool/links/" + tool.ctool.resourceNode.id + "/change_visibility") |
|
||||||
.then(response => setToolVisibility(tool, response.data.visibility)) |
|
||||||
.catch(error => console.log(error)); |
|
||||||
} |
|
||||||
|
|
||||||
function onClickShowAll() { |
|
||||||
axios.post(ENTRYPOINT + `../r/course_tool/links/change_visibility/show?cid=${courseId}&sid=${sessionId}`) |
|
||||||
.then(() => { |
|
||||||
tools.value.authoring.forEach(tool => setToolVisibility(tool, 2)); |
|
||||||
|
|
||||||
tools.value.interaction.forEach(tool => setToolVisibility(tool, 2)); |
|
||||||
|
|
||||||
tools.value.plugin.forEach(tool => setToolVisibility(tool, 2)); |
|
||||||
}) |
|
||||||
.catch(error => console.log(error)); |
|
||||||
} |
|
||||||
|
|
||||||
function onClickHideAll() { |
|
||||||
axios.post(ENTRYPOINT + `../r/course_tool/links/change_visibility/hide?cid=${courseId}&sid=${sessionId}`) |
|
||||||
.then(() => { |
|
||||||
tools.value.authoring.forEach(tool => setToolVisibility(tool, 0)); |
|
||||||
|
|
||||||
tools.value.interaction.forEach(tool => setToolVisibility(tool, 0)); |
|
||||||
|
|
||||||
tools.value.plugin.forEach(tool => setToolVisibility(tool, 0)); |
|
||||||
}) |
|
||||||
.catch(error => console.log(error)); |
|
||||||
} |
|
||||||
</script> |
|
||||||
Loading…
Reference in new issue