UI: Refactoring course introduction

pull/5045/head
Angel Fernando Quiroz Campos 2 years ago
parent 1456406705
commit 2db2f2148b
  1. 100
      assets/vue/components/course/CourseIntroduction.vue
  2. 18
      assets/vue/services/courseService.js
  3. 122
      assets/vue/views/course/CourseHome.vue
  4. 48
      src/CoreBundle/Controller/CourseController.php

@ -0,0 +1,100 @@
<script setup>
import { useI18n } from "vue-i18n"
import { ref } from "vue"
import { useRouter } from "vue-router"
import { storeToRefs } from "pinia"
import EmptyState from "../EmptyState.vue"
import BaseButton from "../basecomponents/BaseButton.vue"
import Skeleton from "primevue/skeleton"
import { useCidReqStore } from "../../store/cidReq"
import courseService from "../../services/courseService"
const { t } = useI18n()
const router = useRouter()
const cidReqStore = useCidReqStore()
const { course, session } = storeToRefs(cidReqStore)
const intro = ref(null)
courseService.loadHomeIntro(course.value.id, session.value?.id).then((data) => (intro.value = data))
const goToIntroCreate = () => {
router.push({
name: "ToolIntroCreate",
params: {
courseTool: intro.value.c_tool.iid,
},
query: {
cid: course.value.id,
sid: session.value?.id,
parentResourceNodeId: course.value.resourceNode.id,
ctoolIntroId: intro.value.iid,
},
})
}
const goToIntroUpdate = () => {
router.push({
name: "ToolIntroUpdate",
params: {
id: `/api/c_tool_intros/${intro.value.iid}`,
},
query: {
cid: course.value.id,
sid: session.value?.id,
ctoolintroIid: intro.value.iid,
ctoolId: intro.value.c_tool.iid,
parentResourceNodeId: course.value.resourceNode.id,
id: `/api/c_tool_intros/${intro.value.iid}`,
},
})
}
const goToCreateOrUpdate = () => {
if (intro.value.createInSession) {
goToIntroCreate()
return
}
goToIntroUpdate()
}
defineExpose({
introduction: intro,
goToCreateOrUpdate,
})
</script>
<template>
<div
v-if="intro"
class="mb-4"
>
<div
v-if="intro.introText"
v-html="intro.introText"
/>
<EmptyState
v-else
:detail="t('Add a course introduction to display to your students.')"
:summary="t('You don\'t have any course content yet.')"
icon="courses"
>
<BaseButton
:label="t('Course introduction')"
class="mt-4"
icon="plus"
type="primary"
@click="goToIntroCreate"
/>
</EmptyState>
</div>
<Skeleton
v-else
class="mb-4"
height="21.5rem"
/>
</template>

@ -31,6 +31,24 @@ const courseService = {
return data
},
/**
* @param {number} courseId
* @param {number=} sessionId
* @returns {Promise<{Object}>}
*/
loadHomeIntro: async (courseId, sessionId = 0) => {
const { data } = await axios.get(
ENTRYPOINT + `../course/${courseId}/getToolIntro`,
{
params: {
sid: sessionId,
},
}
)
return data
},
}
export default courseService

@ -88,15 +88,14 @@
/>
</div>
<div class="grow-0">
<BaseButton
v-if="showUpdateIntroductionButton"
:label="t('Edit introduction')"
icon="edit"
type="black"
@click="createInSession ? addIntro(intro) : updateIntro(intro)"
/>
</div>
<BaseButton
v-if="isCurrentTeacher && courseIntroEl?.introduction?.iid"
:label="t('Edit introduction')"
class="grow-0"
icon="edit"
type="black"
@click="courseIntroEl.goToCreateOrUpdate()"
/>
<div class="grow-0">
<BaseButton
@ -118,34 +117,9 @@
<hr class="mt-1 mb-1" />
<div
<CourseIntroduction
v-if="isAllowedToEdit"
class="mb-4"
>
<div
v-if="intro && !intro.introText"
class="flex flex-col gap-4"
>
<EmptyState
if="!intro.introText && introTool"
:detail="t('Add a course introduction to display to your students.')"
:summary="t('You don\'t have any course content yet.')"
icon="courses"
>
<BaseButton
:label="t('Course introduction')"
class="mt-4"
icon="plus"
type="primary"
@click="addIntro(intro)"
/>
</EmptyState>
</div>
</div>
<div
v-if="intro && intro.introText"
class="mb-4"
v-html="intro.introText"
ref="courseIntroEl"
/>
<div
@ -234,14 +208,12 @@
<script setup>
import { computed, onBeforeMount, onMounted, provide, ref, watch } 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 CourseTool from "../../components/course/CourseTool"
import ShortCutList from "../../components/course/ShortCutList.vue"
import translateHtml from "../../../js/translatehtml.js"
import EmptyState from "../../components/EmptyState"
import Skeleton from "primevue/skeleton"
import BaseButton from "../../components/basecomponents/BaseButton.vue"
import BaseMenu from "../../components/basecomponents/BaseMenu.vue"
@ -252,10 +224,9 @@ import { checkIsAllowedToEdit } from "../../composables/userPermissions"
import { useCidReqStore } from "../../store/cidReq"
import {storeToRefs} from "pinia";
import courseService from "../../services/courseService";
import CourseIntroduction from "../../components/course/CourseIntroduction.vue";
const route = useRoute()
const store = useStore()
const router = useRouter()
const { t } = useI18n()
const cidReqStore = useCidReqStore()
@ -263,23 +234,14 @@ const { course, session } = storeToRefs(cidReqStore)
const tools = ref([])
const shortcuts = ref([])
const intro = ref(null)
const introTool = ref(null)
const createInSession = ref(false)
const courseIntroEl = ref(null);
let sessionId = route.query.sid ?? 0
const isCourseLoading = ref(true)
const showContent = ref(false)
const showUpdateIntroductionButton = computed(() => {
if (course.value && isCurrentTeacher.value && intro.value && intro.value.introText) {
return true;
}
return false;
});
const isCurrentTeacher = computed(() => store.getters["security/isCurrentTeacher"])
const isSorting = ref(false)
@ -313,8 +275,6 @@ courseService.loadTools(course.value.id, session.value?.id)
}))
}
getIntro()
isCourseLoading.value = false
})
.catch((error) => console.log(error))
@ -325,62 +285,6 @@ const toggleCourseTMenu = (event) => {
courseTMenu.value.toggle(event)
}
async function getIntro() {
axios
.get("/course/" + course.value.id + "/getToolIntro", {
params: {
cid: course.value.id,
sid: sessionId,
},
})
.then((response) => {
if (response.data) {
intro.value = response.data
if (response.data.introText) {
introTool.value = response.data.c_tool
}
if (response.data.createInSession) {
createInSession.value = response.data.createInSession
}
}
})
.catch(function (error) {
console.log(error)
})
}
function addIntro(intro) {
let params = {};
if (intro && intro.c_tool.iid) {
params = { courseTool: intro.c_tool.iid };
}
return router.push({
name: "ToolIntroCreate",
params: params,
query: {
cid: course.value.id,
sid: sessionId,
parentResourceNodeId: course.value.resourceNode.id,
ctoolIntroId: intro.iid,
},
})
}
function updateIntro(intro) {
return router.push({
name: "ToolIntroUpdate",
params: { id: "/api/c_tool_intros/" + intro.iid },
query: {
cid: course.value.id,
sid: sessionId,
ctoolintroIid: intro.iid,
ctoolId: intro.c_tool.iid,
parentResourceNodeId: course.value.resourceNode.id,
id: "/api/c_tool_intros/" + intro.iid,
},
})
}
function goToSettingCourseTool(course, tool) {
return "/course/" + course.value.id + "/settings/" + tool.tool.name + "?sid=" + sessionId
}

@ -58,6 +58,7 @@ use UserManager;
class CourseController extends ToolBaseController
{
public function __construct(
private readonly EntityManagerInterface $em,
private readonly SerializerInterface $serializer
) {}
@ -537,25 +538,12 @@ class CourseController extends ToolBaseController
]);
}
#[Route('/{id}/getToolIntro', name: 'chamilo_core_course_gettoolintro')]
public function getToolIntro(Request $request, Course $course, EntityManagerInterface $em): Response
private function findIntroOfCourse(Course $course)
{
$sessionId = (int) $request->get('sid');
// $session = $this->getSession();
$responseData = [];
$ctoolRepo = $em->getRepository(CTool::class);
$sessionRepo = $em->getRepository(Session::class);
$createInSession = false;
$qb = $this->em->createQueryBuilder();
$session = null;
if (!empty($sessionId)) {
$session = $sessionRepo->find($sessionId);
}
$qb = $em->createQueryBuilder();
$query = $qb->select('ct')
->from('Chamilo\CourseBundle\Entity\CTool', 'ct')
->from(CTool::class, 'ct')
->where('ct.course = :c_id')
->andWhere('ct.name = :name')
->andWhere(
@ -572,14 +560,34 @@ class CourseController extends ToolBaseController
->getQuery()
;
$ctool = $query->getOneOrNullResult();
return $query->getOneOrNullResult();
}
#[Route('/{id}/getToolIntro', name: 'chamilo_core_course_gettoolintro')]
public function getToolIntro(Request $request, Course $course, EntityManagerInterface $em): Response
{
$sessionId = (int) $request->get('sid');
// $session = $this->getSession();
$responseData = [];
$ctoolRepo = $em->getRepository(CTool::class);
$sessionRepo = $em->getRepository(Session::class);
$createInSession = false;
$session = null;
if (!empty($sessionId)) {
$session = $sessionRepo->find($sessionId);
}
$ctool = $this->findIntroOfCourse($course);
if ($session) {
$ctoolSession = $ctoolRepo->findOneBy(['name' => 'course_homepage', 'course' => $course, 'session' => $session]);
if (!$ctoolSession) {
$createInSession = true;
} else {
$createInSession = false;
$ctool = $ctoolSession;
}
}
@ -590,12 +598,10 @@ class CourseController extends ToolBaseController
/** @var CToolIntro $ctoolintro */
$ctoolintro = $ctoolintroRepo->findOneBy(['courseTool' => $ctool]);
if ($ctoolintro) {
$introText = $ctoolintro->getIntroText();
$responseData = [
'iid' => $ctoolintro->getIid(),
'introText' => $introText,
'introText' => $ctoolintro->getIntroText(),
'createInSession' => $createInSession,
'cToolId' => $ctool->getIid(),
];
}
$responseData['c_tool'] = [

Loading…
Cancel
Save