UI: Refactor course home + add skeleton while loading

pull/4351/head
Angel Fernando Quiroz Campos 3 years ago
parent 9a180f9858
commit 40ac50e3c7
  1. 139
      assets/vue/views/course/Home.vue

@ -1,18 +1,24 @@
<template> <template>
<div <div
v-if="course"
class="flex flex-col gap-4" class="flex flex-col gap-4"
> >
<div class="flex gap-4 items-center"> <div class="flex gap-4 items-center">
<h2 class="mr-auto"> <h2
v-if="course"
class="mr-auto"
>
{{ course.title }} {{ course.title }}
<small v-if="session"> <small v-if="session">
({{ session.name }}) ({{ session.name }})
</small> </small>
</h2> </h2>
<Skeleton
v-else
height="2rem"
/>
<Button <Button
v-if="isCurrentTeacher" v-if="course && isCurrentTeacher"
:label="t('See as student')" :label="t('See as student')"
icon="pi pi-eye" icon="pi pi-eye"
class="p-button-outlined p-button-plain" class="p-button-outlined p-button-plain"
@ -20,6 +26,7 @@
/> />
<Button <Button
v-if="course && isCurrentTeacher"
icon="mdi mdi-cog" icon="mdi mdi-cog"
class="p-button-text p-button-plain" class="p-button-text p-button-plain"
type="button" type="button"
@ -60,40 +67,55 @@
@click="updateIntro(intro)" @click="updateIntro(intro)"
/> />
</div> </div>
<EmptyState <div
v-else v-else
>
<EmptyState
v-if="introTool"
:summary="t('You don\'t have any course content yet.')" :summary="t('You don\'t have any course content yet.')"
:detail="t('Add a course introduction to display to your students.')" :detail="t('Add a course introduction to display to your students.')"
icon="mdi mdi-book-open-page-variant" icon="mdi mdi-book-open-page-variant"
> >
<Button <Button
v-if="introTool"
class="mt-4 p-button-outlined" class="mt-4 p-button-outlined"
icon="mdi mdi-plus" icon="mdi mdi-plus"
:label="t('Course introduction')" :label="t('Course introduction')"
@click="addIntro(course, introTool)" @click="addIntro(course, introTool)"
/> />
</EmptyState> </EmptyState>
<Skeleton
v-else
height="18rem"
/>
</div>
</div> </div>
<div <div
v-else-if="intro" v-else-if="intro"
v-html="intro.introText" v-html="intro.introText"
/> />
<h6 v-t="'Tools'" />
<hr class="mt-0 mb-4">
<div <div
v-if="isCurrentTeacher && course" v-if="!course"
class="flex justify-between border-b-2 border-gray-200" class="grid gap-y-12 sm:gap-x-5 md:gap-x-16 md:gap-y-12 justify-between grid-cols-course-tools"
> >
<div class="text-h6 font-bold"> <Skeleton
{{ $t('Tools') }} v-for="v in 30"
</div> :key="v"
height="auto"
width="7.5rem"
class="aspect-square"
/>
</div> </div>
<div <div
v-else
class="grid gap-y-12 sm:gap-x-5 md:gap-x-16 md:gap-y-12 justify-between grid-cols-course-tools" class="grid gap-y-12 sm:gap-x-5 md:gap-x-16 md:gap-y-12 justify-between grid-cols-course-tools"
> >
<CourseToolList <CourseToolList
v-for="tool in tools.authoring" v-for="(tool, index) in tools.authoring"
:key="index"
:change-visibility="changeVisibility" :change-visibility="changeVisibility"
:course="course" :course="course"
:go-to-course-tool="goToCourseTool" :go-to-course-tool="goToCourseTool"
@ -102,7 +124,8 @@
/> />
<CourseToolList <CourseToolList
v-for="tool in tools.interaction" v-for="(tool, index) in tools.interaction"
:key="index"
:change-visibility="changeVisibility" :change-visibility="changeVisibility"
:course="course" :course="course"
:go-to-course-tool="goToCourseTool" :go-to-course-tool="goToCourseTool"
@ -111,7 +134,8 @@
/> />
<CourseToolList <CourseToolList
v-for="tool in tools.plugin" v-for="(tool, index) in tools.plugin"
:key="index"
:change-visibility="changeVisibility" :change-visibility="changeVisibility"
:course="course" :course="course"
:go-to-course-tool="goToCourseTool" :go-to-course-tool="goToCourseTool"
@ -120,7 +144,8 @@
/> />
<ShortCutList <ShortCutList
v-for="shortcut in shortcuts" v-for="(shortcut, index) in shortcuts"
:key="index"
:change-visibility="changeVisibility" :change-visibility="changeVisibility"
:go-to-short-cut="goToShortCut" :go-to-short-cut="goToShortCut"
:shortcut="shortcut" :shortcut="shortcut"
@ -133,7 +158,7 @@
import { computed, ref } from 'vue'; import { computed, ref } from 'vue';
import { useStore } from 'vuex'; import { useStore } from 'vuex';
import { useRoute, useRouter } from 'vue-router'; import { useRoute, useRouter } from 'vue-router';
import isEmpty from 'lodash/isEmpty'; import { useI18n } from 'vue-i18n';
import axios from 'axios'; import axios from 'axios';
import { ENTRYPOINT } from '../../config/entrypoint'; import { ENTRYPOINT } from '../../config/entrypoint';
import Button from 'primevue/button'; import Button from 'primevue/button';
@ -141,24 +166,22 @@ import TieredMenu from 'primevue/tieredmenu';
import CourseToolList from '../../components/course/CourseToolList.vue'; import CourseToolList from '../../components/course/CourseToolList.vue';
import ShortCutList from '../../components/course/ShortCutList.vue'; import ShortCutList from '../../components/course/ShortCutList.vue';
import translateHtml from '../../../js/translatehtml.js'; import translateHtml from '../../../js/translatehtml.js';
import { useI18n } from 'vue-i18n';
import EmptyState from '../../components/EmptyState'; import EmptyState from '../../components/EmptyState';
import Skeleton from 'primevue/skeleton';
const servicePrefix = 'Courses'; const route = useRoute();
const store = useStore();
const router = useRouter();
const { t } = useI18n();
const course = ref([]); const course = ref(null);
const session = ref([]); const session = ref(null);
const tools = ref([]); const tools = ref({});
const shortcuts = ref([]); const shortcuts = ref([]);
const intro = ref(null); const intro = ref(null);
const introTool = ref(null); const introTool = ref(null);
const createInSession = ref(false); const createInSession = ref(false);
const route = useRoute();
const store = useStore();
const router = useRouter();
const { t } = useI18n();
let courseId = route.params.id; let courseId = route.params.id;
let sessionId = route.query.sid ?? 0; let sessionId = route.query.sid ?? 0;
@ -167,28 +190,28 @@ const isCurrentTeacher = computed(() => store.getters['security/isCurrentTeacher
// Remove the course session state. // Remove the course session state.
store.dispatch('session/cleanSession'); store.dispatch('session/cleanSession');
axios.get(ENTRYPOINT + '../course/' + courseId + '/home.json?sid=' + sessionId).then(response => { const courseItems = ref([]);
course.value = response.data.course;
session.value = response.data.session;
tools.value = response.data.tools;
shortcuts.value = response.data.shortcuts;
getIntro();
}).catch(function (error) {
console.log(error);
});
const courseTMenu = ref(null); 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;
const courseItems = computed(() => {
if (tools.value.admin) { if (tools.value.admin) {
return tools.value.admin.map(tool => ({ courseItems.value = tools.value.admin.map(tool => ({
label: tool.tool.nameToShow, label: tool.tool.nameToShow,
url: goToCourseTool(course, tool) url: goToCourseTool(course, tool)
})); }));
} }
return []; getIntro();
}); })
.catch(error => console.log(error));
const courseTMenu = ref(null);
const toggleCourseTMenu = event => { const toggleCourseTMenu = event => {
courseTMenu.value.toggle(event); courseTMenu.value.toggle(event);
@ -198,41 +221,33 @@ async function getIntro () {
// Searching for the CTool called 'course_homepage'. // Searching for the CTool called 'course_homepage'.
let currentIntroTool = course.value.tools.find(element => element.name === 'course_homepage'); let currentIntroTool = course.value.tools.find(element => element.name === 'course_homepage');
if (!isEmpty(introTool)) { if (!introTool.value) {
introTool.value = currentIntroTool; introTool.value = currentIntroTool;
// Search CToolIntro for this if (sessionId) {
const filter = { createInSession.value = true;
courseTool: currentIntroTool.iid,
cid: courseId,
};
store.dispatch('ctoolintro/findAll', filter).then(response => {
if (!isEmpty(response)) {
// first item
intro.value = response[0];
translateHtml();
} }
});
if (!isEmpty(sessionId)) { // Search CToolIntro for this
createInSession.value = true;
const filter = { const filter = {
courseTool: currentIntroTool.iid, courseTool: currentIntroTool.iid,
cid: courseId, cid: courseId,
sid: sessionId, sid: sessionId,
}; };
store.dispatch('ctoolintro/findAll', filter).then(response => { store.dispatch('ctoolintro/findAll', filter)
if (!isEmpty(response)) { .then(response => {
if (response) {
if (sessionId) {
createInSession.value = false; createInSession.value = false;
}
// first item
intro.value = response[0]; intro.value = response[0];
translateHtml(); translateHtml();
} }
}); });
} }
} }
}
function addIntro (course, introTool) { function addIntro (course, introTool) {
return router.push({ return router.push({
@ -276,12 +291,12 @@ function goToShortCut (shortcut) {
} }
function changeVisibility (course, tool) { function changeVisibility (course, tool) {
axios.post(ENTRYPOINT + '../r/course_tool/links/' + tool.ctool.resourceNode.id + '/change_visibility').then(response => { axios.post(ENTRYPOINT + '../r/course_tool/links/' + tool.ctool.resourceNode.id + '/change_visibility')
.then(response => {
if (response.data.ok) { if (response.data.ok) {
tool.ctool.resourceNode.resourceLinks[0].visibility = response.data.visibility; tool.ctool.resourceNode.resourceLinks[0].visibility = response.data.visibility;
} }
}).catch(function (error) { })
console.log(error); .catch(error => console.log(error));
});
} }
</script> </script>

Loading…
Cancel
Save